// Copyright (c) Microsoft Corporation. // Licensed under the MIT license. #include "precomp.h" #include "inc/IInputEvent.hpp" #include // 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 FromVkKeyScan(const short vkKeyScanFlags) { std::unordered_set 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; 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(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 FromConsoleControlKeyFlags(const DWORD flags) { std::unordered_set 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; }