mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-03 15:41:41 +00:00
KEYMAPPER: Enable remapping the keyboard modifier keys
This commit is contained in:
parent
73bc139811
commit
29dd15af0c
@ -205,6 +205,19 @@ const KeyTableEntry defaultKeys[] = {
|
||||
{"AUDIOREWIND", KEYCODE_AUDIOREWIND, "Audio Rewind"},
|
||||
{"AUDIOFASTFORWARD", KEYCODE_AUDIOFASTFORWARD, "Audio Fast-Forward"},
|
||||
|
||||
// Modifier keys
|
||||
{"SCROLLOCK", KEYCODE_SCROLLOCK, "Scroll Lock" },
|
||||
{"CAPSLOCK", KEYCODE_CAPSLOCK, "Caps Lock" },
|
||||
{"NUMLOCK", KEYCODE_NUMLOCK, "Num Lock" },
|
||||
{"LSHIFT", KEYCODE_LSHIFT, "Left Shift" },
|
||||
{"RSHIFT", KEYCODE_RSHIFT, "Right Shift" },
|
||||
{"LALT", KEYCODE_LALT, "Left Alt" },
|
||||
{"RALT", KEYCODE_RALT, "Right Alt" },
|
||||
{"LCTRL", KEYCODE_LCTRL, "Left Control" },
|
||||
{"RCTRL", KEYCODE_RCTRL, "Right Control" },
|
||||
{"LMETA", KEYCODE_LMETA, "Left Meta" },
|
||||
{"RMETA", KEYCODE_RMETA, "Right Meta" },
|
||||
|
||||
{0, KEYCODE_INVALID, 0}
|
||||
};
|
||||
|
||||
@ -314,9 +327,11 @@ HardwareInput KeyboardHardwareInputSet::findHardwareInput(const Event &event) co
|
||||
switch (event.type) {
|
||||
case EVENT_KEYDOWN:
|
||||
case EVENT_KEYUP: {
|
||||
KeyState normalizedKeystate = normalizeKeyState(event.kbd);
|
||||
|
||||
const KeyTableEntry *key = nullptr;
|
||||
for (key = _keys; key->hwId; key++) {
|
||||
if (event.kbd.keycode == key->keycode) {
|
||||
if (normalizedKeystate.keycode == key->keycode) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -330,7 +345,7 @@ HardwareInput KeyboardHardwareInputSet::findHardwareInput(const Event &event) co
|
||||
byte modifierFlags = 0;
|
||||
|
||||
for (const ModifierTableEntry *modifier = _modifiers; modifier->id; modifier++) {
|
||||
if (event.kbd.flags & modifier->flag) {
|
||||
if (normalizedKeystate.flags & modifier->flag) {
|
||||
id += modifier->id;
|
||||
id += "+";
|
||||
fullKeyDesc += modifier->desc;
|
||||
@ -346,6 +361,50 @@ HardwareInput KeyboardHardwareInputSet::findHardwareInput(const Event &event) co
|
||||
}
|
||||
}
|
||||
|
||||
KeyState KeyboardHardwareInputSet::normalizeKeyState(const KeyState &keystate) {
|
||||
KeyState normalizedKeystate = keystate;
|
||||
|
||||
// We ignore the sticky modifiers as they traditionally
|
||||
// have no impact on the outcome of key presses.
|
||||
// TODO: Maybe Num Lock should act as a modifier for the keypad.
|
||||
normalizedKeystate.flags &= ~KBD_STICKY;
|
||||
|
||||
// Modifier keypresses ignore the corresponding modifier flag.
|
||||
// That way, for example, `Left Shift` is not identified
|
||||
// as `Shift+Left Shift` by the keymapper.
|
||||
switch (normalizedKeystate.keycode) {
|
||||
case KEYCODE_LSHIFT:
|
||||
case KEYCODE_RSHIFT:
|
||||
normalizedKeystate.flags &= ~KBD_SHIFT;
|
||||
break;
|
||||
case KEYCODE_LCTRL:
|
||||
case KEYCODE_RCTRL:
|
||||
normalizedKeystate.flags &= ~KBD_CTRL;
|
||||
break;
|
||||
case KEYCODE_LALT:
|
||||
case KEYCODE_RALT:
|
||||
normalizedKeystate.flags &= ~KBD_ALT;
|
||||
break;
|
||||
case KEYCODE_LMETA:
|
||||
case KEYCODE_RMETA:
|
||||
normalizedKeystate.flags &= ~KBD_META;
|
||||
break;
|
||||
case KEYCODE_SCROLLOCK:
|
||||
normalizedKeystate.flags &= ~KBD_SCRL;
|
||||
break;
|
||||
case KEYCODE_CAPSLOCK:
|
||||
normalizedKeystate.flags &= ~KBD_CAPS;
|
||||
break;
|
||||
case KEYCODE_NUMLOCK:
|
||||
normalizedKeystate.flags &= ~KBD_NUM;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return normalizedKeystate;
|
||||
}
|
||||
|
||||
MouseHardwareInputSet::MouseHardwareInputSet(const HardwareInputTableEntry *buttonEntries) :
|
||||
_buttonEntries(buttonEntries) {
|
||||
assert(_buttonEntries);
|
||||
|
@ -234,6 +234,9 @@ public:
|
||||
HardwareInput findHardwareInput(const String &id) const override;
|
||||
HardwareInput findHardwareInput(const Event &event) const override;
|
||||
|
||||
/** Transform a keystate into a canonical form that can be used to unambiguously identify the keypress */
|
||||
static KeyState normalizeKeyState(const KeyState &keystate);
|
||||
|
||||
private:
|
||||
const KeyTableEntry *_keys;
|
||||
const ModifierTableEntry *_modifiers;
|
||||
|
@ -128,7 +128,8 @@ Keymap::ActionArray Keymap::getMappedActions(const Event &event) const {
|
||||
switch (event.type) {
|
||||
case EVENT_KEYDOWN:
|
||||
case EVENT_KEYUP: {
|
||||
HardwareInput hardwareInput = HardwareInput::createKeyboard("", event.kbd, "");
|
||||
KeyState normalizedKeystate = KeyboardHardwareInputSet::normalizeKeyState(event.kbd);
|
||||
HardwareInput hardwareInput = HardwareInput::createKeyboard("", normalizedKeystate, "");
|
||||
return _hwActionMap[hardwareInput];
|
||||
}
|
||||
case EVENT_LBUTTONDOWN:
|
||||
|
@ -44,20 +44,21 @@ struct HardwareInput;
|
||||
class HardwareInputSet;
|
||||
class KeymapperDefaultBindings;
|
||||
|
||||
struct Event_EqualTo {
|
||||
struct HardwareInput_EqualTo {
|
||||
bool operator()(const HardwareInput& x, const HardwareInput& y) const {
|
||||
return (x.type == y.type)
|
||||
&& (x.key == y.key) // TODO: Remove the equality operator from KeyState
|
||||
&& (x.key.keycode == y.key.keycode)
|
||||
&& (x.key.flags == y.key.flags)
|
||||
&& (x.inputCode == y.inputCode);
|
||||
}
|
||||
};
|
||||
|
||||
struct Event_Hash {
|
||||
struct HardwareInput_Hash {
|
||||
uint operator()(const HardwareInput& x) const {
|
||||
uint hash = 7;
|
||||
hash = 31 * hash + x.type;
|
||||
hash = 31 * hash + x.key.keycode;
|
||||
hash = 31 * hash + (x.key.flags & ~KBD_STICKY);
|
||||
hash = 31 * hash + x.key.flags;
|
||||
hash = 31 * hash + x.inputCode;
|
||||
return hash;
|
||||
}
|
||||
@ -169,7 +170,7 @@ private:
|
||||
void registerMappings(Action *action, const StringArray &hwInputIds);
|
||||
bool areMappingsIdentical(const Array<HardwareInput> &inputs, const StringArray &mapping);
|
||||
|
||||
typedef HashMap<HardwareInput, ActionArray, Event_Hash, Event_EqualTo> HardwareActionMap;
|
||||
typedef HashMap<HardwareInput, ActionArray, HardwareInput_Hash, HardwareInput_EqualTo> HardwareActionMap;
|
||||
|
||||
KeymapType _type;
|
||||
String _id;
|
||||
|
@ -346,8 +346,8 @@ struct KeyState {
|
||||
|
||||
/**
|
||||
* Check if two key states are equal. This implementation ignores the state
|
||||
* of the sticky flags (caps lock, num lock, scroll lock) completely. This
|
||||
* functionality is currently only used by the keymapper.
|
||||
* of the sticky flags (caps lock, num lock, scroll lock) completely.
|
||||
* @todo is this still being used?
|
||||
*/
|
||||
bool operator==(const KeyState &x) const {
|
||||
// Intentionally ignore ASCII, as the keycode and non-sticky flag
|
||||
|
Loading…
Reference in New Issue
Block a user