terminal/src/types/ModifierKeyState.cpp
Josh Soref a13ccfd0f5
Fix a bunch of spelling errors across the project (#4295)
Generated by https://github.com/jsoref/spelling `f`; to maintain your repo, please consider `fchurn`

I generally try to ignore upstream bits. I've accidentally included some items from the `deps/` directory. I expect someone will give me a list of items to drop, I'm happy to drop whole files/directories, or to split the PR into multiple items (E.g. comments/locals/public).

Closes #4294
2020-02-10 20:40:01 +00:00

138 lines
4.8 KiB
C++

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "precomp.h"
#include "inc/IInputEvent.hpp"
#include <unordered_map>
// Routine Description:
// - checks if flag is present in flags
// Arguments:
// - flags - bit pattern to check for flag
// - flag - bit pattern to search for
// Return Value:
// - true if flag is present in flags
// Note:
// - The wil version of IsFlagSet is only to operate on values that
// are compile time constants. This will work with runtime calculated
// values.
constexpr bool RuntimeIsFlagSet(const DWORD flags, const DWORD flag) noexcept
{
return !!(flags & flag);
}
std::unordered_set<ModifierKeyState> FromVkKeyScan(const short vkKeyScanFlags)
{
std::unordered_set<ModifierKeyState> keyState;
switch (vkKeyScanFlags)
{
case VkKeyScanModState::None:
break;
case VkKeyScanModState::ShiftPressed:
keyState.insert(ModifierKeyState::Shift);
break;
case VkKeyScanModState::CtrlPressed:
keyState.insert(ModifierKeyState::LeftCtrl);
keyState.insert(ModifierKeyState::RightCtrl);
break;
case VkKeyScanModState::ShiftAndCtrlPressed:
keyState.insert(ModifierKeyState::Shift);
keyState.insert(ModifierKeyState::LeftCtrl);
keyState.insert(ModifierKeyState::RightCtrl);
break;
case VkKeyScanModState::AltPressed:
keyState.insert(ModifierKeyState::LeftAlt);
keyState.insert(ModifierKeyState::RightAlt);
break;
case VkKeyScanModState::ShiftAndAltPressed:
keyState.insert(ModifierKeyState::Shift);
keyState.insert(ModifierKeyState::LeftAlt);
keyState.insert(ModifierKeyState::RightAlt);
break;
case VkKeyScanModState::CtrlAndAltPressed:
keyState.insert(ModifierKeyState::LeftCtrl);
keyState.insert(ModifierKeyState::RightCtrl);
keyState.insert(ModifierKeyState::LeftAlt);
keyState.insert(ModifierKeyState::RightAlt);
break;
case VkKeyScanModState::ModPressed:
keyState.insert(ModifierKeyState::Shift);
keyState.insert(ModifierKeyState::LeftCtrl);
keyState.insert(ModifierKeyState::RightCtrl);
keyState.insert(ModifierKeyState::LeftAlt);
keyState.insert(ModifierKeyState::RightAlt);
break;
default:
THROW_HR(E_INVALIDARG);
break;
}
return keyState;
}
using ModifierKeyStateMapping = std::pair<ModifierKeyState, DWORD>;
constexpr static ModifierKeyStateMapping ModifierKeyStateTranslationTable[] = {
{ ModifierKeyState::RightAlt, RIGHT_ALT_PRESSED },
{ ModifierKeyState::LeftAlt, LEFT_ALT_PRESSED },
{ ModifierKeyState::RightCtrl, RIGHT_CTRL_PRESSED },
{ ModifierKeyState::LeftCtrl, LEFT_CTRL_PRESSED },
{ ModifierKeyState::Shift, SHIFT_PRESSED },
{ ModifierKeyState::NumLock, NUMLOCK_ON },
{ ModifierKeyState::ScrollLock, SCROLLLOCK_ON },
{ ModifierKeyState::CapsLock, CAPSLOCK_ON },
{ ModifierKeyState::EnhancedKey, ENHANCED_KEY },
{ ModifierKeyState::NlsDbcsChar, NLS_DBCSCHAR },
{ ModifierKeyState::NlsAlphanumeric, NLS_ALPHANUMERIC },
{ ModifierKeyState::NlsKatakana, NLS_KATAKANA },
{ ModifierKeyState::NlsHiragana, NLS_HIRAGANA },
{ ModifierKeyState::NlsRoman, NLS_ROMAN },
{ ModifierKeyState::NlsImeConversion, NLS_IME_CONVERSION },
{ ModifierKeyState::AltNumpad, ALTNUMPAD_BIT },
{ ModifierKeyState::NlsImeDisable, NLS_IME_DISABLE }
};
static_assert(size(ModifierKeyStateTranslationTable) == static_cast<int>(ModifierKeyState::ENUM_COUNT),
"ModifierKeyStateTranslationTable must have a valid mapping for each modifier value");
// Routine Description:
// - Expands legacy control keys bitsets into a stl set
// Arguments:
// - flags - legacy bitset to expand
// Return Value:
// - set of ModifierKeyState values that represent flags
std::unordered_set<ModifierKeyState> FromConsoleControlKeyFlags(const DWORD flags)
{
std::unordered_set<ModifierKeyState> keyStates;
for (const ModifierKeyStateMapping& mapping : ModifierKeyStateTranslationTable)
{
if (RuntimeIsFlagSet(flags, mapping.second))
{
keyStates.insert(mapping.first);
}
}
return keyStates;
}
// Routine Description:
// - Converts ModifierKeyState back to the bizarre console bitflag associated with it.
// Arguments:
// - modifierKey - modifier to convert
// Return Value:
// - console bitflag associated with modifierKey
DWORD ToConsoleControlKeyFlag(const ModifierKeyState modifierKey) noexcept
{
for (const ModifierKeyStateMapping& mapping : ModifierKeyStateTranslationTable)
{
if (mapping.first == modifierKey)
{
return mapping.second;
}
}
return 0;
}