a13ccfd0f5
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
138 lines
4.8 KiB
C++
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;
|
|
}
|