|
@@ -97,16 +97,74 @@ void SDL_SetKeymapEntry(SDL_Keymap *keymap, SDL_Scancode scancode, SDL_Keymod mo
|
|
|
|
|
|
SDL_Keycode SDL_GetKeymapKeycode(SDL_Keymap *keymap, SDL_Scancode scancode, SDL_Keymod modstate)
|
|
|
{
|
|
|
- SDL_Keycode keycode;
|
|
|
+ if (keymap) {
|
|
|
+ const void *value;
|
|
|
+ const SDL_Keymod normalized_modstate = NormalizeModifierStateForKeymap(modstate);
|
|
|
+ Uint32 key = ((Uint32)normalized_modstate << 16) | scancode;
|
|
|
|
|
|
- const Uint32 key = ((Uint32)NormalizeModifierStateForKeymap(modstate) << 16) | scancode;
|
|
|
- const void *value;
|
|
|
- if (keymap && SDL_FindInHashTable(keymap->scancode_to_keycode, (void *)(uintptr_t)key, &value)) {
|
|
|
- keycode = (SDL_Keycode)(uintptr_t)value;
|
|
|
- } else {
|
|
|
- keycode = SDL_GetDefaultKeyFromScancode(scancode, modstate);
|
|
|
+ // First, try the requested set of modifiers.
|
|
|
+ if (SDL_FindInHashTable(keymap->scancode_to_keycode, (void *)(uintptr_t)key, &value)) {
|
|
|
+ return (SDL_Keycode)(uintptr_t)value;
|
|
|
+ }
|
|
|
+
|
|
|
+ // If the requested set of modifiers was not found, search for the key from the highest to lowest modifier levels.
|
|
|
+ if (normalized_modstate) {
|
|
|
+ SDL_Keymod caps_mask = normalized_modstate & SDL_KMOD_CAPS;
|
|
|
+
|
|
|
+ for (int i = caps_mask ? 2 : 1; i; --i) {
|
|
|
+ // Shift level 5
|
|
|
+ if (normalized_modstate & SDL_KMOD_LEVEL5) {
|
|
|
+ const SDL_Keymod shifted_modstate = SDL_KMOD_LEVEL5 | caps_mask;
|
|
|
+ key = ((Uint32)shifted_modstate << 16) | scancode;
|
|
|
+
|
|
|
+ if (shifted_modstate != normalized_modstate && SDL_FindInHashTable(keymap->scancode_to_keycode, (void *)(uintptr_t)key, &value)) {
|
|
|
+ return (SDL_Keycode)(uintptr_t)value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Shift level 4 (Level 3 + Shift)
|
|
|
+ if ((normalized_modstate & (SDL_KMOD_MODE | SDL_KMOD_SHIFT)) == (SDL_KMOD_MODE | SDL_KMOD_SHIFT)) {
|
|
|
+ const SDL_Keymod shifted_modstate = SDL_KMOD_MODE | SDL_KMOD_SHIFT | caps_mask;
|
|
|
+ key = ((Uint32)shifted_modstate << 16) | scancode;
|
|
|
+
|
|
|
+ if (shifted_modstate != normalized_modstate && SDL_FindInHashTable(keymap->scancode_to_keycode, (void *)(uintptr_t)key, &value)) {
|
|
|
+ return (SDL_Keycode)(uintptr_t)value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Shift level 3
|
|
|
+ if (normalized_modstate & SDL_KMOD_MODE) {
|
|
|
+ const SDL_Keymod shifted_modstate = SDL_KMOD_MODE | caps_mask;
|
|
|
+ key = ((Uint32)shifted_modstate << 16) | scancode;
|
|
|
+
|
|
|
+ if (shifted_modstate != normalized_modstate && SDL_FindInHashTable(keymap->scancode_to_keycode, (void *)(uintptr_t)key, &value)) {
|
|
|
+ return (SDL_Keycode)(uintptr_t)value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Shift level 2
|
|
|
+ if (normalized_modstate & SDL_KMOD_SHIFT) {
|
|
|
+ const SDL_Keymod shifted_modstate = SDL_KMOD_SHIFT | caps_mask;
|
|
|
+ key = ((Uint32)shifted_modstate << 16) | scancode;
|
|
|
+
|
|
|
+ if (shifted_modstate != normalized_modstate && SDL_FindInHashTable(keymap->scancode_to_keycode, (void *)(uintptr_t)key, &value)) {
|
|
|
+ return (SDL_Keycode)(uintptr_t)value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Shift Level 1 (unmodified)
|
|
|
+ key = ((Uint32)caps_mask << 16) | scancode;
|
|
|
+ if (SDL_FindInHashTable(keymap->scancode_to_keycode, (void *)(uintptr_t)key, &value)) {
|
|
|
+ return (SDL_Keycode)(uintptr_t)value;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Clear the capslock mask, if set.
|
|
|
+ caps_mask = SDL_KMOD_NONE;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
- return keycode;
|
|
|
+
|
|
|
+ return SDL_GetDefaultKeyFromScancode(scancode, modstate);
|
|
|
}
|
|
|
|
|
|
SDL_Scancode SDL_GetKeymapScancode(SDL_Keymap *keymap, SDL_Keycode keycode, SDL_Keymod *modstate)
|