From 4f7c0e7c4617931ebb642bf54c69dd2d1d22cc94 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
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 fc23ebe317ba5..c6d73d5d00348 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 054fb0950786e..4f94170b7c13d 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;