From 4f7c0e7c4617931ebb642bf54c69dd2d1d22cc94 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 5 Aug 2024 18:49:19 -0700 Subject: [PATCH] Fixed key names for non-latin keyboard layouts --- src/events/SDL_keyboard.c | 52 ++++++++++++++++++++++++++------------- src/events/SDL_keymap.c | 28 +++++++-------------- 2 files changed, 44 insertions(+), 36 deletions(-) diff --git a/src/events/SDL_keyboard.c b/src/events/SDL_keyboard.c index fc23ebe317..c6d73d5d00 100644 --- a/src/events/SDL_keyboard.c +++ b/src/events/SDL_keyboard.c @@ -57,7 +57,8 @@ typedef struct SDL_Keyboard Uint8 keystate[SDL_NUM_SCANCODES]; SDL_Keymap *keymap; SDL_bool french_numbers; - SDL_bool non_latin_letters; + SDL_bool latin_letters; + SDL_bool thai_keyboard; Uint32 keycode_options; SDL_bool autorelease_pending; Uint64 hardware_timestamp; @@ -229,6 +230,17 @@ SDL_Keymap *SDL_GetCurrentKeymap(void) { SDL_Keyboard *keyboard = &SDL_keyboard; + if (keyboard->thai_keyboard) { + // Thai keyboards are QWERTY plus Thai characters, use the default QWERTY keymap + return NULL; + } + + if ((keyboard->keycode_options & KEYCODE_OPTION_LATIN_LETTERS) && + !keyboard->latin_letters) { + // We'll use the default QWERTY keymap + return NULL; + } + return keyboard->keymap; } @@ -253,10 +265,17 @@ void SDL_SetKeymap(SDL_Keymap *keymap, SDL_bool send_event) } // Detect non-Latin keymap - keyboard->non_latin_letters = SDL_TRUE; + keyboard->thai_keyboard = SDL_FALSE; + keyboard->latin_letters = SDL_FALSE; for (int i = SDL_SCANCODE_A; i <= SDL_SCANCODE_D; ++i) { - if (SDL_GetKeymapKeycode(keymap, (SDL_Scancode)i, SDL_KMOD_NONE) <= 0xFF) { - keyboard->non_latin_letters = SDL_FALSE; + SDL_Keycode key = SDL_GetKeymapKeycode(keymap, (SDL_Scancode)i, SDL_KMOD_NONE); + if (key <= 0xFF) { + keyboard->latin_letters = SDL_TRUE; + break; + } + + if (key >= 0x0E00 && key <= 0x0E7F) { + keyboard->thai_keyboard = SDL_TRUE; break; } } @@ -437,30 +456,29 @@ SDL_Keycode SDL_GetKeyFromScancode(SDL_Scancode scancode, SDL_Keymod modstate, S SDL_Keycode keycode; if (key_event) { + SDL_Keymap *keymap = SDL_GetCurrentKeymap(); SDL_bool numlock = (modstate & SDL_KMOD_NUM) != 0; // We won't be applying any modifiers by default modstate = SDL_KMOD_NONE; - if ((keyboard->keycode_options & KEYCODE_OPTION_LATIN_LETTERS) && - keyboard->non_latin_letters) { - keycode = SDL_GetKeymapKeycode(NULL, scancode, modstate); - } else { - if ((keyboard->keycode_options & KEYCODE_OPTION_FRENCH_NUMBERS) && - keyboard->french_numbers && - (scancode >= SDL_SCANCODE_1 && scancode <= SDL_SCANCODE_0)) { - // Add the shift state to generate a numeric keycode - modstate |= SDL_KMOD_SHIFT; - } - - keycode = SDL_GetKeymapKeycode(keyboard->keymap, scancode, modstate); + if ((keyboard->keycode_options & KEYCODE_OPTION_FRENCH_NUMBERS) && + keyboard->french_numbers && + (scancode >= SDL_SCANCODE_1 && scancode <= SDL_SCANCODE_0)) { + // Add the shift state to generate a numeric keycode + modstate |= SDL_KMOD_SHIFT; } + keycode = SDL_GetKeymapKeycode(keymap, scancode, modstate); + if (keyboard->keycode_options & KEYCODE_OPTION_HIDE_NUMPAD) { keycode = SDL_ConvertNumpadKeycode(keycode, numlock); } } else { - keycode = SDL_GetKeymapKeycode(keyboard->keymap, scancode, modstate); + // Use the real keymap + SDL_Keymap *keymap = keyboard->keymap; + + keycode = SDL_GetKeymapKeycode(keymap, scancode, modstate); } return keycode; } diff --git a/src/events/SDL_keymap.c b/src/events/SDL_keymap.c index 054fb09507..4f94170b7c 100644 --- a/src/events/SDL_keymap.c +++ b/src/events/SDL_keymap.c @@ -1008,17 +1008,11 @@ const char *SDL_GetKeyName(SDL_Keycode key, SDL_bool uppercase) // SDL_Keycode is defined as the unshifted key on the keyboard, // but the key name is defined as the letter printed on that key, // which is usually the shifted capital letter. - if (key >= 'a' && key <= 'z') { - key = 'A' + (key - 'a'); - } else if (key > 0x7F) { + if (key > 0x7F || (key >= 'a' && key <= 'z')) { SDL_Keymap *keymap = SDL_GetCurrentKeymap(); - SDL_Scancode scancode = SDL_GetKeymapScancode(keymap, key, NULL); - if (scancode != SDL_SCANCODE_UNKNOWN) { - if (key >= 0x0E00 && key <= 0x0E7F) { - // Thai keyboards are QWERTY plus Thai characters, so let's use the ASCII key names - return SDL_GetScancodeName(scancode); - } - + SDL_Keymod modstate; + SDL_Scancode scancode = SDL_GetKeymapScancode(keymap, key, &modstate); + if (scancode != SDL_SCANCODE_UNKNOWN && !(modstate & SDL_KMOD_SHIFT)) { SDL_Keycode capital = SDL_GetKeymapKeycode(keymap, scancode, SDL_KMOD_SHIFT); if (capital > 0x7F || (capital >= 'A' && capital <= 'Z')) { key = capital; @@ -1083,15 +1077,11 @@ SDL_Keycode SDL_GetKeyFromName(const char *name, SDL_bool uppercase) // SDL_Keycode is defined as the unshifted key on the keyboard, // but the key name is defined as the letter printed on that key, // which is usually the shifted capital letter. - if (key >= 'A' && key <= 'Z') { - key = 'a' + (key - 'A'); - } else if (key > 0x7F) { - SDL_Keymap *keymap = SDL_GetCurrentKeymap(); - SDL_Keymod modstate; - SDL_Scancode scancode = SDL_GetKeymapScancode(keymap, key, &modstate); - if (scancode != SDL_SCANCODE_UNKNOWN && (modstate & SDL_KMOD_SHIFT)) { - key = SDL_GetKeymapKeycode(keymap, scancode, SDL_KMOD_NONE); - } + SDL_Keymap *keymap = SDL_GetCurrentKeymap(); + SDL_Keymod modstate; + SDL_Scancode scancode = SDL_GetKeymapScancode(keymap, key, &modstate); + if (scancode != SDL_SCANCODE_UNKNOWN && (modstate & SDL_KMOD_SHIFT)) { + key = SDL_GetKeymapKeycode(keymap, scancode, SDL_KMOD_NONE); } } return key;