From c535dd104d661035f44a835246feb0a5cb6631ae Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 19 Jun 2024 15:00:12 -0700 Subject: [PATCH] Added the ability to query the keymap for keycodes based on modifier state --- VisualC-GDK/SDL/SDL.vcxproj | 2 + VisualC-GDK/SDL/SDL.vcxproj.filters | 2 + VisualC-WinRT/SDL-UWP.vcxproj | 2 + VisualC-WinRT/SDL-UWP.vcxproj.filters | 6 + VisualC/SDL/SDL.vcxproj | 2 + VisualC/SDL/SDL.vcxproj.filters | 6 + Xcode/SDL/SDL.xcodeproj/project.pbxproj | 8 + docs/README-migration.md | 2 + include/SDL3/SDL_events.h | 8 +- include/SDL3/SDL_keyboard.h | 48 +- include/SDL3/SDL_keycode.h | 32 +- src/SDL_hashtable.c | 9 +- src/SDL_hashtable.h | 1 + src/SDL_utils.c | 25 + src/SDL_utils_c.h | 2 + src/dynapi/SDL_dynapi.sym | 2 + src/dynapi/SDL_dynapi_overrides.h | 2 + src/dynapi/SDL_dynapi_procs.h | 8 +- src/events/SDL_keyboard.c | 867 +----------------------- src/events/SDL_keyboard_c.h | 19 +- src/events/SDL_keymap.c | 711 +++++++++++++++++++ src/events/SDL_keymap_c.h | 37 + src/events/scancodes_ascii.h | 165 ----- src/video/cocoa/SDL_cocoakeyboard.m | 61 +- src/video/haiku/SDL_bkeyboard.cc | 217 +++--- src/video/ngage/SDL_ngageevents.cpp | 50 +- src/video/psp/SDL_pspevents.c | 226 +++--- src/video/vita/SDL_vitavideo.c | 6 +- src/video/wayland/SDL_waylandevents.c | 14 +- src/video/windows/SDL_windowskeyboard.c | 98 ++- src/video/x11/SDL_x11events.c | 2 +- src/video/x11/SDL_x11keyboard.c | 6 +- test/checkkeys.c | 126 +++- test/testautomation_keyboard.c | 12 +- 34 files changed, 1376 insertions(+), 1408 deletions(-) create mode 100644 src/events/SDL_keymap.c create mode 100644 src/events/SDL_keymap_c.h delete mode 100644 src/events/scancodes_ascii.h diff --git a/VisualC-GDK/SDL/SDL.vcxproj b/VisualC-GDK/SDL/SDL.vcxproj index 057cb1c331ae9..82a5aaae01495 100644 --- a/VisualC-GDK/SDL/SDL.vcxproj +++ b/VisualC-GDK/SDL/SDL.vcxproj @@ -414,6 +414,7 @@ + @@ -634,6 +635,7 @@ + diff --git a/VisualC-GDK/SDL/SDL.vcxproj.filters b/VisualC-GDK/SDL/SDL.vcxproj.filters index 9ac9cd48fe5e4..91684485f4fa2 100644 --- a/VisualC-GDK/SDL/SDL.vcxproj.filters +++ b/VisualC-GDK/SDL/SDL.vcxproj.filters @@ -47,6 +47,7 @@ + @@ -326,6 +327,7 @@ + diff --git a/VisualC-WinRT/SDL-UWP.vcxproj b/VisualC-WinRT/SDL-UWP.vcxproj index ac172fb96456a..0231e2dd03a3a 100644 --- a/VisualC-WinRT/SDL-UWP.vcxproj +++ b/VisualC-WinRT/SDL-UWP.vcxproj @@ -119,6 +119,7 @@ + @@ -320,6 +321,7 @@ + diff --git a/VisualC-WinRT/SDL-UWP.vcxproj.filters b/VisualC-WinRT/SDL-UWP.vcxproj.filters index 8447d95db2bc3..7112f2f9cc378 100644 --- a/VisualC-WinRT/SDL-UWP.vcxproj.filters +++ b/VisualC-WinRT/SDL-UWP.vcxproj.filters @@ -273,6 +273,9 @@ Source Files + + Source Files + Source Files @@ -585,6 +588,9 @@ Source Files + + Source Files + Source Files diff --git a/VisualC/SDL/SDL.vcxproj b/VisualC/SDL/SDL.vcxproj index 0164338ee5ba3..a9849a3a53957 100644 --- a/VisualC/SDL/SDL.vcxproj +++ b/VisualC/SDL/SDL.vcxproj @@ -338,6 +338,7 @@ + @@ -524,6 +525,7 @@ + diff --git a/VisualC/SDL/SDL.vcxproj.filters b/VisualC/SDL/SDL.vcxproj.filters index 17838de16a1dd..448bf3e4e49a5 100644 --- a/VisualC/SDL/SDL.vcxproj.filters +++ b/VisualC/SDL/SDL.vcxproj.filters @@ -507,6 +507,9 @@ events + + events + events @@ -1000,6 +1003,9 @@ events + + events + events diff --git a/Xcode/SDL/SDL.xcodeproj/project.pbxproj b/Xcode/SDL/SDL.xcodeproj/project.pbxproj index 40e6effe10725..43ebab04d0429 100644 --- a/Xcode/SDL/SDL.xcodeproj/project.pbxproj +++ b/Xcode/SDL/SDL.xcodeproj/project.pbxproj @@ -386,6 +386,8 @@ F310138D2C1F2CB700FBE946 /* SDL_getenv_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F310138A2C1F2CB700FBE946 /* SDL_getenv_c.h */; }; F310138E2C1F2CB700FBE946 /* SDL_random.c in Sources */ = {isa = PBXBuildFile; fileRef = F310138B2C1F2CB700FBE946 /* SDL_random.c */; }; F310138F2C1F2CB700FBE946 /* SDL_sysstdlib.h in Headers */ = {isa = PBXBuildFile; fileRef = F310138C2C1F2CB700FBE946 /* SDL_sysstdlib.h */; }; + F31013C72C24E98200FBE946 /* SDL_keymap.c in Sources */ = {isa = PBXBuildFile; fileRef = F31013C52C24E98200FBE946 /* SDL_keymap.c */; }; + F31013C82C24E98200FBE946 /* SDL_keymap_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F31013C62C24E98200FBE946 /* SDL_keymap_c.h */; }; F316ABD82B5C3185002EF551 /* SDL_memset.c in Sources */ = {isa = PBXBuildFile; fileRef = F316ABD62B5C3185002EF551 /* SDL_memset.c */; }; F316ABD92B5C3185002EF551 /* SDL_memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = F316ABD72B5C3185002EF551 /* SDL_memcpy.c */; }; F316ABDB2B5CA721002EF551 /* SDL_memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = F316ABDA2B5CA721002EF551 /* SDL_memmove.c */; }; @@ -915,6 +917,8 @@ F310138A2C1F2CB700FBE946 /* SDL_getenv_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_getenv_c.h; sourceTree = ""; }; F310138B2C1F2CB700FBE946 /* SDL_random.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_random.c; sourceTree = ""; }; F310138C2C1F2CB700FBE946 /* SDL_sysstdlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_sysstdlib.h; sourceTree = ""; }; + F31013C52C24E98200FBE946 /* SDL_keymap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_keymap.c; sourceTree = ""; }; + F31013C62C24E98200FBE946 /* SDL_keymap_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_keymap_c.h; sourceTree = ""; }; F316ABD62B5C3185002EF551 /* SDL_memset.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_memset.c; sourceTree = ""; }; F316ABD72B5C3185002EF551 /* SDL_memcpy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_memcpy.c; sourceTree = ""; }; F316ABDA2B5CA721002EF551 /* SDL_memmove.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_memmove.c; sourceTree = ""; }; @@ -2183,6 +2187,8 @@ A7D8A93523E2514000DCD162 /* SDL_events.c */, A7D8A93D23E2514000DCD162 /* SDL_keyboard_c.h */, A7D8A93823E2514000DCD162 /* SDL_keyboard.c */, + F31013C62C24E98200FBE946 /* SDL_keymap_c.h */, + F31013C52C24E98200FBE946 /* SDL_keymap.c */, A7D8A92B23E2514000DCD162 /* SDL_mouse_c.h */, A7D8A92A23E2514000DCD162 /* SDL_mouse.c */, 63134A232A7902FD0021E9A6 /* SDL_pen_c.h */, @@ -2422,6 +2428,7 @@ F3F7D9392933074E00816151 /* SDL_opengles2_gl2ext.h in Headers */, F3F7D9692933074E00816151 /* SDL_opengles2_gl2platform.h in Headers */, F3F7D9092933074E00816151 /* SDL_opengles2_khrplatform.h in Headers */, + F31013C82C24E98200FBE946 /* SDL_keymap_c.h in Headers */, 63134A222A7902CF0021E9A6 /* SDL_pen.h in Headers */, 63134A252A7902FD0021E9A6 /* SDL_pen_c.h in Headers */, F36C34312C0F876500991150 /* SDL_offscreenvulkan.h in Headers */, @@ -2675,6 +2682,7 @@ A7D8BAC723E2514500DCD162 /* e_pow.c in Sources */, A7D8B41C23E2514300DCD162 /* SDL_systls.c in Sources */, 9846B07C287A9020000C35C8 /* SDL_hidapi_shield.c in Sources */, + F31013C72C24E98200FBE946 /* SDL_keymap.c in Sources */, A7D8BBD923E2574800DCD162 /* SDL_uikitmessagebox.m in Sources */, F32DDAD42AB795A30041EAA5 /* SDL_audioresample.c in Sources */, F3FA5A212B59ACE000FEAD97 /* yuv_rgb_std.c in Sources */, diff --git a/docs/README-migration.md b/docs/README-migration.md index db55d27b1d509..00629a3fdeeff 100644 --- a/docs/README-migration.md +++ b/docs/README-migration.md @@ -890,6 +890,8 @@ The following symbols have been removed: Text input is no longer automatically enabled when initializing video, you should call SDL_StartTextInput() when you want to receive text input and call SDL_StopTextInput() when you are done. Starting text input may shown an input method editor (IME) and cause key up/down events to be skipped, so should only be enabled when the application wants text input. +SDL_GetDefaultKeyFromScancode(), SDL_GetKeyFromScancode(), and SDL_GetScancodeFromKey() take an SDL_Keymod parameter and use that to provide the correct result based on keyboard modifier state. + The following functions have been renamed: * SDL_IsScreenKeyboardShown() => SDL_ScreenKeyboardShown() * SDL_IsTextInputActive() => SDL_TextInputActive() diff --git a/include/SDL3/SDL_events.h b/include/SDL3/SDL_events.h index 829619e0db648..1494740409df3 100644 --- a/include/SDL3/SDL_events.h +++ b/include/SDL3/SDL_events.h @@ -316,8 +316,7 @@ typedef struct SDL_KeyboardEvent /** * Keyboard text editing event structure (event.edit.*) * - * The `text` is owned by SDL and should be copied if the application wants to - * hold onto it beyond the scope of handling this event. + * The text string follows the SDL_GetStringRule. * * \since This struct is available since SDL 3.0.0. */ @@ -335,8 +334,7 @@ typedef struct SDL_TextEditingEvent /** * Keyboard text input event structure (event.text.*) * - * The `text` is owned by SDL and should be copied if the application wants to - * hold onto it beyond the scope of handling this event. + * The text string follows the SDL_GetStringRule. * * This event will never be delivered unless text input is enabled by calling * SDL_StartTextInput(). Text input is disabled by default! @@ -733,7 +731,7 @@ typedef struct SDL_PenButtonEvent * An event used to drop text or request a file open by the system * (event.drop.*) * - * The `source` and `data` are owned by SDL and should be copied if the application wants to hold onto them beyond the scope of handling this event. + * The source and data strings follow the SDL_GetStringRule. * * \since This struct is available since SDL 3.0.0. */ diff --git a/include/SDL3/SDL_keyboard.h b/include/SDL3/SDL_keyboard.h index ffa15949504c6..af505ce2e1ef7 100644 --- a/include/SDL3/SDL_keyboard.h +++ b/include/SDL3/SDL_keyboard.h @@ -211,6 +211,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_SetModState(SDL_Keymod modstate); * See SDL_Keycode for details. * * \param scancode the desired SDL_Scancode to query. + * \param modstate the modifier state to use when translating the scancode to a keycode. * \returns the SDL_Keycode that corresponds to the given SDL_Scancode. * * \since This function is available since SDL 3.0.0. @@ -218,7 +219,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_SetModState(SDL_Keymod modstate); * \sa SDL_GetKeyName * \sa SDL_GetScancodeFromKey */ -extern SDL_DECLSPEC SDL_Keycode SDLCALL SDL_GetDefaultKeyFromScancode(SDL_Scancode scancode); +extern SDL_DECLSPEC SDL_Keycode SDLCALL SDL_GetDefaultKeyFromScancode(SDL_Scancode scancode, SDL_Keymod modstate); /** * Get the key code corresponding to the given scancode according to the @@ -227,35 +228,67 @@ extern SDL_DECLSPEC SDL_Keycode SDLCALL SDL_GetDefaultKeyFromScancode(SDL_Scanco * See SDL_Keycode for details. * * \param scancode the desired SDL_Scancode to query. + * \param modstate the modifier state to use when translating the scancode to a keycode. * \returns the SDL_Keycode that corresponds to the given SDL_Scancode. * * \since This function is available since SDL 3.0.0. * + * \sa SDL_GetDefaultKeyFromScancode * \sa SDL_GetKeyName * \sa SDL_GetScancodeFromKey */ -extern SDL_DECLSPEC SDL_Keycode SDLCALL SDL_GetKeyFromScancode(SDL_Scancode scancode); +extern SDL_DECLSPEC SDL_Keycode SDLCALL SDL_GetKeyFromScancode(SDL_Scancode scancode, SDL_Keymod modstate); + +/** + * Get the scancode corresponding to the given key code according to a default en_US keyboard layout. + * + * Note that there may be multiple scancode+modifier states that can generate this keycode, this will just return the first one found. + * + * \param key the desired SDL_Keycode to query. + * \param modstate a pointer to the modifier state that would be used when the scancode generates this key, may be NULL. + * \returns the SDL_Scancode that corresponds to the given SDL_Keycode. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_GetScancodeFromKey + * \sa SDL_GetScancodeName + */ +extern SDL_DECLSPEC SDL_Scancode SDLCALL SDL_GetDefaultScancodeFromKey(SDL_Keycode key, SDL_Keymod *modstate); /** * Get the scancode corresponding to the given key code according to the * current keyboard layout. * - * See SDL_Scancode for details. + * Note that there may be multiple scancode+modifier states that can generate this keycode, this will just return the first one found. * * \param key the desired SDL_Keycode to query. + * \param modstate a pointer to the modifier state that would be used when the scancode generates this key, may be NULL. * \returns the SDL_Scancode that corresponds to the given SDL_Keycode. * * \since This function is available since SDL 3.0.0. * + * \sa SDL_GetDefaultScancodeFromKey * \sa SDL_GetKeyFromScancode * \sa SDL_GetScancodeName */ -extern SDL_DECLSPEC SDL_Scancode SDLCALL SDL_GetScancodeFromKey(SDL_Keycode key); +extern SDL_DECLSPEC SDL_Scancode SDLCALL SDL_GetScancodeFromKey(SDL_Keycode key, SDL_Keymod *modstate); /** - * Get a human-readable name for a scancode. + * Set a human-readable name for a scancode. + * + * \param scancode the desired SDL_Scancode + * \param name the name to use for the scancode, encoded as UTF-8. The string is not copied, so the pointer given to this function must stay valid while SDL is being used. + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 3.0.0. * - * See SDL_Scancode for details. + * \sa SDL_GetScancodeName + */ +extern SDL_DECLSPEC int SDLCALL SDL_SetScancodeName(SDL_Scancode scancode, const char *name); + +/** + * Get a human-readable name for a scancode. * * The returned string follows the SDL_GetStringRule. * @@ -276,6 +309,7 @@ extern SDL_DECLSPEC SDL_Scancode SDLCALL SDL_GetScancodeFromKey(SDL_Keycode key) * * \sa SDL_GetScancodeFromKey * \sa SDL_GetScancodeFromName + * \sa SDL_SetScancodeName */ extern SDL_DECLSPEC const char *SDLCALL SDL_GetScancodeName(SDL_Scancode scancode); @@ -297,8 +331,6 @@ extern SDL_DECLSPEC SDL_Scancode SDLCALL SDL_GetScancodeFromName(const char *nam /** * Get a human-readable name for a key. * - * See SDL_Scancode and SDL_Keycode for details. - * * The returned string follows the SDL_GetStringRule. * * \param key the desired SDL_Keycode to query. diff --git a/include/SDL3/SDL_keycode.h b/include/SDL3/SDL_keycode.h index 839c24503ab32..18b802194a490 100644 --- a/include/SDL3/SDL_keycode.h +++ b/include/SDL3/SDL_keycode.h @@ -88,6 +88,32 @@ typedef Uint32 SDL_Keycode; #define SDLK_GREATER '>' #define SDLK_QUESTION '?' #define SDLK_AT '@' +#define SDLK_A 'A' +#define SDLK_B 'B' +#define SDLK_C 'C' +#define SDLK_D 'D' +#define SDLK_E 'E' +#define SDLK_F 'F' +#define SDLK_G 'G' +#define SDLK_H 'H' +#define SDLK_I 'I' +#define SDLK_J 'J' +#define SDLK_K 'K' +#define SDLK_L 'L' +#define SDLK_M 'M' +#define SDLK_N 'N' +#define SDLK_O 'O' +#define SDLK_P 'P' +#define SDLK_Q 'Q' +#define SDLK_R 'R' +#define SDLK_S 'S' +#define SDLK_T 'T' +#define SDLK_U 'U' +#define SDLK_V 'V' +#define SDLK_W 'W' +#define SDLK_X 'X' +#define SDLK_Y 'Y' +#define SDLK_Z 'Z' #define SDLK_LEFTBRACKET '[' #define SDLK_BACKSLASH '\\' #define SDLK_RIGHTBRACKET ']' @@ -120,6 +146,11 @@ typedef Uint32 SDL_Keycode; #define SDLK_x 'x' #define SDLK_y 'y' #define SDLK_z 'z' +#define SDLK_LEFTBRACE '{' +#define SDLK_PIPE '|' +#define SDLK_RIGHTBRACE '}' +#define SDLK_TILDE '~' +#define SDLK_DELETE '\x7F' #define SDLK_CAPSLOCK SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CAPSLOCK) #define SDLK_F1 SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F1) #define SDLK_F2 SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_F2) @@ -139,7 +170,6 @@ typedef Uint32 SDL_Keycode; #define SDLK_INSERT SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_INSERT) #define SDLK_HOME SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_HOME) #define SDLK_PAGEUP SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PAGEUP) -#define SDLK_DELETE '\x7F' #define SDLK_END SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_END) #define SDLK_PAGEDOWN SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PAGEDOWN) #define SDLK_RIGHT SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RIGHT) diff --git a/src/SDL_hashtable.c b/src/SDL_hashtable.c index 60488ed18be97..fc7a44791c9a4 100644 --- a/src/SDL_hashtable.c +++ b/src/SDL_hashtable.c @@ -241,7 +241,7 @@ SDL_bool SDL_HashTableEmpty(SDL_HashTable *table) return SDL_TRUE; } -void SDL_DestroyHashTable(SDL_HashTable *table) +void SDL_EmptyHashTable(SDL_HashTable *table) { if (table) { void *data = table->data; @@ -257,8 +257,15 @@ void SDL_DestroyHashTable(SDL_HashTable *table) SDL_free(item); item = next; } + table->table[i] = NULL; } + } +} +void SDL_DestroyHashTable(SDL_HashTable *table) +{ + if (table) { + SDL_EmptyHashTable(table); SDL_free(table->table); SDL_free(table); } diff --git a/src/SDL_hashtable.h b/src/SDL_hashtable.h index 96614bc17d7bd..ef0945ee0c47b 100644 --- a/src/SDL_hashtable.h +++ b/src/SDL_hashtable.h @@ -36,6 +36,7 @@ SDL_HashTable *SDL_CreateHashTable(void *data, const SDL_HashTable_NukeFn nukefn, const SDL_bool stackable); +void SDL_EmptyHashTable(SDL_HashTable *table); void SDL_DestroyHashTable(SDL_HashTable *table); SDL_bool SDL_InsertIntoHashTable(SDL_HashTable *table, const void *key, const void *value); SDL_bool SDL_RemoveFromHashTable(SDL_HashTable *table, const void *key); diff --git a/src/SDL_utils.c b/src/SDL_utils.c index 222cf49a3ed13..0aaa3dc391bc3 100644 --- a/src/SDL_utils.c +++ b/src/SDL_utils.c @@ -101,6 +101,31 @@ SDL_bool SDL_endswith(const char *string, const char *suffix) return SDL_FALSE; } +char *SDL_UCS4ToUTF8(Uint32 ch, char *dst) +{ + Uint8 *p = (Uint8 *)dst; + if (ch <= 0x7F) { + *p = (Uint8)ch; + ++dst; + } else if (ch <= 0x7FF) { + p[0] = 0xC0 | (Uint8)((ch >> 6) & 0x1F); + p[1] = 0x80 | (Uint8)(ch & 0x3F); + dst += 2; + } else if (ch <= 0xFFFF) { + p[0] = 0xE0 | (Uint8)((ch >> 12) & 0x0F); + p[1] = 0x80 | (Uint8)((ch >> 6) & 0x3F); + p[2] = 0x80 | (Uint8)(ch & 0x3F); + dst += 3; + } else { + p[0] = 0xF0 | (Uint8)((ch >> 18) & 0x07); + p[1] = 0x80 | (Uint8)((ch >> 12) & 0x3F); + p[2] = 0x80 | (Uint8)((ch >> 6) & 0x3F); + p[3] = 0x80 | (Uint8)(ch & 0x3F); + dst += 4; + } + return dst; +} + /* Assume we can wrap SDL_AtomicInt values and cast to Uint32 */ SDL_COMPILE_TIME_ASSERT(sizeof_object_id, sizeof(int) == sizeof(Uint32)); diff --git a/src/SDL_utils_c.h b/src/SDL_utils_c.h index 35d8543e8a04f..fb83c30be9ef8 100644 --- a/src/SDL_utils_c.h +++ b/src/SDL_utils_c.h @@ -32,6 +32,8 @@ extern void SDL_CalculateFraction(float x, int *numerator, int *denominator); extern SDL_bool SDL_endswith(const char *string, const char *suffix); +extern char *SDL_UCS4ToUTF8(Uint32 ch, char *dst); + typedef enum { SDL_OBJECT_TYPE_UNKNOWN, diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym index 56191fc18b9a8..89e7a13f57f6e 100644 --- a/src/dynapi/SDL_dynapi.sym +++ b/src/dynapi/SDL_dynapi.sym @@ -210,6 +210,7 @@ SDL3_0.0.0 { SDL_GetDefaultAssertionHandler; SDL_GetDefaultCursor; SDL_GetDefaultKeyFromScancode; + SDL_GetDefaultScancodeFromKey; SDL_GetDesktopDisplayMode; SDL_GetDisplayBounds; SDL_GetDisplayContentScale; @@ -732,6 +733,7 @@ SDL3_0.0.0 { SDL_SetRenderTarget; SDL_SetRenderVSync; SDL_SetRenderViewport; + SDL_SetScancodeName; SDL_SetStringProperty; SDL_SetSurfaceAlphaMod; SDL_SetSurfaceBlendMode; diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index d79f758f6187e..6ea7208db5183 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -235,6 +235,7 @@ #define SDL_GetDefaultAssertionHandler SDL_GetDefaultAssertionHandler_REAL #define SDL_GetDefaultCursor SDL_GetDefaultCursor_REAL #define SDL_GetDefaultKeyFromScancode SDL_GetDefaultKeyFromScancode_REAL +#define SDL_GetDefaultScancodeFromKey SDL_GetDefaultScancodeFromKey_REAL #define SDL_GetDesktopDisplayMode SDL_GetDesktopDisplayMode_REAL #define SDL_GetDisplayBounds SDL_GetDisplayBounds_REAL #define SDL_GetDisplayContentScale SDL_GetDisplayContentScale_REAL @@ -757,6 +758,7 @@ #define SDL_SetRenderTarget SDL_SetRenderTarget_REAL #define SDL_SetRenderVSync SDL_SetRenderVSync_REAL #define SDL_SetRenderViewport SDL_SetRenderViewport_REAL +#define SDL_SetScancodeName SDL_SetScancodeName_REAL #define SDL_SetStringProperty SDL_SetStringProperty_REAL #define SDL_SetSurfaceAlphaMod SDL_SetSurfaceAlphaMod_REAL #define SDL_SetSurfaceBlendMode SDL_SetSurfaceBlendMode_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 8bdecdb6c6ac5..75a0cb05a193e 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -254,7 +254,8 @@ SDL_DYNAPI_PROC(int,SDL_GetDayOfYear,(int a, int b, int c),(a,b,c),return) SDL_DYNAPI_PROC(int,SDL_GetDaysInMonth,(int a, int b),(a,b),return) SDL_DYNAPI_PROC(SDL_AssertionHandler,SDL_GetDefaultAssertionHandler,(void),(),return) SDL_DYNAPI_PROC(SDL_Cursor*,SDL_GetDefaultCursor,(void),(),return) -SDL_DYNAPI_PROC(SDL_Keycode,SDL_GetDefaultKeyFromScancode,(SDL_Scancode a),(a),return) +SDL_DYNAPI_PROC(SDL_Keycode,SDL_GetDefaultKeyFromScancode,(SDL_Scancode a, SDL_Keymod b),(a,b),return) +SDL_DYNAPI_PROC(SDL_Scancode,SDL_GetDefaultScancodeFromKey,(SDL_Keycode a, SDL_Keymod *b),(a,b),return) SDL_DYNAPI_PROC(const SDL_DisplayMode*,SDL_GetDesktopDisplayMode,(SDL_DisplayID a),(a),return) SDL_DYNAPI_PROC(int,SDL_GetDisplayBounds,(SDL_DisplayID a, SDL_Rect *b),(a,b),return) SDL_DYNAPI_PROC(float,SDL_GetDisplayContentScale,(SDL_DisplayID a),(a),return) @@ -364,7 +365,7 @@ SDL_DYNAPI_PROC(SDL_JoystickType,SDL_GetJoystickType,(SDL_Joystick *a),(a),retur SDL_DYNAPI_PROC(Uint16,SDL_GetJoystickVendor,(SDL_Joystick *a),(a),return) SDL_DYNAPI_PROC(SDL_JoystickID*,SDL_GetJoysticks,(int *a),(a),return) SDL_DYNAPI_PROC(SDL_Keycode,SDL_GetKeyFromName,(const char *a),(a),return) -SDL_DYNAPI_PROC(SDL_Keycode,SDL_GetKeyFromScancode,(SDL_Scancode a),(a),return) +SDL_DYNAPI_PROC(SDL_Keycode,SDL_GetKeyFromScancode,(SDL_Scancode a, SDL_Keymod b),(a,b),return) SDL_DYNAPI_PROC(const char*,SDL_GetKeyName,(SDL_Keycode a),(a),return) SDL_DYNAPI_PROC(SDL_Window*,SDL_GetKeyboardFocus,(void),(),return) SDL_DYNAPI_PROC(const char*,SDL_GetKeyboardInstanceName,(SDL_KeyboardID a),(a),return) @@ -451,7 +452,7 @@ SDL_DYNAPI_PROC(const char *,SDL_GetRendererName,(SDL_Renderer *a),(a),return) SDL_DYNAPI_PROC(SDL_PropertiesID,SDL_GetRendererProperties,(SDL_Renderer *a),(a),return) SDL_DYNAPI_PROC(const char*,SDL_GetRevision,(void),(),return) SDL_DYNAPI_PROC(size_t,SDL_GetSIMDAlignment,(void),(),return) -SDL_DYNAPI_PROC(SDL_Scancode,SDL_GetScancodeFromKey,(SDL_Keycode a),(a),return) +SDL_DYNAPI_PROC(SDL_Scancode,SDL_GetScancodeFromKey,(SDL_Keycode a, SDL_Keymod *b),(a,b),return) SDL_DYNAPI_PROC(SDL_Scancode,SDL_GetScancodeFromName,(const char *a),(a),return) SDL_DYNAPI_PROC(const char*,SDL_GetScancodeName,(SDL_Scancode a),(a),return) SDL_DYNAPI_PROC(Uint32,SDL_GetSemaphoreValue,(SDL_Semaphore *a),(a),return) @@ -767,6 +768,7 @@ SDL_DYNAPI_PROC(int,SDL_SetRenderScale,(SDL_Renderer *a, float b, float c),(a,b, SDL_DYNAPI_PROC(int,SDL_SetRenderTarget,(SDL_Renderer *a, SDL_Texture *b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_SetRenderVSync,(SDL_Renderer *a, int b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_SetRenderViewport,(SDL_Renderer *a, const SDL_Rect *b),(a,b),return) +SDL_DYNAPI_PROC(int,SDL_SetScancodeName,(SDL_Scancode a, const char *b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_SetStringProperty,(SDL_PropertiesID a, const char *b, const char *c),(a,b,c),return) SDL_DYNAPI_PROC(int,SDL_SetSurfaceAlphaMod,(SDL_Surface *a, Uint8 b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_SetSurfaceBlendMode,(SDL_Surface *a, SDL_BlendMode b),(a,b),return) diff --git a/src/events/SDL_keyboard.c b/src/events/SDL_keyboard.c index 3492adc8c7b14..ac69713d41a46 100644 --- a/src/events/SDL_keyboard.c +++ b/src/events/SDL_keyboard.c @@ -23,8 +23,8 @@ /* General keyboard handling code for SDL */ #include "SDL_events_c.h" +#include "SDL_keymap_c.h" #include "../video/SDL_sysvideo.h" -#include "scancodes_ascii.h" /* #define DEBUG_KEYBOARD */ @@ -53,7 +53,7 @@ typedef struct SDL_Keyboard SDL_Keymod modstate; Uint8 keysource[SDL_NUM_SCANCODES]; Uint8 keystate[SDL_NUM_SCANCODES]; - SDL_Keycode keymap[SDL_NUM_SCANCODES]; + SDL_Keymap *keymap; SDL_bool autorelease_pending; Uint64 hardware_timestamp; } SDL_Keyboard; @@ -62,625 +62,9 @@ static SDL_Keyboard SDL_keyboard; static int SDL_keyboard_count; static SDL_KeyboardInstance *SDL_keyboards; -static const SDL_Keycode SDL_default_keymap[SDL_NUM_SCANCODES] = { - /* 0 */ SDLK_UNKNOWN, - /* 1 */ SDLK_UNKNOWN, - /* 2 */ SDLK_UNKNOWN, - /* 3 */ SDLK_UNKNOWN, - /* 4 */ 'a', - /* 5 */ 'b', - /* 6 */ 'c', - /* 7 */ 'd', - /* 8 */ 'e', - /* 9 */ 'f', - /* 10 */ 'g', - /* 11 */ 'h', - /* 12 */ 'i', - /* 13 */ 'j', - /* 14 */ 'k', - /* 15 */ 'l', - /* 16 */ 'm', - /* 17 */ 'n', - /* 18 */ 'o', - /* 19 */ 'p', - /* 20 */ 'q', - /* 21 */ 'r', - /* 22 */ 's', - /* 23 */ 't', - /* 24 */ 'u', - /* 25 */ 'v', - /* 26 */ 'w', - /* 27 */ 'x', - /* 28 */ 'y', - /* 29 */ 'z', - /* 30 */ '1', - /* 31 */ '2', - /* 32 */ '3', - /* 33 */ '4', - /* 34 */ '5', - /* 35 */ '6', - /* 36 */ '7', - /* 37 */ '8', - /* 38 */ '9', - /* 39 */ '0', - /* 40 */ SDLK_RETURN, - /* 41 */ SDLK_ESCAPE, - /* 42 */ SDLK_BACKSPACE, - /* 43 */ SDLK_TAB, - /* 44 */ SDLK_SPACE, - /* 45 */ '-', - /* 46 */ '=', - /* 47 */ '[', - /* 48 */ ']', - /* 49 */ '\\', - /* 50 */ '#', - /* 51 */ ';', - /* 52 */ '\'', - /* 53 */ '`', - /* 54 */ ',', - /* 55 */ '.', - /* 56 */ '/', - /* 57 */ SDLK_CAPSLOCK, - /* 58 */ SDLK_F1, - /* 59 */ SDLK_F2, - /* 60 */ SDLK_F3, - /* 61 */ SDLK_F4, - /* 62 */ SDLK_F5, - /* 63 */ SDLK_F6, - /* 64 */ SDLK_F7, - /* 65 */ SDLK_F8, - /* 66 */ SDLK_F9, - /* 67 */ SDLK_F10, - /* 68 */ SDLK_F11, - /* 69 */ SDLK_F12, - /* 70 */ SDLK_PRINTSCREEN, - /* 71 */ SDLK_SCROLLLOCK, - /* 72 */ SDLK_PAUSE, - /* 73 */ SDLK_INSERT, - /* 74 */ SDLK_HOME, - /* 75 */ SDLK_PAGEUP, - /* 76 */ SDLK_DELETE, - /* 77 */ SDLK_END, - /* 78 */ SDLK_PAGEDOWN, - /* 79 */ SDLK_RIGHT, - /* 80 */ SDLK_LEFT, - /* 81 */ SDLK_DOWN, - /* 82 */ SDLK_UP, - /* 83 */ SDLK_NUMLOCKCLEAR, - /* 84 */ SDLK_KP_DIVIDE, - /* 85 */ SDLK_KP_MULTIPLY, - /* 86 */ SDLK_KP_MINUS, - /* 87 */ SDLK_KP_PLUS, - /* 88 */ SDLK_KP_ENTER, - /* 89 */ SDLK_KP_1, - /* 90 */ SDLK_KP_2, - /* 91 */ SDLK_KP_3, - /* 92 */ SDLK_KP_4, - /* 93 */ SDLK_KP_5, - /* 94 */ SDLK_KP_6, - /* 95 */ SDLK_KP_7, - /* 96 */ SDLK_KP_8, - /* 97 */ SDLK_KP_9, - /* 98 */ SDLK_KP_0, - /* 99 */ SDLK_KP_PERIOD, - /* 100 */ SDLK_UNKNOWN, - /* 101 */ SDLK_APPLICATION, - /* 102 */ SDLK_POWER, - /* 103 */ SDLK_KP_EQUALS, - /* 104 */ SDLK_F13, - /* 105 */ SDLK_F14, - /* 106 */ SDLK_F15, - /* 107 */ SDLK_F16, - /* 108 */ SDLK_F17, - /* 109 */ SDLK_F18, - /* 110 */ SDLK_F19, - /* 111 */ SDLK_F20, - /* 112 */ SDLK_F21, - /* 113 */ SDLK_F22, - /* 114 */ SDLK_F23, - /* 115 */ SDLK_F24, - /* 116 */ SDLK_EXECUTE, - /* 117 */ SDLK_HELP, - /* 118 */ SDLK_MENU, - /* 119 */ SDLK_SELECT, - /* 120 */ SDLK_STOP, - /* 121 */ SDLK_AGAIN, - /* 122 */ SDLK_UNDO, - /* 123 */ SDLK_CUT, - /* 124 */ SDLK_COPY, - /* 125 */ SDLK_PASTE, - /* 126 */ SDLK_FIND, - /* 127 */ SDLK_MUTE, - /* 128 */ SDLK_VOLUMEUP, - /* 129 */ SDLK_VOLUMEDOWN, - /* 130 */ SDLK_UNKNOWN, - /* 131 */ SDLK_UNKNOWN, - /* 132 */ SDLK_UNKNOWN, - /* 133 */ SDLK_KP_COMMA, - /* 134 */ SDLK_KP_EQUALSAS400, - /* 135 */ SDLK_UNKNOWN, - /* 136 */ SDLK_UNKNOWN, - /* 137 */ SDLK_UNKNOWN, - /* 138 */ SDLK_UNKNOWN, - /* 139 */ SDLK_UNKNOWN, - /* 140 */ SDLK_UNKNOWN, - /* 141 */ SDLK_UNKNOWN, - /* 142 */ SDLK_UNKNOWN, - /* 143 */ SDLK_UNKNOWN, - /* 144 */ SDLK_UNKNOWN, - /* 145 */ SDLK_UNKNOWN, - /* 146 */ SDLK_UNKNOWN, - /* 147 */ SDLK_UNKNOWN, - /* 148 */ SDLK_UNKNOWN, - /* 149 */ SDLK_UNKNOWN, - /* 150 */ SDLK_UNKNOWN, - /* 151 */ SDLK_UNKNOWN, - /* 152 */ SDLK_UNKNOWN, - /* 153 */ SDLK_ALTERASE, - /* 154 */ SDLK_SYSREQ, - /* 155 */ SDLK_CANCEL, - /* 156 */ SDLK_CLEAR, - /* 157 */ SDLK_PRIOR, - /* 158 */ SDLK_RETURN2, - /* 159 */ SDLK_SEPARATOR, - /* 160 */ SDLK_OUT, - /* 161 */ SDLK_OPER, - /* 162 */ SDLK_CLEARAGAIN, - /* 163 */ SDLK_CRSEL, - /* 164 */ SDLK_EXSEL, - /* 165 */ SDLK_UNKNOWN, - /* 166 */ SDLK_UNKNOWN, - /* 167 */ SDLK_UNKNOWN, - /* 168 */ SDLK_UNKNOWN, - /* 169 */ SDLK_UNKNOWN, - /* 170 */ SDLK_UNKNOWN, - /* 171 */ SDLK_UNKNOWN, - /* 172 */ SDLK_UNKNOWN, - /* 173 */ SDLK_UNKNOWN, - /* 174 */ SDLK_UNKNOWN, - /* 175 */ SDLK_UNKNOWN, - /* 176 */ SDLK_KP_00, - /* 177 */ SDLK_KP_000, - /* 178 */ SDLK_THOUSANDSSEPARATOR, - /* 179 */ SDLK_DECIMALSEPARATOR, - /* 180 */ SDLK_CURRENCYUNIT, - /* 181 */ SDLK_CURRENCYSUBUNIT, - /* 182 */ SDLK_KP_LEFTPAREN, - /* 183 */ SDLK_KP_RIGHTPAREN, - /* 184 */ SDLK_KP_LEFTBRACE, - /* 185 */ SDLK_KP_RIGHTBRACE, - /* 186 */ SDLK_KP_TAB, - /* 187 */ SDLK_KP_BACKSPACE, - /* 188 */ SDLK_KP_A, - /* 189 */ SDLK_KP_B, - /* 190 */ SDLK_KP_C, - /* 191 */ SDLK_KP_D, - /* 192 */ SDLK_KP_E, - /* 193 */ SDLK_KP_F, - /* 194 */ SDLK_KP_XOR, - /* 195 */ SDLK_KP_POWER, - /* 196 */ SDLK_KP_PERCENT, - /* 197 */ SDLK_KP_LESS, - /* 198 */ SDLK_KP_GREATER, - /* 199 */ SDLK_KP_AMPERSAND, - /* 200 */ SDLK_KP_DBLAMPERSAND, - /* 201 */ SDLK_KP_VERTICALBAR, - /* 202 */ SDLK_KP_DBLVERTICALBAR, - /* 203 */ SDLK_KP_COLON, - /* 204 */ SDLK_KP_HASH, - /* 205 */ SDLK_KP_SPACE, - /* 206 */ SDLK_KP_AT, - /* 207 */ SDLK_KP_EXCLAM, - /* 208 */ SDLK_KP_MEMSTORE, - /* 209 */ SDLK_KP_MEMRECALL, - /* 210 */ SDLK_KP_MEMCLEAR, - /* 211 */ SDLK_KP_MEMADD, - /* 212 */ SDLK_KP_MEMSUBTRACT, - /* 213 */ SDLK_KP_MEMMULTIPLY, - /* 214 */ SDLK_KP_MEMDIVIDE, - /* 215 */ SDLK_KP_PLUSMINUS, - /* 216 */ SDLK_KP_CLEAR, - /* 217 */ SDLK_KP_CLEARENTRY, - /* 218 */ SDLK_KP_BINARY, - /* 219 */ SDLK_KP_OCTAL, - /* 220 */ SDLK_KP_DECIMAL, - /* 221 */ SDLK_KP_HEXADECIMAL, - /* 222 */ SDLK_UNKNOWN, - /* 223 */ SDLK_UNKNOWN, - /* 224 */ SDLK_LCTRL, - /* 225 */ SDLK_LSHIFT, - /* 226 */ SDLK_LALT, - /* 227 */ SDLK_LGUI, - /* 228 */ SDLK_RCTRL, - /* 229 */ SDLK_RSHIFT, - /* 230 */ SDLK_RALT, - /* 231 */ SDLK_RGUI, - /* 232 */ SDLK_UNKNOWN, - /* 233 */ SDLK_UNKNOWN, - /* 234 */ SDLK_UNKNOWN, - /* 235 */ SDLK_UNKNOWN, - /* 236 */ SDLK_UNKNOWN, - /* 237 */ SDLK_UNKNOWN, - /* 238 */ SDLK_UNKNOWN, - /* 239 */ SDLK_UNKNOWN, - /* 240 */ SDLK_UNKNOWN, - /* 241 */ SDLK_UNKNOWN, - /* 242 */ SDLK_UNKNOWN, - /* 243 */ SDLK_UNKNOWN, - /* 244 */ SDLK_UNKNOWN, - /* 245 */ SDLK_UNKNOWN, - /* 246 */ SDLK_UNKNOWN, - /* 247 */ SDLK_UNKNOWN, - /* 248 */ SDLK_UNKNOWN, - /* 249 */ SDLK_UNKNOWN, - /* 250 */ SDLK_UNKNOWN, - /* 251 */ SDLK_UNKNOWN, - /* 252 */ SDLK_UNKNOWN, - /* 253 */ SDLK_UNKNOWN, - /* 254 */ SDLK_UNKNOWN, - /* 255 */ SDLK_UNKNOWN, - /* 256 */ SDLK_UNKNOWN, - /* 257 */ SDLK_MODE, - /* 258 */ SDLK_SLEEP, - /* 258 */ SDLK_WAKE, - /* 260 */ SDLK_CHANNEL_INCREMENT, - /* 261 */ SDLK_CHANNEL_DECREMENT, - /* 262 */ SDLK_MEDIA_PLAY, - /* 263 */ SDLK_MEDIA_PAUSE, - /* 264 */ SDLK_MEDIA_RECORD, - /* 265 */ SDLK_MEDIA_FAST_FORWARD, - /* 266 */ SDLK_MEDIA_REWIND, - /* 267 */ SDLK_MEDIA_NEXT_TRACK, - /* 268 */ SDLK_MEDIA_PREVIOUS_TRACK, - /* 269 */ SDLK_MEDIA_STOP, - /* 270 */ SDLK_MEDIA_EJECT, - /* 271 */ SDLK_MEDIA_PLAY_PAUSE, - /* 272 */ SDLK_MEDIA_SELECT, - /* 273 */ SDLK_AC_NEW, - /* 274 */ SDLK_AC_OPEN, - /* 275 */ SDLK_AC_CLOSE, - /* 276 */ SDLK_AC_EXIT, - /* 277 */ SDLK_AC_SAVE, - /* 278 */ SDLK_AC_PRINT, - /* 279 */ SDLK_AC_PROPERTIES, - /* 280 */ SDLK_AC_SEARCH, - /* 281 */ SDLK_AC_HOME, - /* 282 */ SDLK_AC_BACK, - /* 283 */ SDLK_AC_FORWARD, - /* 284 */ SDLK_AC_STOP, - /* 285 */ SDLK_AC_REFRESH, - /* 286 */ SDLK_AC_BOOKMARKS, - /* 287 */ SDLK_SOFTLEFT, - /* 288 */ SDLK_SOFTRIGHT, - /* 289 */ SDLK_CALL, - /* 290 */ SDLK_ENDCALL, -}; - -static const char *SDL_scancode_names[SDL_NUM_SCANCODES] = { - /* 0 */ NULL, - /* 1 */ NULL, - /* 2 */ NULL, - /* 3 */ NULL, - /* 4 */ "A", - /* 5 */ "B", - /* 6 */ "C", - /* 7 */ "D", - /* 8 */ "E", - /* 9 */ "F", - /* 10 */ "G", - /* 11 */ "H", - /* 12 */ "I", - /* 13 */ "J", - /* 14 */ "K", - /* 15 */ "L", - /* 16 */ "M", - /* 17 */ "N", - /* 18 */ "O", - /* 19 */ "P", - /* 20 */ "Q", - /* 21 */ "R", - /* 22 */ "S", - /* 23 */ "T", - /* 24 */ "U", - /* 25 */ "V", - /* 26 */ "W", - /* 27 */ "X", - /* 28 */ "Y", - /* 29 */ "Z", - /* 30 */ "1", - /* 31 */ "2", - /* 32 */ "3", - /* 33 */ "4", - /* 34 */ "5", - /* 35 */ "6", - /* 36 */ "7", - /* 37 */ "8", - /* 38 */ "9", - /* 39 */ "0", - /* 40 */ "Return", - /* 41 */ "Escape", - /* 42 */ "Backspace", - /* 43 */ "Tab", - /* 44 */ "Space", - /* 45 */ "-", - /* 46 */ "=", - /* 47 */ "[", - /* 48 */ "]", - /* 49 */ "\\", - /* 50 */ "#", - /* 51 */ ";", - /* 52 */ "'", - /* 53 */ "`", - /* 54 */ ",", - /* 55 */ ".", - /* 56 */ "/", - /* 57 */ "CapsLock", - /* 58 */ "F1", - /* 59 */ "F2", - /* 60 */ "F3", - /* 61 */ "F4", - /* 62 */ "F5", - /* 63 */ "F6", - /* 64 */ "F7", - /* 65 */ "F8", - /* 66 */ "F9", - /* 67 */ "F10", - /* 68 */ "F11", - /* 69 */ "F12", - /* 70 */ "PrintScreen", - /* 71 */ "ScrollLock", - /* 72 */ "Pause", - /* 73 */ "Insert", - /* 74 */ "Home", - /* 75 */ "PageUp", - /* 76 */ "Delete", - /* 77 */ "End", - /* 78 */ "PageDown", - /* 79 */ "Right", - /* 80 */ "Left", - /* 81 */ "Down", - /* 82 */ "Up", - /* 83 */ "Numlock", - /* 84 */ "Keypad /", - /* 85 */ "Keypad *", - /* 86 */ "Keypad -", - /* 87 */ "Keypad +", - /* 88 */ "Keypad Enter", - /* 89 */ "Keypad 1", - /* 90 */ "Keypad 2", - /* 91 */ "Keypad 3", - /* 92 */ "Keypad 4", - /* 93 */ "Keypad 5", - /* 94 */ "Keypad 6", - /* 95 */ "Keypad 7", - /* 96 */ "Keypad 8", - /* 97 */ "Keypad 9", - /* 98 */ "Keypad 0", - /* 99 */ "Keypad .", - /* 100 */ NULL, - /* 101 */ "Application", - /* 102 */ "Power", - /* 103 */ "Keypad =", - /* 104 */ "F13", - /* 105 */ "F14", - /* 106 */ "F15", - /* 107 */ "F16", - /* 108 */ "F17", - /* 109 */ "F18", - /* 110 */ "F19", - /* 111 */ "F20", - /* 112 */ "F21", - /* 113 */ "F22", - /* 114 */ "F23", - /* 115 */ "F24", - /* 116 */ "Execute", - /* 117 */ "Help", - /* 118 */ "Menu", - /* 119 */ "Select", - /* 120 */ "Stop", - /* 121 */ "Again", - /* 122 */ "Undo", - /* 123 */ "Cut", - /* 124 */ "Copy", - /* 125 */ "Paste", - /* 126 */ "Find", - /* 127 */ "Mute", - /* 128 */ "VolumeUp", - /* 129 */ "VolumeDown", - /* 130 */ NULL, - /* 131 */ NULL, - /* 132 */ NULL, - /* 133 */ "Keypad ,", - /* 134 */ "Keypad = (AS400)", - /* 135 */ NULL, - /* 136 */ NULL, - /* 137 */ NULL, - /* 138 */ NULL, - /* 139 */ NULL, - /* 140 */ NULL, - /* 141 */ NULL, - /* 142 */ NULL, - /* 143 */ NULL, - /* 144 */ NULL, - /* 145 */ NULL, - /* 146 */ NULL, - /* 147 */ NULL, - /* 148 */ NULL, - /* 149 */ NULL, - /* 150 */ NULL, - /* 151 */ NULL, - /* 152 */ NULL, - /* 153 */ "AltErase", - /* 154 */ "SysReq", - /* 155 */ "Cancel", - /* 156 */ "Clear", - /* 157 */ "Prior", - /* 158 */ "Return", - /* 159 */ "Separator", - /* 160 */ "Out", - /* 161 */ "Oper", - /* 162 */ "Clear / Again", - /* 163 */ "CrSel", - /* 164 */ "ExSel", - /* 165 */ NULL, - /* 166 */ NULL, - /* 167 */ NULL, - /* 168 */ NULL, - /* 169 */ NULL, - /* 170 */ NULL, - /* 171 */ NULL, - /* 172 */ NULL, - /* 173 */ NULL, - /* 174 */ NULL, - /* 175 */ NULL, - /* 176 */ "Keypad 00", - /* 177 */ "Keypad 000", - /* 178 */ "ThousandsSeparator", - /* 179 */ "DecimalSeparator", - /* 180 */ "CurrencyUnit", - /* 181 */ "CurrencySubUnit", - /* 182 */ "Keypad (", - /* 183 */ "Keypad )", - /* 184 */ "Keypad {", - /* 185 */ "Keypad }", - /* 186 */ "Keypad Tab", - /* 187 */ "Keypad Backspace", - /* 188 */ "Keypad A", - /* 189 */ "Keypad B", - /* 190 */ "Keypad C", - /* 191 */ "Keypad D", - /* 192 */ "Keypad E", - /* 193 */ "Keypad F", - /* 194 */ "Keypad XOR", - /* 195 */ "Keypad ^", - /* 196 */ "Keypad %", - /* 197 */ "Keypad <", - /* 198 */ "Keypad >", - /* 199 */ "Keypad &", - /* 200 */ "Keypad &&", - /* 201 */ "Keypad |", - /* 202 */ "Keypad ||", - /* 203 */ "Keypad :", - /* 204 */ "Keypad #", - /* 205 */ "Keypad Space", - /* 206 */ "Keypad @", - /* 207 */ "Keypad !", - /* 208 */ "Keypad MemStore", - /* 209 */ "Keypad MemRecall", - /* 210 */ "Keypad MemClear", - /* 211 */ "Keypad MemAdd", - /* 212 */ "Keypad MemSubtract", - /* 213 */ "Keypad MemMultiply", - /* 214 */ "Keypad MemDivide", - /* 215 */ "Keypad +/-", - /* 216 */ "Keypad Clear", - /* 217 */ "Keypad ClearEntry", - /* 218 */ "Keypad Binary", - /* 219 */ "Keypad Octal", - /* 220 */ "Keypad Decimal", - /* 221 */ "Keypad Hexadecimal", - /* 222 */ NULL, - /* 223 */ NULL, - /* 224 */ "Left Ctrl", - /* 225 */ "Left Shift", - /* 226 */ "Left Alt", - /* 227 */ "Left GUI", - /* 228 */ "Right Ctrl", - /* 229 */ "Right Shift", - /* 230 */ "Right Alt", - /* 231 */ "Right GUI", - /* 232 */ NULL, - /* 233 */ NULL, - /* 234 */ NULL, - /* 235 */ NULL, - /* 236 */ NULL, - /* 237 */ NULL, - /* 238 */ NULL, - /* 239 */ NULL, - /* 240 */ NULL, - /* 241 */ NULL, - /* 242 */ NULL, - /* 243 */ NULL, - /* 244 */ NULL, - /* 245 */ NULL, - /* 246 */ NULL, - /* 247 */ NULL, - /* 248 */ NULL, - /* 249 */ NULL, - /* 250 */ NULL, - /* 251 */ NULL, - /* 252 */ NULL, - /* 253 */ NULL, - /* 254 */ NULL, - /* 255 */ NULL, - /* 256 */ NULL, - /* 257 */ "ModeSwitch", - /* 258 */ "Sleep", - /* 259 */ "Wake", - /* 260 */ "ChannelUp", - /* 261 */ "ChannelDown", - /* 262 */ "MediaPlay", - /* 263 */ "MediaPause", - /* 264 */ "MediaRecord", - /* 265 */ "MediaFastForward", - /* 266 */ "MediaRewind", - /* 267 */ "MediaTrackNext", - /* 268 */ "MediaTrackPrevious", - /* 269 */ "MediaStop", - /* 270 */ "Eject", - /* 271 */ "MediaPlayPause", - /* 272 */ "MediaSelect", - /* 273 */ "AC New", - /* 274 */ "AC Open", - /* 275 */ "AC Close", - /* 276 */ "AC Exit", - /* 277 */ "AC Save", - /* 278 */ "AC Print", - /* 279 */ "AC Properties", - /* 280 */ "AC Search", - /* 281 */ "AC Home", - /* 282 */ "AC Back", - /* 283 */ "AC Forward", - /* 284 */ "AC Stop", - /* 285 */ "AC Refresh", - /* 286 */ "AC Bookmarks", - /* 287 */ "SoftLeft", - /* 288 */ "SoftRight", - /* 289 */ "Call", - /* 290 */ "EndCall", -}; - -/* Taken from SDL_iconv() */ -char *SDL_UCS4ToUTF8(Uint32 ch, char *dst) -{ - Uint8 *p = (Uint8 *)dst; - if (ch <= 0x7F) { - *p = (Uint8)ch; - ++dst; - } else if (ch <= 0x7FF) { - p[0] = 0xC0 | (Uint8)((ch >> 6) & 0x1F); - p[1] = 0x80 | (Uint8)(ch & 0x3F); - dst += 2; - } else if (ch <= 0xFFFF) { - p[0] = 0xE0 | (Uint8)((ch >> 12) & 0x0F); - p[1] = 0x80 | (Uint8)((ch >> 6) & 0x3F); - p[2] = 0x80 | (Uint8)(ch & 0x3F); - dst += 3; - } else { - p[0] = 0xF0 | (Uint8)((ch >> 18) & 0x07); - p[1] = 0x80 | (Uint8)((ch >> 12) & 0x3F); - p[2] = 0x80 | (Uint8)((ch >> 6) & 0x3F); - p[3] = 0x80 | (Uint8)(ch & 0x3F); - dst += 4; - } - return dst; -} - /* Public functions */ int SDL_InitKeyboard(void) { - /* Set the default keymap */ - SDL_SetKeymap(0, SDL_default_keymap, SDL_NUM_SCANCODES, SDL_FALSE); return 0; } @@ -811,73 +195,21 @@ void SDL_ResetKeyboard(void) } } -void SDL_GetDefaultKeymap(SDL_Keycode *keymap) -{ - SDL_memcpy(keymap, SDL_default_keymap, sizeof(SDL_default_keymap)); -} - -void SDL_SetKeymap(int start, const SDL_Keycode *keys, int length, SDL_bool send_event) +void SDL_SetKeymap(SDL_Keymap *keymap, SDL_bool send_event) { SDL_Keyboard *keyboard = &SDL_keyboard; - SDL_Scancode scancode; - SDL_Keycode normalized_keymap[SDL_NUM_SCANCODES]; - SDL_bool is_azerty = SDL_FALSE; - - if (start < 0 || start + length > SDL_NUM_SCANCODES) { - return; - } - if (start > 0) { - SDL_memcpy(&normalized_keymap[0], &keyboard->keymap[0], sizeof(*keys) * start); + if (keyboard->keymap) { + SDL_DestroyKeymap(keyboard->keymap); } - SDL_memcpy(&normalized_keymap[start], keys, sizeof(*keys) * length); - - if (start + length < SDL_NUM_SCANCODES) { - int offset = start + length; - SDL_memcpy(&normalized_keymap[offset], &keyboard->keymap[offset], sizeof(*keys) * (SDL_NUM_SCANCODES - offset)); - } - - /* On AZERTY layouts the number keys are technically symbols, but users (and games) - * always think of them and view them in UI as number keys, so remap them here. - */ - if (normalized_keymap[SDL_SCANCODE_0] < SDLK_0 || normalized_keymap[SDL_SCANCODE_0] > SDLK_9) { - is_azerty = SDL_TRUE; - for (scancode = SDL_SCANCODE_1; scancode <= SDL_SCANCODE_9; ++scancode) { - if (normalized_keymap[scancode] >= SDLK_0 && normalized_keymap[scancode] <= SDLK_9) { - /* There's a number on this row, it's not AZERTY */ - is_azerty = SDL_FALSE; - break; - } - } - } - if (is_azerty) { - normalized_keymap[SDL_SCANCODE_0] = SDLK_0; - for (scancode = SDL_SCANCODE_1; scancode <= SDL_SCANCODE_9; ++scancode) { - normalized_keymap[scancode] = SDLK_1 + (scancode - SDL_SCANCODE_1); - } - } - - /* If the mapping didn't really change, we're done here */ - if (!SDL_memcmp(&keyboard->keymap[start], &normalized_keymap[start], sizeof(*keys) * length)) { - return; - } - - SDL_memcpy(&keyboard->keymap[start], &normalized_keymap[start], sizeof(*keys) * length); + keyboard->keymap = keymap; if (send_event) { SDL_SendKeymapChangedEvent(); } } -void SDL_SetScancodeName(SDL_Scancode scancode, const char *name) -{ - if (scancode >= SDL_NUM_SCANCODES) { - return; - } - SDL_scancode_names[scancode] = name; -} - SDL_Window *SDL_GetKeyboardFocus(void) { SDL_Keyboard *keyboard = &SDL_keyboard; @@ -993,7 +325,7 @@ static int SDL_SendKeyboardKeyInternal(Uint64 timestamp, Uint32 flags, SDL_Keybo keyboard->keystate[scancode] = state; if (keycode == SDLK_UNKNOWN) { - keycode = keyboard->keymap[scancode]; + keycode = SDL_GetKeyFromScancode(scancode, SDL_KMOD_NONE /*keyboard->modstate*/); } } else if (keycode == SDLK_UNKNOWN && rawcode == 0) { @@ -1098,26 +430,22 @@ static int SDL_SendKeyboardKeyInternal(Uint64 timestamp, Uint32 flags, SDL_Keybo int SDL_SendKeyboardUnicodeKey(Uint64 timestamp, Uint32 ch) { - SDL_Scancode code = SDL_SCANCODE_UNKNOWN; - uint16_t mod = 0; + SDL_Keymod modstate = SDL_KMOD_NONE; + SDL_Scancode scancode = SDL_GetDefaultScancodeFromKey(ch, &modstate); - if (ch < SDL_arraysize(SDL_ASCIIKeyInfoTable)) { - code = SDL_ASCIIKeyInfoTable[ch].code; - mod = SDL_ASCIIKeyInfoTable[ch].mod; - } - if (mod & SDL_KMOD_SHIFT) { + if (modstate & SDL_KMOD_SHIFT) { /* If the character uses shift, press shift down */ - SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_GLOBAL_KEYBOARD_ID, 0, SDL_SCANCODE_LSHIFT, SDLK_UNKNOWN, SDL_PRESSED); + SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_GLOBAL_KEYBOARD_ID, 0, SDL_SCANCODE_LSHIFT, SDLK_LSHIFT, SDL_PRESSED); } /* Send a keydown and keyup for the character */ - SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_GLOBAL_KEYBOARD_ID, 0, code, SDLK_UNKNOWN, SDL_PRESSED); - SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_GLOBAL_KEYBOARD_ID, 0, code, SDLK_UNKNOWN, SDL_RELEASED); + SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_GLOBAL_KEYBOARD_ID, 0, scancode, ch, SDL_PRESSED); + SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_GLOBAL_KEYBOARD_ID, 0, scancode, ch, SDL_RELEASED); - if (mod & SDL_KMOD_SHIFT) { + if (modstate & SDL_KMOD_SHIFT) { /* If the character uses shift, release shift */ - SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_GLOBAL_KEYBOARD_ID, 0, SDL_SCANCODE_LSHIFT, SDLK_UNKNOWN, SDL_RELEASED); + SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_GLOBAL_KEYBOARD_ID, 0, SDL_SCANCODE_LSHIFT, SDLK_LSHIFT, SDL_RELEASED); } return 0; } @@ -1256,6 +584,11 @@ void SDL_QuitKeyboard(void) } SDL_free(SDL_keyboards); SDL_keyboards = NULL; + + if (SDL_keyboard.keymap) { + SDL_DestroyKeymap(SDL_keyboard.keymap); + SDL_keyboard.keymap = NULL; + } } const Uint8 *SDL_GetKeyboardState(int *numkeys) @@ -1293,165 +626,13 @@ void SDL_ToggleModState(const SDL_Keymod modstate, const SDL_bool toggle) } } -SDL_Keycode SDL_GetKeyFromScancode(SDL_Scancode scancode) -{ - SDL_Keyboard *keyboard = &SDL_keyboard; - - if (((int)scancode) < SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) { - SDL_InvalidParamError("scancode"); - return 0; - } - - return keyboard->keymap[scancode]; -} - -SDL_Keycode SDL_GetDefaultKeyFromScancode(SDL_Scancode scancode) -{ - if (((int)scancode) < SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) { - SDL_InvalidParamError("scancode"); - return 0; - } - - return SDL_default_keymap[scancode]; -} - -SDL_Scancode SDL_GetScancodeFromKey(SDL_Keycode key) +SDL_Keycode SDL_GetKeyFromScancode(SDL_Scancode scancode, SDL_Keymod modstate) { - SDL_Keyboard *keyboard = &SDL_keyboard; - SDL_Scancode scancode; - - for (scancode = SDL_SCANCODE_UNKNOWN; scancode < SDL_NUM_SCANCODES; - ++scancode) { - if (keyboard->keymap[scancode] == key) { - return scancode; - } - } - return SDL_SCANCODE_UNKNOWN; + return SDL_GetKeymapKeycode(SDL_keyboard.keymap, scancode, modstate); } -// these are static memory, so we don't use SDL_FreeLater on them. -const char *SDL_GetScancodeName(SDL_Scancode scancode) +SDL_Scancode SDL_GetScancodeFromKey(SDL_Keycode key, SDL_Keymod *modstate) { - const char *name; - if (((int)scancode) < SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) { - SDL_InvalidParamError("scancode"); - return ""; - } - - name = SDL_scancode_names[scancode]; - if (name) { - return name; - } - - return ""; + return SDL_GetKeymapScancode(SDL_keyboard.keymap, key, modstate); } -SDL_Scancode SDL_GetScancodeFromName(const char *name) -{ - int i; - - if (!name || !*name) { - SDL_InvalidParamError("name"); - return SDL_SCANCODE_UNKNOWN; - } - - for (i = 0; i < SDL_arraysize(SDL_scancode_names); ++i) { - if (!SDL_scancode_names[i]) { - continue; - } - if (SDL_strcasecmp(name, SDL_scancode_names[i]) == 0) { - return (SDL_Scancode)i; - } - } - - SDL_InvalidParamError("name"); - return SDL_SCANCODE_UNKNOWN; -} - -const char *SDL_GetKeyName(SDL_Keycode key) -{ - char name[8]; - char *end; - - if (key & SDLK_SCANCODE_MASK) { - return SDL_GetScancodeName((SDL_Scancode)(key & ~SDLK_SCANCODE_MASK)); - } - - switch (key) { - case SDLK_RETURN: - return SDL_GetScancodeName(SDL_SCANCODE_RETURN); - case SDLK_ESCAPE: - return SDL_GetScancodeName(SDL_SCANCODE_ESCAPE); - case SDLK_BACKSPACE: - return SDL_GetScancodeName(SDL_SCANCODE_BACKSPACE); - case SDLK_TAB: - return SDL_GetScancodeName(SDL_SCANCODE_TAB); - case SDLK_SPACE: - return SDL_GetScancodeName(SDL_SCANCODE_SPACE); - case SDLK_DELETE: - return SDL_GetScancodeName(SDL_SCANCODE_DELETE); - default: - /* Unaccented letter keys on latin keyboards are normally - labeled in upper case (and probably on others like Greek or - Cyrillic too, so if you happen to know for sure, please - adapt this). */ - if (key >= 'a' && key <= 'z') { - key -= 32; - } - - end = SDL_UCS4ToUTF8((Uint32)key, name); - *end = '\0'; - return SDL_FreeLater(SDL_strdup(name)); - } -} - -SDL_Keycode SDL_GetKeyFromName(const char *name) -{ - SDL_Keycode key; - - /* Check input */ - if (!name) { - return SDLK_UNKNOWN; - } - - /* If it's a single UTF-8 character, then that's the keycode itself */ - key = *(const unsigned char *)name; - if (key >= 0xF0) { - if (SDL_strlen(name) == 4) { - int i = 0; - key = (Uint16)(name[i] & 0x07) << 18; - key |= (Uint16)(name[++i] & 0x3F) << 12; - key |= (Uint16)(name[++i] & 0x3F) << 6; - key |= (Uint16)(name[++i] & 0x3F); - return key; - } - return SDLK_UNKNOWN; - } else if (key >= 0xE0) { - if (SDL_strlen(name) == 3) { - int i = 0; - key = (Uint16)(name[i] & 0x0F) << 12; - key |= (Uint16)(name[++i] & 0x3F) << 6; - key |= (Uint16)(name[++i] & 0x3F); - return key; - } - return SDLK_UNKNOWN; - } else if (key >= 0xC0) { - if (SDL_strlen(name) == 2) { - int i = 0; - key = (Uint16)(name[i] & 0x1F) << 6; - key |= (Uint16)(name[++i] & 0x3F); - return key; - } - return SDLK_UNKNOWN; - } else { - if (SDL_strlen(name) == 1) { - if (key >= 'A' && key <= 'Z') { - key += 32; - } - return key; - } - - /* Get the scancode for this name, and the associated keycode */ - return SDL_default_keymap[SDL_GetScancodeFromName(name)]; - } -} diff --git a/src/events/SDL_keyboard_c.h b/src/events/SDL_keyboard_c.h index 3233b1b33a45e..df43168329f4f 100644 --- a/src/events/SDL_keyboard_c.h +++ b/src/events/SDL_keyboard_c.h @@ -23,6 +23,8 @@ #ifndef SDL_keyboard_c_h_ #define SDL_keyboard_c_h_ +#include "SDL_keymap_c.h" + /* Keyboard events not associated with a specific input device */ #define SDL_GLOBAL_KEYBOARD_ID 0 @@ -41,20 +43,8 @@ extern void SDL_AddKeyboard(SDL_KeyboardID keyboardID, const char *name, SDL_boo /* A keyboard has been removed from the system */ extern void SDL_RemoveKeyboard(SDL_KeyboardID keyboardID, SDL_bool send_event); -/* Get the default keymap */ -extern void SDL_GetDefaultKeymap(SDL_Keycode *keymap); - -/* Get the default key code for a scancode */ -extern SDL_Keycode SDL_GetDefaultKeyFromScancode(SDL_Scancode scancode); - /* Set the mapping of scancode to key codes */ -extern void SDL_SetKeymap(int start, const SDL_Keycode *keys, int length, SDL_bool send_event); - -/* Set a platform-dependent key name, overriding the default platform-agnostic - name. Encoded as UTF-8. The string is not copied, thus the pointer given to - this function must stay valid forever (or at least until the call to - VideoQuit()). */ -extern void SDL_SetScancodeName(SDL_Scancode scancode, const char *name); +extern void SDL_SetKeymap(SDL_Keymap *keymap, SDL_bool send_event); /* Set the keyboard focus window */ extern int SDL_SetKeyboardFocus(SDL_Window *window); @@ -91,9 +81,6 @@ extern int SDL_SendEditingText(const char *text, int start, int length); /* Shutdown the keyboard subsystem */ extern void SDL_QuitKeyboard(void); -/* Convert to UTF-8 */ -extern char *SDL_UCS4ToUTF8(Uint32 ch, char *dst); - /* Toggle on or off pieces of the keyboard mod state. */ extern void SDL_ToggleModState(const SDL_Keymod modstate, const SDL_bool toggle); diff --git a/src/events/SDL_keymap.c b/src/events/SDL_keymap.c new file mode 100644 index 0000000000000..03f5455cb3083 --- /dev/null +++ b/src/events/SDL_keymap.c @@ -0,0 +1,711 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_internal.h" + +#include "SDL_keymap_c.h" +#include "../SDL_hashtable.h" + +struct SDL_Keymap +{ + SDL_HashTable *scancode_to_keycode; + SDL_HashTable *keycode_to_scancode; +}; + +SDL_Keymap *SDL_CreateKeymap(void) +{ + SDL_Keymap *keymap = (SDL_Keymap *)SDL_malloc(sizeof(*keymap)); + if (!keymap) { + return NULL; + } + + keymap->scancode_to_keycode = SDL_CreateHashTable(NULL, 64, SDL_HashID, SDL_KeyMatchID, NULL, SDL_FALSE); + keymap->keycode_to_scancode = SDL_CreateHashTable(NULL, 64, SDL_HashID, SDL_KeyMatchID, NULL, SDL_FALSE); + if (!keymap->scancode_to_keycode || !keymap->keycode_to_scancode) { + SDL_DestroyKeymap(keymap); + return NULL; + } + return keymap; +} + +static SDL_Keymod NormalizeModifierStateForKeymap(SDL_Keymod modstate) +{ + // The modifiers that affect the keymap are: SHIFT, CAPS, ALT, and MODE + modstate &= (SDL_KMOD_SHIFT | SDL_KMOD_CAPS | SDL_KMOD_ALT | SDL_KMOD_MODE); + + // If either right or left Shift are set, set both in the output + if (modstate & SDL_KMOD_SHIFT) { + modstate |= SDL_KMOD_SHIFT; + } + + // If either right or left Alt are set, set both in the output + if (modstate & SDL_KMOD_ALT) { + modstate |= SDL_KMOD_ALT; + } + + return modstate; +} + +void SDL_SetKeymapEntry(SDL_Keymap *keymap, SDL_Scancode scancode, SDL_Keymod modstate, SDL_Keycode keycode) +{ + if (!keymap) { + return; + } + + if (keycode == SDL_GetDefaultKeyFromScancode(scancode, modstate)) { + return; + } + + Uint32 key = ((Uint32)NormalizeModifierStateForKeymap(modstate) << 16) | scancode; + SDL_InsertIntoHashTable(keymap->scancode_to_keycode, (void *)(uintptr_t)key, (void *)(uintptr_t)keycode); + SDL_InsertIntoHashTable(keymap->keycode_to_scancode, (void *)(uintptr_t)keycode, (void *)(uintptr_t)key); +} + +SDL_Keycode SDL_GetKeymapKeycode(SDL_Keymap *keymap, SDL_Scancode scancode, SDL_Keymod modstate) +{ + SDL_Keycode keycode; + + 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); + } + return keycode; +} + +SDL_Scancode SDL_GetKeymapScancode(SDL_Keymap *keymap, SDL_Keycode keycode, SDL_Keymod *modstate) +{ + SDL_Scancode scancode; + + const void *value; + if (keymap && SDL_FindInHashTable(keymap->keycode_to_scancode, (void *)(uintptr_t)keycode, &value)) { + scancode = (SDL_Scancode)((uintptr_t)value & 0xFFFF); + if (modstate) { + *modstate = (SDL_Keymod)((uintptr_t)value >> 16); + } + } else { + scancode = SDL_GetDefaultScancodeFromKey(keycode, modstate); + } + return scancode; +} + +void SDL_ResetKeymap(SDL_Keymap *keymap) +{ + if (keymap) { + SDL_EmptyHashTable(keymap->scancode_to_keycode); + SDL_EmptyHashTable(keymap->keycode_to_scancode); + } +} + +void SDL_DestroyKeymap(SDL_Keymap *keymap) +{ + if (keymap) { + SDL_DestroyHashTable(keymap->scancode_to_keycode); + SDL_DestroyHashTable(keymap->keycode_to_scancode); + SDL_free(keymap); + } +} + +static const SDL_Keycode normal_default_symbols[] = { + SDLK_1, + SDLK_2, + SDLK_3, + SDLK_4, + SDLK_5, + SDLK_6, + SDLK_7, + SDLK_8, + SDLK_9, + SDLK_0, + SDLK_RETURN, + SDLK_ESCAPE, + SDLK_BACKSPACE, + SDLK_TAB, + SDLK_SPACE, + SDLK_MINUS, + SDLK_EQUALS, + SDLK_LEFTBRACKET, + SDLK_RIGHTBRACKET, + SDLK_BACKSLASH, + SDLK_HASH, + SDLK_SEMICOLON, + SDLK_APOSTROPHE, + SDLK_GRAVE, + SDLK_COMMA, + SDLK_PERIOD, + SDLK_SLASH, +}; + +static const SDL_Keycode shifted_default_symbols[] = { + SDLK_EXCLAIM, + SDLK_AT, + SDLK_HASH, + SDLK_DOLLAR, + SDLK_PERCENT, + SDLK_CARET, + SDLK_AMPERSAND, + SDLK_ASTERISK, + SDLK_LEFTPAREN, + SDLK_RIGHTPAREN, + SDLK_RETURN, + SDLK_ESCAPE, + SDLK_BACKSPACE, + SDLK_TAB, + SDLK_SPACE, + SDLK_UNDERSCORE, + SDLK_PLUS, + SDLK_LEFTBRACE, + SDLK_RIGHTBRACE, + SDLK_PIPE, + SDLK_HASH, + SDLK_COLON, + SDLK_DBLAPOSTROPHE, + SDLK_TILDE, + SDLK_LESS, + SDLK_GREATER, + SDLK_QUESTION +}; + +SDL_Keycode SDL_GetDefaultKeyFromScancode(SDL_Scancode scancode, SDL_Keymod modstate) +{ + if (modstate & SDL_KMOD_MODE) { + return SDLK_UNKNOWN; + } + + if (scancode < SDL_SCANCODE_A) { + return SDLK_UNKNOWN; + } + + if (scancode < SDL_SCANCODE_1) { + SDL_bool shifted = (modstate & SDL_KMOD_SHIFT) ? SDL_TRUE : SDL_FALSE; +#ifdef SDL_PLATFORM_APPLE + // Apple maps to upper case for either shift or capslock inclusive + if (modstate & SDL_KMOD_CAPS) { + shifted = SDL_TRUE; + } +#else + if (modstate & SDL_KMOD_CAPS) { + shifted = !shifted; + } +#endif + if (!shifted) { + return (SDL_Keycode)('a' + scancode - SDL_SCANCODE_A); + } else { + return (SDL_Keycode)('A' + scancode - SDL_SCANCODE_A); + } + } + + if (scancode < SDL_SCANCODE_CAPSLOCK) { + SDL_bool shifted = (modstate & SDL_KMOD_SHIFT) ? SDL_TRUE : SDL_FALSE; + + if (!shifted) { + return normal_default_symbols[scancode - SDL_SCANCODE_1]; + } else { + return shifted_default_symbols[scancode - SDL_SCANCODE_1]; + } + } + + if (scancode == SDL_SCANCODE_DELETE) { + return SDLK_DELETE; + } + + return SDL_SCANCODE_TO_KEYCODE(scancode); +} + +SDL_Scancode SDL_GetDefaultScancodeFromKey(SDL_Keycode key, SDL_Keymod *modstate) +{ + if (modstate) { + *modstate = SDL_KMOD_NONE; + } + + if (key == SDLK_UNKNOWN) { + return SDL_SCANCODE_UNKNOWN; + } + + if (key & SDLK_SCANCODE_MASK) { + return (SDL_Scancode)(key & ~SDLK_SCANCODE_MASK); + } + + if (key >= SDLK_a && key <= SDLK_z) { + return (SDL_Scancode)(SDL_SCANCODE_A + key - SDLK_a); + } + + if (key >= SDLK_Z && key <= SDLK_Z) { + if (modstate) { + *modstate = SDL_KMOD_SHIFT; + } + return (SDL_Scancode)(SDL_SCANCODE_A + key - SDLK_Z); + } + + for (int i = 0; i < SDL_arraysize(normal_default_symbols); ++i) { + if (key == normal_default_symbols[i]) { + return(SDL_Scancode)(SDL_SCANCODE_1 + i); + } + } + + for (int i = 0; i < SDL_arraysize(shifted_default_symbols); ++i) { + if (key == shifted_default_symbols[i]) { + if (modstate) { + *modstate = SDL_KMOD_SHIFT; + } + return(SDL_Scancode)(SDL_SCANCODE_1 + i); + } + } + + if (key == SDLK_DELETE) { + return SDL_SCANCODE_DELETE; + } + + return SDL_SCANCODE_UNKNOWN; +} + +static const char *SDL_scancode_names[SDL_NUM_SCANCODES] = +{ + /* 0 */ NULL, + /* 1 */ NULL, + /* 2 */ NULL, + /* 3 */ NULL, + /* 4 */ "A", + /* 5 */ "B", + /* 6 */ "C", + /* 7 */ "D", + /* 8 */ "E", + /* 9 */ "F", + /* 10 */ "G", + /* 11 */ "H", + /* 12 */ "I", + /* 13 */ "J", + /* 14 */ "K", + /* 15 */ "L", + /* 16 */ "M", + /* 17 */ "N", + /* 18 */ "O", + /* 19 */ "P", + /* 20 */ "Q", + /* 21 */ "R", + /* 22 */ "S", + /* 23 */ "T", + /* 24 */ "U", + /* 25 */ "V", + /* 26 */ "W", + /* 27 */ "X", + /* 28 */ "Y", + /* 29 */ "Z", + /* 30 */ "1", + /* 31 */ "2", + /* 32 */ "3", + /* 33 */ "4", + /* 34 */ "5", + /* 35 */ "6", + /* 36 */ "7", + /* 37 */ "8", + /* 38 */ "9", + /* 39 */ "0", + /* 40 */ "Return", + /* 41 */ "Escape", + /* 42 */ "Backspace", + /* 43 */ "Tab", + /* 44 */ "Space", + /* 45 */ "-", + /* 46 */ "=", + /* 47 */ "[", + /* 48 */ "]", + /* 49 */ "\\", + /* 50 */ "#", + /* 51 */ ";", + /* 52 */ "'", + /* 53 */ "`", + /* 54 */ ",", + /* 55 */ ".", + /* 56 */ "/", + /* 57 */ "CapsLock", + /* 58 */ "F1", + /* 59 */ "F2", + /* 60 */ "F3", + /* 61 */ "F4", + /* 62 */ "F5", + /* 63 */ "F6", + /* 64 */ "F7", + /* 65 */ "F8", + /* 66 */ "F9", + /* 67 */ "F10", + /* 68 */ "F11", + /* 69 */ "F12", + /* 70 */ "PrintScreen", + /* 71 */ "ScrollLock", + /* 72 */ "Pause", + /* 73 */ "Insert", + /* 74 */ "Home", + /* 75 */ "PageUp", + /* 76 */ "Delete", + /* 77 */ "End", + /* 78 */ "PageDown", + /* 79 */ "Right", + /* 80 */ "Left", + /* 81 */ "Down", + /* 82 */ "Up", + /* 83 */ "Numlock", + /* 84 */ "Keypad /", + /* 85 */ "Keypad *", + /* 86 */ "Keypad -", + /* 87 */ "Keypad +", + /* 88 */ "Keypad Enter", + /* 89 */ "Keypad 1", + /* 90 */ "Keypad 2", + /* 91 */ "Keypad 3", + /* 92 */ "Keypad 4", + /* 93 */ "Keypad 5", + /* 94 */ "Keypad 6", + /* 95 */ "Keypad 7", + /* 96 */ "Keypad 8", + /* 97 */ "Keypad 9", + /* 98 */ "Keypad 0", + /* 99 */ "Keypad .", + /* 100 */ NULL, + /* 101 */ "Application", + /* 102 */ "Power", + /* 103 */ "Keypad =", + /* 104 */ "F13", + /* 105 */ "F14", + /* 106 */ "F15", + /* 107 */ "F16", + /* 108 */ "F17", + /* 109 */ "F18", + /* 110 */ "F19", + /* 111 */ "F20", + /* 112 */ "F21", + /* 113 */ "F22", + /* 114 */ "F23", + /* 115 */ "F24", + /* 116 */ "Execute", + /* 117 */ "Help", + /* 118 */ "Menu", + /* 119 */ "Select", + /* 120 */ "Stop", + /* 121 */ "Again", + /* 122 */ "Undo", + /* 123 */ "Cut", + /* 124 */ "Copy", + /* 125 */ "Paste", + /* 126 */ "Find", + /* 127 */ "Mute", + /* 128 */ "VolumeUp", + /* 129 */ "VolumeDown", + /* 130 */ NULL, + /* 131 */ NULL, + /* 132 */ NULL, + /* 133 */ "Keypad ,", + /* 134 */ "Keypad = (AS400)", + /* 135 */ NULL, + /* 136 */ NULL, + /* 137 */ NULL, + /* 138 */ NULL, + /* 139 */ NULL, + /* 140 */ NULL, + /* 141 */ NULL, + /* 142 */ NULL, + /* 143 */ NULL, + /* 144 */ NULL, + /* 145 */ NULL, + /* 146 */ NULL, + /* 147 */ NULL, + /* 148 */ NULL, + /* 149 */ NULL, + /* 150 */ NULL, + /* 151 */ NULL, + /* 152 */ NULL, + /* 153 */ "AltErase", + /* 154 */ "SysReq", + /* 155 */ "Cancel", + /* 156 */ "Clear", + /* 157 */ "Prior", + /* 158 */ "Return", + /* 159 */ "Separator", + /* 160 */ "Out", + /* 161 */ "Oper", + /* 162 */ "Clear / Again", + /* 163 */ "CrSel", + /* 164 */ "ExSel", + /* 165 */ NULL, + /* 166 */ NULL, + /* 167 */ NULL, + /* 168 */ NULL, + /* 169 */ NULL, + /* 170 */ NULL, + /* 171 */ NULL, + /* 172 */ NULL, + /* 173 */ NULL, + /* 174 */ NULL, + /* 175 */ NULL, + /* 176 */ "Keypad 00", + /* 177 */ "Keypad 000", + /* 178 */ "ThousandsSeparator", + /* 179 */ "DecimalSeparator", + /* 180 */ "CurrencyUnit", + /* 181 */ "CurrencySubUnit", + /* 182 */ "Keypad (", + /* 183 */ "Keypad )", + /* 184 */ "Keypad {", + /* 185 */ "Keypad }", + /* 186 */ "Keypad Tab", + /* 187 */ "Keypad Backspace", + /* 188 */ "Keypad A", + /* 189 */ "Keypad B", + /* 190 */ "Keypad C", + /* 191 */ "Keypad D", + /* 192 */ "Keypad E", + /* 193 */ "Keypad F", + /* 194 */ "Keypad XOR", + /* 195 */ "Keypad ^", + /* 196 */ "Keypad %", + /* 197 */ "Keypad <", + /* 198 */ "Keypad >", + /* 199 */ "Keypad &", + /* 200 */ "Keypad &&", + /* 201 */ "Keypad |", + /* 202 */ "Keypad ||", + /* 203 */ "Keypad :", + /* 204 */ "Keypad #", + /* 205 */ "Keypad Space", + /* 206 */ "Keypad @", + /* 207 */ "Keypad !", + /* 208 */ "Keypad MemStore", + /* 209 */ "Keypad MemRecall", + /* 210 */ "Keypad MemClear", + /* 211 */ "Keypad MemAdd", + /* 212 */ "Keypad MemSubtract", + /* 213 */ "Keypad MemMultiply", + /* 214 */ "Keypad MemDivide", + /* 215 */ "Keypad +/-", + /* 216 */ "Keypad Clear", + /* 217 */ "Keypad ClearEntry", + /* 218 */ "Keypad Binary", + /* 219 */ "Keypad Octal", + /* 220 */ "Keypad Decimal", + /* 221 */ "Keypad Hexadecimal", + /* 222 */ NULL, + /* 223 */ NULL, + /* 224 */ "Left Ctrl", + /* 225 */ "Left Shift", + /* 226 */ "Left Alt", + /* 227 */ "Left GUI", + /* 228 */ "Right Ctrl", + /* 229 */ "Right Shift", + /* 230 */ "Right Alt", + /* 231 */ "Right GUI", + /* 232 */ NULL, + /* 233 */ NULL, + /* 234 */ NULL, + /* 235 */ NULL, + /* 236 */ NULL, + /* 237 */ NULL, + /* 238 */ NULL, + /* 239 */ NULL, + /* 240 */ NULL, + /* 241 */ NULL, + /* 242 */ NULL, + /* 243 */ NULL, + /* 244 */ NULL, + /* 245 */ NULL, + /* 246 */ NULL, + /* 247 */ NULL, + /* 248 */ NULL, + /* 249 */ NULL, + /* 250 */ NULL, + /* 251 */ NULL, + /* 252 */ NULL, + /* 253 */ NULL, + /* 254 */ NULL, + /* 255 */ NULL, + /* 256 */ NULL, + /* 257 */ "ModeSwitch", + /* 258 */ "Sleep", + /* 259 */ "Wake", + /* 260 */ "ChannelUp", + /* 261 */ "ChannelDown", + /* 262 */ "MediaPlay", + /* 263 */ "MediaPause", + /* 264 */ "MediaRecord", + /* 265 */ "MediaFastForward", + /* 266 */ "MediaRewind", + /* 267 */ "MediaTrackNext", + /* 268 */ "MediaTrackPrevious", + /* 269 */ "MediaStop", + /* 270 */ "Eject", + /* 271 */ "MediaPlayPause", + /* 272 */ "MediaSelect", + /* 273 */ "AC New", + /* 274 */ "AC Open", + /* 275 */ "AC Close", + /* 276 */ "AC Exit", + /* 277 */ "AC Save", + /* 278 */ "AC Print", + /* 279 */ "AC Properties", + /* 280 */ "AC Search", + /* 281 */ "AC Home", + /* 282 */ "AC Back", + /* 283 */ "AC Forward", + /* 284 */ "AC Stop", + /* 285 */ "AC Refresh", + /* 286 */ "AC Bookmarks", + /* 287 */ "SoftLeft", + /* 288 */ "SoftRight", + /* 289 */ "Call", + /* 290 */ "EndCall", +}; + +int SDL_SetScancodeName(SDL_Scancode scancode, const char *name) +{ + if (((int)scancode) < SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) { + return SDL_InvalidParamError("scancode"); + } + + SDL_scancode_names[scancode] = name; + return 0; +} + +// these are static memory, so we don't use SDL_FreeLater on them. +const char *SDL_GetScancodeName(SDL_Scancode scancode) +{ + const char *name; + if (((int)scancode) < SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) { + SDL_InvalidParamError("scancode"); + return ""; + } + + name = SDL_scancode_names[scancode]; + if (name) { + return name; + } + + return ""; +} + +SDL_Scancode SDL_GetScancodeFromName(const char *name) +{ + int i; + + if (!name || !*name) { + SDL_InvalidParamError("name"); + return SDL_SCANCODE_UNKNOWN; + } + + for (i = 0; i < SDL_arraysize(SDL_scancode_names); ++i) { + if (!SDL_scancode_names[i]) { + continue; + } + if (SDL_strcasecmp(name, SDL_scancode_names[i]) == 0) { + return (SDL_Scancode)i; + } + } + + SDL_InvalidParamError("name"); + return SDL_SCANCODE_UNKNOWN; +} + +const char *SDL_GetKeyName(SDL_Keycode key) +{ + char name[8]; + char *end; + + if (key & SDLK_SCANCODE_MASK) { + return SDL_GetScancodeName((SDL_Scancode)(key & ~SDLK_SCANCODE_MASK)); + } + + switch (key) { + case SDLK_RETURN: + return SDL_GetScancodeName(SDL_SCANCODE_RETURN); + case SDLK_ESCAPE: + return SDL_GetScancodeName(SDL_SCANCODE_ESCAPE); + case SDLK_BACKSPACE: + return SDL_GetScancodeName(SDL_SCANCODE_BACKSPACE); + case SDLK_TAB: + return SDL_GetScancodeName(SDL_SCANCODE_TAB); + case SDLK_SPACE: + return SDL_GetScancodeName(SDL_SCANCODE_SPACE); + case SDLK_DELETE: + return SDL_GetScancodeName(SDL_SCANCODE_DELETE); + default: + /* Unaccented letter keys on latin keyboards are normally + labeled in upper case (and probably on others like Greek or + Cyrillic too, so if you happen to know for sure, please + adapt this). */ + if (key >= 'a' && key <= 'z') { + key -= 32; + } + + end = SDL_UCS4ToUTF8(key, name); + *end = '\0'; + return SDL_FreeLater(SDL_strdup(name)); + } +} + +SDL_Keycode SDL_GetKeyFromName(const char *name) +{ + SDL_Keycode key; + + /* Check input */ + if (!name) { + return SDLK_UNKNOWN; + } + + /* If it's a single UTF-8 character, then that's the keycode itself */ + key = *(const unsigned char *)name; + if (key >= 0xF0) { + if (SDL_strlen(name) == 4) { + int i = 0; + key = (Uint16)(name[i] & 0x07) << 18; + key |= (Uint16)(name[++i] & 0x3F) << 12; + key |= (Uint16)(name[++i] & 0x3F) << 6; + key |= (Uint16)(name[++i] & 0x3F); + return key; + } + return SDLK_UNKNOWN; + } else if (key >= 0xE0) { + if (SDL_strlen(name) == 3) { + int i = 0; + key = (Uint16)(name[i] & 0x0F) << 12; + key |= (Uint16)(name[++i] & 0x3F) << 6; + key |= (Uint16)(name[++i] & 0x3F); + return key; + } + return SDLK_UNKNOWN; + } else if (key >= 0xC0) { + if (SDL_strlen(name) == 2) { + int i = 0; + key = (Uint16)(name[i] & 0x1F) << 6; + key |= (Uint16)(name[++i] & 0x3F); + return key; + } + return SDLK_UNKNOWN; + } else { + if (SDL_strlen(name) == 1) { + if (key >= 'A' && key <= 'Z') { + key += 32; + } + return key; + } + + /* Get the scancode for this name, and the associated keycode */ + return SDL_GetKeyFromScancode(SDL_GetScancodeFromName(name), SDL_KMOD_NONE); + } +} diff --git a/src/events/SDL_keymap_c.h b/src/events/SDL_keymap_c.h new file mode 100644 index 0000000000000..93128a6300c23 --- /dev/null +++ b/src/events/SDL_keymap_c.h @@ -0,0 +1,37 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_internal.h" + +#ifndef SDL_keymap_c_h_ +#define SDL_keymap_c_h_ + +#include "../SDL_hashtable.h" + +typedef struct SDL_Keymap SDL_Keymap; + +SDL_Keymap *SDL_CreateKeymap(void); +void SDL_SetKeymapEntry(SDL_Keymap *keymap, SDL_Scancode scancode, SDL_Keymod modstate, SDL_Keycode keycode); +SDL_Keycode SDL_GetKeymapKeycode(SDL_Keymap *keymap, SDL_Scancode scancode, SDL_Keymod modstate); +SDL_Scancode SDL_GetKeymapScancode(SDL_Keymap *keymap, SDL_Keycode keycode, SDL_Keymod *modstate); +void SDL_ResetKeymap(SDL_Keymap *keymap); +void SDL_DestroyKeymap(SDL_Keymap *keymap); + +#endif /* SDL_keymap_c_h_ */ diff --git a/src/events/scancodes_ascii.h b/src/events/scancodes_ascii.h deleted file mode 100644 index ee49ab8813532..0000000000000 --- a/src/events/scancodes_ascii.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -/* - This file is used to convert between characters passed in from an ASCII - virtual keyboard in US layout and tuples of SDL_Scancode and SDL_keymods. - - For example ASCIIKeyInfoTable['a'] would give you the scan code and keymod - for lower case a. -*/ - -typedef struct -{ - SDL_Scancode code; - uint16_t mod; -} ASCIIKeyInfo; - -static ASCIIKeyInfo SDL_ASCIIKeyInfoTable[] = { - /* 0 */ { SDL_SCANCODE_UNKNOWN, 0 }, - /* 1 */ { SDL_SCANCODE_UNKNOWN, 0 }, - /* 2 */ { SDL_SCANCODE_UNKNOWN, 0 }, - /* 3 */ { SDL_SCANCODE_UNKNOWN, 0 }, - /* 4 */ { SDL_SCANCODE_UNKNOWN, 0 }, - /* 5 */ { SDL_SCANCODE_UNKNOWN, 0 }, - /* 6 */ { SDL_SCANCODE_UNKNOWN, 0 }, - /* 7 */ { SDL_SCANCODE_UNKNOWN, 0 }, - /* 8 */ { SDL_SCANCODE_BACKSPACE, 0 }, - /* 9 */ { SDL_SCANCODE_UNKNOWN, 0 }, - /* 10 */ { SDL_SCANCODE_RETURN, 0 }, - /* 11 */ { SDL_SCANCODE_UNKNOWN, 0 }, - /* 12 */ { SDL_SCANCODE_UNKNOWN, 0 }, - /* 13 */ { SDL_SCANCODE_RETURN, 0 }, - /* 14 */ { SDL_SCANCODE_UNKNOWN, 0 }, - /* 15 */ { SDL_SCANCODE_UNKNOWN, 0 }, - /* 16 */ { SDL_SCANCODE_UNKNOWN, 0 }, - /* 17 */ { SDL_SCANCODE_UNKNOWN, 0 }, - /* 18 */ { SDL_SCANCODE_UNKNOWN, 0 }, - /* 19 */ { SDL_SCANCODE_UNKNOWN, 0 }, - /* 20 */ { SDL_SCANCODE_UNKNOWN, 0 }, - /* 21 */ { SDL_SCANCODE_UNKNOWN, 0 }, - /* 22 */ { SDL_SCANCODE_UNKNOWN, 0 }, - /* 23 */ { SDL_SCANCODE_UNKNOWN, 0 }, - /* 24 */ { SDL_SCANCODE_UNKNOWN, 0 }, - /* 25 */ { SDL_SCANCODE_UNKNOWN, 0 }, - /* 26 */ { SDL_SCANCODE_UNKNOWN, 0 }, - /* 27 */ { SDL_SCANCODE_UNKNOWN, 0 }, - /* 28 */ { SDL_SCANCODE_UNKNOWN, 0 }, - /* 29 */ { SDL_SCANCODE_UNKNOWN, 0 }, - /* 30 */ { SDL_SCANCODE_UNKNOWN, 0 }, - /* 31 */ { SDL_SCANCODE_UNKNOWN, 0 }, - /* 32 */ { SDL_SCANCODE_SPACE, 0 }, - /* 33 */ { SDL_SCANCODE_1, SDL_KMOD_SHIFT }, /* plus shift modifier '!' */ - /* 34 */ { SDL_SCANCODE_APOSTROPHE, SDL_KMOD_SHIFT }, /* plus shift modifier '"' */ - /* 35 */ { SDL_SCANCODE_3, SDL_KMOD_SHIFT }, /* plus shift modifier '#' */ - /* 36 */ { SDL_SCANCODE_4, SDL_KMOD_SHIFT }, /* plus shift modifier '$' */ - /* 37 */ { SDL_SCANCODE_5, SDL_KMOD_SHIFT }, /* plus shift modifier '%' */ - /* 38 */ { SDL_SCANCODE_7, SDL_KMOD_SHIFT }, /* plus shift modifier '&' */ - /* 39 */ { SDL_SCANCODE_APOSTROPHE, 0 }, /* ''' */ - /* 40 */ { SDL_SCANCODE_9, SDL_KMOD_SHIFT }, /* plus shift modifier '(' */ - /* 41 */ { SDL_SCANCODE_0, SDL_KMOD_SHIFT }, /* plus shift modifier ')' */ - /* 42 */ { SDL_SCANCODE_8, SDL_KMOD_SHIFT }, /* '*' */ - /* 43 */ { SDL_SCANCODE_EQUALS, SDL_KMOD_SHIFT }, /* plus shift modifier '+' */ - /* 44 */ { SDL_SCANCODE_COMMA, 0 }, /* ',' */ - /* 45 */ { SDL_SCANCODE_MINUS, 0 }, /* '-' */ - /* 46 */ { SDL_SCANCODE_PERIOD, 0 }, /* '.' */ - /* 47 */ { SDL_SCANCODE_SLASH, 0 }, /* '/' */ - /* 48 */ { SDL_SCANCODE_0, 0 }, - /* 49 */ { SDL_SCANCODE_1, 0 }, - /* 50 */ { SDL_SCANCODE_2, 0 }, - /* 51 */ { SDL_SCANCODE_3, 0 }, - /* 52 */ { SDL_SCANCODE_4, 0 }, - /* 53 */ { SDL_SCANCODE_5, 0 }, - /* 54 */ { SDL_SCANCODE_6, 0 }, - /* 55 */ { SDL_SCANCODE_7, 0 }, - /* 56 */ { SDL_SCANCODE_8, 0 }, - /* 57 */ { SDL_SCANCODE_9, 0 }, - /* 58 */ { SDL_SCANCODE_SEMICOLON, SDL_KMOD_SHIFT }, /* plus shift modifier ';' */ - /* 59 */ { SDL_SCANCODE_SEMICOLON, 0 }, - /* 60 */ { SDL_SCANCODE_COMMA, SDL_KMOD_SHIFT }, /* plus shift modifier '<' */ - /* 61 */ { SDL_SCANCODE_EQUALS, 0 }, - /* 62 */ { SDL_SCANCODE_PERIOD, SDL_KMOD_SHIFT }, /* plus shift modifier '>' */ - /* 63 */ { SDL_SCANCODE_SLASH, SDL_KMOD_SHIFT }, /* plus shift modifier '?' */ - /* 64 */ { SDL_SCANCODE_2, SDL_KMOD_SHIFT }, /* plus shift modifier '@' */ - /* 65 */ { SDL_SCANCODE_A, SDL_KMOD_SHIFT }, /* all the following need shift modifiers */ - /* 66 */ { SDL_SCANCODE_B, SDL_KMOD_SHIFT }, - /* 67 */ { SDL_SCANCODE_C, SDL_KMOD_SHIFT }, - /* 68 */ { SDL_SCANCODE_D, SDL_KMOD_SHIFT }, - /* 69 */ { SDL_SCANCODE_E, SDL_KMOD_SHIFT }, - /* 70 */ { SDL_SCANCODE_F, SDL_KMOD_SHIFT }, - /* 71 */ { SDL_SCANCODE_G, SDL_KMOD_SHIFT }, - /* 72 */ { SDL_SCANCODE_H, SDL_KMOD_SHIFT }, - /* 73 */ { SDL_SCANCODE_I, SDL_KMOD_SHIFT }, - /* 74 */ { SDL_SCANCODE_J, SDL_KMOD_SHIFT }, - /* 75 */ { SDL_SCANCODE_K, SDL_KMOD_SHIFT }, - /* 76 */ { SDL_SCANCODE_L, SDL_KMOD_SHIFT }, - /* 77 */ { SDL_SCANCODE_M, SDL_KMOD_SHIFT }, - /* 78 */ { SDL_SCANCODE_N, SDL_KMOD_SHIFT }, - /* 79 */ { SDL_SCANCODE_O, SDL_KMOD_SHIFT }, - /* 80 */ { SDL_SCANCODE_P, SDL_KMOD_SHIFT }, - /* 81 */ { SDL_SCANCODE_Q, SDL_KMOD_SHIFT }, - /* 82 */ { SDL_SCANCODE_R, SDL_KMOD_SHIFT }, - /* 83 */ { SDL_SCANCODE_S, SDL_KMOD_SHIFT }, - /* 84 */ { SDL_SCANCODE_T, SDL_KMOD_SHIFT }, - /* 85 */ { SDL_SCANCODE_U, SDL_KMOD_SHIFT }, - /* 86 */ { SDL_SCANCODE_V, SDL_KMOD_SHIFT }, - /* 87 */ { SDL_SCANCODE_W, SDL_KMOD_SHIFT }, - /* 88 */ { SDL_SCANCODE_X, SDL_KMOD_SHIFT }, - /* 89 */ { SDL_SCANCODE_Y, SDL_KMOD_SHIFT }, - /* 90 */ { SDL_SCANCODE_Z, SDL_KMOD_SHIFT }, - /* 91 */ { SDL_SCANCODE_LEFTBRACKET, 0 }, - /* 92 */ { SDL_SCANCODE_BACKSLASH, 0 }, - /* 93 */ { SDL_SCANCODE_RIGHTBRACKET, 0 }, - /* 94 */ { SDL_SCANCODE_6, SDL_KMOD_SHIFT }, /* plus shift modifier '^' */ - /* 95 */ { SDL_SCANCODE_MINUS, SDL_KMOD_SHIFT }, /* plus shift modifier '_' */ - /* 96 */ { SDL_SCANCODE_GRAVE, SDL_KMOD_SHIFT }, /* '`' */ - /* 97 */ { SDL_SCANCODE_A, 0 }, - /* 98 */ { SDL_SCANCODE_B, 0 }, - /* 99 */ { SDL_SCANCODE_C, 0 }, - /* 100 */ { SDL_SCANCODE_D, 0 }, - /* 101 */ { SDL_SCANCODE_E, 0 }, - /* 102 */ { SDL_SCANCODE_F, 0 }, - /* 103 */ { SDL_SCANCODE_G, 0 }, - /* 104 */ { SDL_SCANCODE_H, 0 }, - /* 105 */ { SDL_SCANCODE_I, 0 }, - /* 106 */ { SDL_SCANCODE_J, 0 }, - /* 107 */ { SDL_SCANCODE_K, 0 }, - /* 108 */ { SDL_SCANCODE_L, 0 }, - /* 109 */ { SDL_SCANCODE_M, 0 }, - /* 110 */ { SDL_SCANCODE_N, 0 }, - /* 111 */ { SDL_SCANCODE_O, 0 }, - /* 112 */ { SDL_SCANCODE_P, 0 }, - /* 113 */ { SDL_SCANCODE_Q, 0 }, - /* 114 */ { SDL_SCANCODE_R, 0 }, - /* 115 */ { SDL_SCANCODE_S, 0 }, - /* 116 */ { SDL_SCANCODE_T, 0 }, - /* 117 */ { SDL_SCANCODE_U, 0 }, - /* 118 */ { SDL_SCANCODE_V, 0 }, - /* 119 */ { SDL_SCANCODE_W, 0 }, - /* 120 */ { SDL_SCANCODE_X, 0 }, - /* 121 */ { SDL_SCANCODE_Y, 0 }, - /* 122 */ { SDL_SCANCODE_Z, 0 }, - /* 123 */ { SDL_SCANCODE_LEFTBRACKET, SDL_KMOD_SHIFT }, /* plus shift modifier '{' */ - /* 124 */ { SDL_SCANCODE_BACKSLASH, SDL_KMOD_SHIFT }, /* plus shift modifier '|' */ - /* 125 */ { SDL_SCANCODE_RIGHTBRACKET, SDL_KMOD_SHIFT }, /* plus shift modifier '}' */ - /* 126 */ { SDL_SCANCODE_GRAVE, SDL_KMOD_SHIFT }, /* plus shift modifier '~' */ - /* 127 */ { SDL_SCANCODE_BACKSPACE, SDL_KMOD_SHIFT } -}; diff --git a/src/video/cocoa/SDL_cocoakeyboard.m b/src/video/cocoa/SDL_cocoakeyboard.m index 5da5db1277ac5..f6ef52bf3ad57 100644 --- a/src/video/cocoa/SDL_cocoakeyboard.m +++ b/src/video/cocoa/SDL_cocoakeyboard.m @@ -240,10 +240,7 @@ static void HandleModifiers(SDL_VideoDevice *_this, SDL_Scancode code, unsigned static void UpdateKeymap(SDL_CocoaVideoData *data, SDL_bool send_event) { TISInputSourceRef key_layout; - const void *chr_data; - int i; - SDL_Scancode scancode; - SDL_Keycode keymap[SDL_NUM_SCANCODES]; + UCKeyboardLayout *keyLayoutPtr = NULL; CFDataRef uchrDataRef; /* See if the keymap needs to be updated */ @@ -253,29 +250,45 @@ static void UpdateKeymap(SDL_CocoaVideoData *data, SDL_bool send_event) } data.key_layout = key_layout; - SDL_GetDefaultKeymap(keymap); - /* Try Unicode data first */ uchrDataRef = TISGetInputSourceProperty(key_layout, kTISPropertyUnicodeKeyLayoutData); if (uchrDataRef) { - chr_data = CFDataGetBytePtr(uchrDataRef); - } else { - goto cleanup; + keyLayoutPtr = (UCKeyboardLayout *)CFDataGetBytePtr(uchrDataRef); } - if (chr_data) { - UInt32 keyboard_type = LMGetKbdType(); - OSStatus err; + if (!keyLayoutPtr) { + CFRelease(key_layout); + return; + } - for (i = 0; i < SDL_arraysize(darwin_scancode_table); i++) { + static struct { + int flags; + SDL_Keymod modstate; + } mods[] = { + { 0, SDL_KMOD_NONE }, + { shiftKey, SDL_KMOD_SHIFT }, + { alphaLock, SDL_KMOD_CAPS }, + { (shiftKey | alphaLock), (SDL_KMOD_SHIFT | SDL_KMOD_CAPS) }, + { optionKey, SDL_KMOD_ALT }, + { (optionKey | shiftKey), (SDL_KMOD_ALT | SDL_KMOD_SHIFT) }, + { (optionKey | alphaLock), (SDL_KMOD_ALT | SDL_KMOD_CAPS) }, + { (optionKey | shiftKey | alphaLock), (SDL_KMOD_ALT | SDL_KMOD_SHIFT | SDL_KMOD_CAPS) } + }; + + UInt32 keyboard_type = LMGetKbdType(); + + SDL_Keymap *keymap = SDL_CreateKeymap(); + for (int m = 0; m < SDL_arraysize(mods); ++m) { + for (int i = 0; i < SDL_arraysize(darwin_scancode_table); i++) { + OSStatus err; UniChar s[8]; UniCharCount len; UInt32 dead_key_state; /* Make sure this scancode is a valid character scancode */ - scancode = darwin_scancode_table[i]; + SDL_Scancode scancode = darwin_scancode_table[i]; if (scancode == SDL_SCANCODE_UNKNOWN || - (keymap[scancode] & SDLK_SCANCODE_MASK)) { + (SDL_GetDefaultKeyFromScancode(scancode, SDL_KMOD_NONE) & SDLK_SCANCODE_MASK)) { continue; } @@ -291,9 +304,8 @@ static void UpdateKeymap(SDL_CocoaVideoData *data, SDL_bool send_event) } dead_key_state = 0; - err = UCKeyTranslate((UCKeyboardLayout *)chr_data, - i, kUCKeyActionDown, - 0, keyboard_type, + err = UCKeyTranslate(keyLayoutPtr, i, kUCKeyActionDown, + ((mods[m].flags >> 8) & 0xFF), keyboard_type, kUCKeyTranslateNoDeadKeysMask, &dead_key_state, 8, &len, s); if (err != noErr) { @@ -301,15 +313,16 @@ static void UpdateKeymap(SDL_CocoaVideoData *data, SDL_bool send_event) } if (len > 0 && s[0] != 0x10) { - keymap[scancode] = s[0]; + SDL_SetKeymapEntry(keymap, scancode, mods[m].modstate, s[0]); + } else { + // The default keymap doesn't have any SDL_KMOD_ALT entries, so we don't need to override them + if (!(mods[m].modstate & SDL_KMOD_ALT)) { + SDL_SetKeymapEntry(keymap, scancode, mods[m].modstate, SDLK_UNKNOWN); + } } } - SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES, send_event); - return; } - -cleanup: - CFRelease(key_layout); + SDL_SetKeymap(keymap, send_event); } void Cocoa_InitKeyboard(SDL_VideoDevice *_this) diff --git a/src/video/haiku/SDL_bkeyboard.cc b/src/video/haiku/SDL_bkeyboard.cc index 10af7ad763ff6..5f3fbaf17a2af 100644 --- a/src/video/haiku/SDL_bkeyboard.cc +++ b/src/video/haiku/SDL_bkeyboard.cc @@ -39,7 +39,8 @@ extern "C" { static SDL_Scancode keymap[KEYMAP_SIZE]; static int8 keystate[KEYMAP_SIZE]; -void HAIKU_InitOSKeymap(void) { +void HAIKU_InitOSKeymap(void) +{ for ( uint i = 0; i < SDL_arraysize(keymap); ++i ) { keymap[i] = SDL_SCANCODE_UNKNOWN; } @@ -48,113 +49,113 @@ void HAIKU_InitOSKeymap(void) { keystate[i] = SDL_RELEASED; } - keymap[0x01] = SDL_GetScancodeFromKey(SDLK_ESCAPE); - keymap[B_F1_KEY] = SDL_GetScancodeFromKey(SDLK_F1); - keymap[B_F2_KEY] = SDL_GetScancodeFromKey(SDLK_F2); - keymap[B_F3_KEY] = SDL_GetScancodeFromKey(SDLK_F3); - keymap[B_F4_KEY] = SDL_GetScancodeFromKey(SDLK_F4); - keymap[B_F5_KEY] = SDL_GetScancodeFromKey(SDLK_F5); - keymap[B_F6_KEY] = SDL_GetScancodeFromKey(SDLK_F6); - keymap[B_F7_KEY] = SDL_GetScancodeFromKey(SDLK_F7); - keymap[B_F8_KEY] = SDL_GetScancodeFromKey(SDLK_F8); - keymap[B_F9_KEY] = SDL_GetScancodeFromKey(SDLK_F9); - keymap[B_F10_KEY] = SDL_GetScancodeFromKey(SDLK_F10); - keymap[B_F11_KEY] = SDL_GetScancodeFromKey(SDLK_F11); - keymap[B_F12_KEY] = SDL_GetScancodeFromKey(SDLK_F12); - keymap[B_PRINT_KEY] = SDL_GetScancodeFromKey(SDLK_PRINTSCREEN); - keymap[B_SCROLL_KEY] = SDL_GetScancodeFromKey(SDLK_SCROLLLOCK); - keymap[B_PAUSE_KEY] = SDL_GetScancodeFromKey(SDLK_PAUSE); - keymap[0x11] = SDL_GetScancodeFromKey(SDLK_GRAVE); - keymap[0x12] = SDL_GetScancodeFromKey(SDLK_1); - keymap[0x13] = SDL_GetScancodeFromKey(SDLK_2); - keymap[0x14] = SDL_GetScancodeFromKey(SDLK_3); - keymap[0x15] = SDL_GetScancodeFromKey(SDLK_4); - keymap[0x16] = SDL_GetScancodeFromKey(SDLK_5); - keymap[0x17] = SDL_GetScancodeFromKey(SDLK_6); - keymap[0x18] = SDL_GetScancodeFromKey(SDLK_7); - keymap[0x19] = SDL_GetScancodeFromKey(SDLK_8); - keymap[0x1a] = SDL_GetScancodeFromKey(SDLK_9); - keymap[0x1b] = SDL_GetScancodeFromKey(SDLK_0); - keymap[0x1c] = SDL_GetScancodeFromKey(SDLK_MINUS); - keymap[0x1d] = SDL_GetScancodeFromKey(SDLK_EQUALS); - keymap[0x1e] = SDL_GetScancodeFromKey(SDLK_BACKSPACE); - keymap[0x1f] = SDL_GetScancodeFromKey(SDLK_INSERT); - keymap[0x20] = SDL_GetScancodeFromKey(SDLK_HOME); - keymap[0x21] = SDL_GetScancodeFromKey(SDLK_PAGEUP); - keymap[0x22] = SDL_GetScancodeFromKey(SDLK_NUMLOCKCLEAR); - keymap[0x23] = SDL_GetScancodeFromKey(SDLK_KP_DIVIDE); - keymap[0x24] = SDL_GetScancodeFromKey(SDLK_KP_MULTIPLY); - keymap[0x25] = SDL_GetScancodeFromKey(SDLK_KP_MINUS); - keymap[0x26] = SDL_GetScancodeFromKey(SDLK_TAB); - keymap[0x27] = SDL_GetScancodeFromKey(SDLK_q); - keymap[0x28] = SDL_GetScancodeFromKey(SDLK_w); - keymap[0x29] = SDL_GetScancodeFromKey(SDLK_e); - keymap[0x2a] = SDL_GetScancodeFromKey(SDLK_r); - keymap[0x2b] = SDL_GetScancodeFromKey(SDLK_t); - keymap[0x2c] = SDL_GetScancodeFromKey(SDLK_y); - keymap[0x2d] = SDL_GetScancodeFromKey(SDLK_u); - keymap[0x2e] = SDL_GetScancodeFromKey(SDLK_i); - keymap[0x2f] = SDL_GetScancodeFromKey(SDLK_o); - keymap[0x30] = SDL_GetScancodeFromKey(SDLK_p); - keymap[0x31] = SDL_GetScancodeFromKey(SDLK_LEFTBRACKET); - keymap[0x32] = SDL_GetScancodeFromKey(SDLK_RIGHTBRACKET); - keymap[0x33] = SDL_GetScancodeFromKey(SDLK_BACKSLASH); - keymap[0x34] = SDL_GetScancodeFromKey(SDLK_DELETE); - keymap[0x35] = SDL_GetScancodeFromKey(SDLK_END); - keymap[0x36] = SDL_GetScancodeFromKey(SDLK_PAGEDOWN); - keymap[0x37] = SDL_GetScancodeFromKey(SDLK_KP_7); - keymap[0x38] = SDL_GetScancodeFromKey(SDLK_KP_8); - keymap[0x39] = SDL_GetScancodeFromKey(SDLK_KP_9); - keymap[0x3a] = SDL_GetScancodeFromKey(SDLK_KP_PLUS); - keymap[0x3b] = SDL_GetScancodeFromKey(SDLK_CAPSLOCK); - keymap[0x3c] = SDL_GetScancodeFromKey(SDLK_a); - keymap[0x3d] = SDL_GetScancodeFromKey(SDLK_s); - keymap[0x3e] = SDL_GetScancodeFromKey(SDLK_d); - keymap[0x3f] = SDL_GetScancodeFromKey(SDLK_f); - keymap[0x40] = SDL_GetScancodeFromKey(SDLK_g); - keymap[0x41] = SDL_GetScancodeFromKey(SDLK_h); - keymap[0x42] = SDL_GetScancodeFromKey(SDLK_j); - keymap[0x43] = SDL_GetScancodeFromKey(SDLK_k); - keymap[0x44] = SDL_GetScancodeFromKey(SDLK_l); - keymap[0x45] = SDL_GetScancodeFromKey(SDLK_SEMICOLON); - keymap[0x46] = SDL_GetScancodeFromKey(SDLK_APOSTROPHE); - keymap[0x47] = SDL_GetScancodeFromKey(SDLK_RETURN); - keymap[0x48] = SDL_GetScancodeFromKey(SDLK_KP_4); - keymap[0x49] = SDL_GetScancodeFromKey(SDLK_KP_5); - keymap[0x4a] = SDL_GetScancodeFromKey(SDLK_KP_6); - keymap[0x4b] = SDL_GetScancodeFromKey(SDLK_LSHIFT); - keymap[0x4c] = SDL_GetScancodeFromKey(SDLK_z); - keymap[0x4d] = SDL_GetScancodeFromKey(SDLK_x); - keymap[0x4e] = SDL_GetScancodeFromKey(SDLK_c); - keymap[0x4f] = SDL_GetScancodeFromKey(SDLK_v); - keymap[0x50] = SDL_GetScancodeFromKey(SDLK_b); - keymap[0x51] = SDL_GetScancodeFromKey(SDLK_n); - keymap[0x52] = SDL_GetScancodeFromKey(SDLK_m); - keymap[0x53] = SDL_GetScancodeFromKey(SDLK_COMMA); - keymap[0x54] = SDL_GetScancodeFromKey(SDLK_PERIOD); - keymap[0x55] = SDL_GetScancodeFromKey(SDLK_SLASH); - keymap[0x56] = SDL_GetScancodeFromKey(SDLK_RSHIFT); - keymap[0x57] = SDL_GetScancodeFromKey(SDLK_UP); - keymap[0x58] = SDL_GetScancodeFromKey(SDLK_KP_1); - keymap[0x59] = SDL_GetScancodeFromKey(SDLK_KP_2); - keymap[0x5a] = SDL_GetScancodeFromKey(SDLK_KP_3); - keymap[0x5b] = SDL_GetScancodeFromKey(SDLK_KP_ENTER); - keymap[0x5c] = SDL_GetScancodeFromKey(SDLK_LCTRL); - keymap[0x5d] = SDL_GetScancodeFromKey(SDLK_LALT); - keymap[0x5e] = SDL_GetScancodeFromKey(SDLK_SPACE); - keymap[0x5f] = SDL_GetScancodeFromKey(SDLK_RALT); - keymap[0x60] = SDL_GetScancodeFromKey(SDLK_RCTRL); - keymap[0x61] = SDL_GetScancodeFromKey(SDLK_LEFT); - keymap[0x62] = SDL_GetScancodeFromKey(SDLK_DOWN); - keymap[0x63] = SDL_GetScancodeFromKey(SDLK_RIGHT); - keymap[0x64] = SDL_GetScancodeFromKey(SDLK_KP_0); - keymap[0x65] = SDL_GetScancodeFromKey(SDLK_KP_PERIOD); - keymap[0x66] = SDL_GetScancodeFromKey(SDLK_LGUI); - keymap[0x67] = SDL_GetScancodeFromKey(SDLK_RGUI); - keymap[0x68] = SDL_GetScancodeFromKey(SDLK_MENU); - keymap[0x69] = SDL_GetScancodeFromKey(SDLK_2); /* SDLK_EURO */ - keymap[0x6a] = SDL_GetScancodeFromKey(SDLK_KP_EQUALS); - keymap[0x6b] = SDL_GetScancodeFromKey(SDLK_POWER); + keymap[0x01] = SDL_SCANCODE_ESCAPE; + keymap[B_F1_KEY] = SDL_SCANCODE_F1; + keymap[B_F2_KEY] = SDL_SCANCODE_F2; + keymap[B_F3_KEY] = SDL_SCANCODE_F3; + keymap[B_F4_KEY] = SDL_SCANCODE_F4; + keymap[B_F5_KEY] = SDL_SCANCODE_F5; + keymap[B_F6_KEY] = SDL_SCANCODE_F6; + keymap[B_F7_KEY] = SDL_SCANCODE_F7; + keymap[B_F8_KEY] = SDL_SCANCODE_F8; + keymap[B_F9_KEY] = SDL_SCANCODE_F9; + keymap[B_F10_KEY] = SDL_SCANCODE_F10; + keymap[B_F11_KEY] = SDL_SCANCODE_F11; + keymap[B_F12_KEY] = SDL_SCANCODE_F12; + keymap[B_PRINT_KEY] = SDL_SCANCODE_PRINTSCREEN; + keymap[B_SCROLL_KEY]= SDL_SCANCODE_SCROLLLOCK; + keymap[B_PAUSE_KEY] = SDL_SCANCODE_PAUSE; + keymap[0x11] = SDL_SCANCODE_GRAVE; + keymap[0x12] = SDL_SCANCODE_1; + keymap[0x13] = SDL_SCANCODE_2; + keymap[0x14] = SDL_SCANCODE_3; + keymap[0x15] = SDL_SCANCODE_4; + keymap[0x16] = SDL_SCANCODE_5; + keymap[0x17] = SDL_SCANCODE_6; + keymap[0x18] = SDL_SCANCODE_7; + keymap[0x19] = SDL_SCANCODE_8; + keymap[0x1a] = SDL_SCANCODE_9; + keymap[0x1b] = SDL_SCANCODE_0; + keymap[0x1c] = SDL_SCANCODE_MINUS; + keymap[0x1d] = SDL_SCANCODE_EQUALS; + keymap[0x1e] = SDL_SCANCODE_BACKSPACE; + keymap[0x1f] = SDL_SCANCODE_INSERT; + keymap[0x20] = SDL_SCANCODE_HOME; + keymap[0x21] = SDL_SCANCODE_PAGEUP; + keymap[0x22] = SDL_SCANCODE_NUMLOCKCLEAR; + keymap[0x23] = SDL_SCANCODE_KP_DIVIDE; + keymap[0x24] = SDL_SCANCODE_KP_MULTIPLY; + keymap[0x25] = SDL_SCANCODE_KP_MINUS; + keymap[0x26] = SDL_SCANCODE_TAB; + keymap[0x27] = SDL_SCANCODE_Q; + keymap[0x28] = SDL_SCANCODE_W; + keymap[0x29] = SDL_SCANCODE_E; + keymap[0x2a] = SDL_SCANCODE_R; + keymap[0x2b] = SDL_SCANCODE_T; + keymap[0x2c] = SDL_SCANCODE_Y; + keymap[0x2d] = SDL_SCANCODE_U; + keymap[0x2e] = SDL_SCANCODE_I; + keymap[0x2f] = SDL_SCANCODE_O; + keymap[0x30] = SDL_SCANCODE_P; + keymap[0x31] = SDL_SCANCODE_LEFTBRACKET; + keymap[0x32] = SDL_SCANCODE_RIGHTBRACKET; + keymap[0x33] = SDL_SCANCODE_BACKSLASH; + keymap[0x34] = SDL_SCANCODE_DELETE; + keymap[0x35] = SDL_SCANCODE_END; + keymap[0x36] = SDL_SCANCODE_PAGEDOWN; + keymap[0x37] = SDL_SCANCODE_KP_7; + keymap[0x38] = SDL_SCANCODE_KP_8; + keymap[0x39] = SDL_SCANCODE_KP_9; + keymap[0x3a] = SDL_SCANCODE_KP_PLUS; + keymap[0x3b] = SDL_SCANCODE_CAPSLOCK; + keymap[0x3c] = SDL_SCANCODE_A; + keymap[0x3d] = SDL_SCANCODE_S; + keymap[0x3e] = SDL_SCANCODE_D; + keymap[0x3f] = SDL_SCANCODE_F; + keymap[0x40] = SDL_SCANCODE_G; + keymap[0x41] = SDL_SCANCODE_H; + keymap[0x42] = SDL_SCANCODE_J; + keymap[0x43] = SDL_SCANCODE_K; + keymap[0x44] = SDL_SCANCODE_L; + keymap[0x45] = SDL_SCANCODE_SEMICOLON; + keymap[0x46] = SDL_SCANCODE_APOSTROPHE; + keymap[0x47] = SDL_SCANCODE_RETURN; + keymap[0x48] = SDL_SCANCODE_KP_4; + keymap[0x49] = SDL_SCANCODE_KP_5; + keymap[0x4a] = SDL_SCANCODE_KP_6; + keymap[0x4b] = SDL_SCANCODE_LSHIFT; + keymap[0x4c] = SDL_SCANCODE_Z; + keymap[0x4d] = SDL_SCANCODE_X; + keymap[0x4e] = SDL_SCANCODE_C; + keymap[0x4f] = SDL_SCANCODE_V; + keymap[0x50] = SDL_SCANCODE_B; + keymap[0x51] = SDL_SCANCODE_N; + keymap[0x52] = SDL_SCANCODE_M; + keymap[0x53] = SDL_SCANCODE_COMMA; + keymap[0x54] = SDL_SCANCODE_PERIOD; + keymap[0x55] = SDL_SCANCODE_SLASH; + keymap[0x56] = SDL_SCANCODE_RSHIFT; + keymap[0x57] = SDL_SCANCODE_UP; + keymap[0x58] = SDL_SCANCODE_KP_1; + keymap[0x59] = SDL_SCANCODE_KP_2; + keymap[0x5a] = SDL_SCANCODE_KP_3; + keymap[0x5b] = SDL_SCANCODE_KP_ENTER; + keymap[0x5c] = SDL_SCANCODE_LCTRL; + keymap[0x5d] = SDL_SCANCODE_LALT; + keymap[0x5e] = SDL_SCANCODE_SPACE; + keymap[0x5f] = SDL_SCANCODE_RALT; + keymap[0x60] = SDL_SCANCODE_RCTRL; + keymap[0x61] = SDL_SCANCODE_LEFT; + keymap[0x62] = SDL_SCANCODE_DOWN; + keymap[0x63] = SDL_SCANCODE_RIGHT; + keymap[0x64] = SDL_SCANCODE_KP_0; + keymap[0x65] = SDL_SCANCODE_KP_PERIOD; + keymap[0x66] = SDL_SCANCODE_LGUI; + keymap[0x67] = SDL_SCANCODE_RGUI; + keymap[0x68] = SDL_SCANCODE_MENU; + keymap[0x69] = SDL_SCANCODE_2; /* SDLK_EURO */ + keymap[0x6a] = SDL_SCANCODE_KP_EQUALS; + keymap[0x6b] = SDL_SCANCODE_POWER; } SDL_Scancode HAIKU_GetScancodeFromBeKey(int32 bkey) { diff --git a/src/video/ngage/SDL_ngageevents.cpp b/src/video/ngage/SDL_ngageevents.cpp index cd82b6b4a4611..59a524a8f76dd 100644 --- a/src/video/ngage/SDL_ngageevents.cpp +++ b/src/video/ngage/SDL_ngageevents.cpp @@ -70,81 +70,81 @@ TBool isCursorVisible = EFalse; static SDL_Scancode ConvertScancode(SDL_VideoDevice *_this, int key) { - SDL_Keycode keycode; + SDL_Keycode scancode; switch (key) { case EStdKeyBackspace: // Clear key - keycode = SDLK_BACKSPACE; + scancode = SDL_SCANCODE_BACKSPACE; break; case 0x31: // 1 - keycode = SDLK_1; + scancode = SDL_SCANCODE_1; break; case 0x32: // 2 - keycode = SDLK_2; + scancode = SDL_SCANCODE_2; break; case 0x33: // 3 - keycode = SDLK_3; + scancode = SDL_SCANCODE_3; break; case 0x34: // 4 - keycode = SDLK_4; + scancode = SDL_SCANCODE_4; break; case 0x35: // 5 - keycode = SDLK_5; + scancode = SDL_SCANCODE_5; break; case 0x36: // 6 - keycode = SDLK_6; + scancode = SDL_SCANCODE_6; break; case 0x37: // 7 - keycode = SDLK_7; + scancode = SDL_SCANCODE_7; break; case 0x38: // 8 - keycode = SDLK_8; + scancode = SDL_SCANCODE_8; break; case 0x39: // 9 - keycode = SDLK_9; + scancode = SDL_SCANCODE_9; break; case 0x30: // 0 - keycode = SDLK_0; + scancode = SDL_SCANCODE_0; break; case 0x2a: // Asterisk - keycode = SDLK_ASTERISK; + scancode = SDL_SCANCODE_ASTERISK; break; case EStdKeyHash: // Hash - keycode = SDLK_HASH; + scancode = SDL_SCANCODE_HASH; break; case EStdKeyDevice0: // Left softkey - keycode = SDLK_SOFTLEFT; + scancode = SDL_SCANCODE_SOFTLEFT; break; case EStdKeyDevice1: // Right softkey - keycode = SDLK_SOFTRIGHT; + scancode = SDL_SCANCODE_SOFTRIGHT; break; case EStdKeyApplication0: // Call softkey - keycode = SDLK_CALL; + scancode = SDL_SCANCODE_CALL; break; case EStdKeyApplication1: // End call softkey - keycode = SDLK_ENDCALL; + scancode = SDL_SCANCODE_ENDCALL; break; case EStdKeyDevice3: // Middle softkey - keycode = SDLK_SELECT; + scancode = SDL_SCANCODE_SELECT; break; case EStdKeyUpArrow: // Up arrow - keycode = SDLK_UP; + scancode = SDL_SCANCODE_UP; break; case EStdKeyDownArrow: // Down arrow - keycode = SDLK_DOWN; + scancode = SDL_SCANCODE_DOWN; break; case EStdKeyLeftArrow: // Left arrow - keycode = SDLK_LEFT; + scancode = SDL_SCANCODE_LEFT; break; case EStdKeyRightArrow: // Right arrow - keycode = SDLK_RIGHT; + scancode = SDL_SCANCODE_RIGHT; break; default: - keycode = SDLK_UNKNOWN; + scancode = SDL_SCANCODE_UNKNOWN; break; } - return SDL_GetScancodeFromKey(keycode); + return scancode; } int HandleWsEvent(SDL_VideoDevice *_this, const TWsEvent &aWsEvent) diff --git a/src/video/psp/SDL_pspevents.c b/src/video/psp/SDL_pspevents.c index ecc441c1ff1e3..1876b3f067473 100644 --- a/src/video/psp/SDL_pspevents.c +++ b/src/video/psp/SDL_pspevents.c @@ -41,7 +41,7 @@ #define IRKBD_CONFIG_FILE NULL /* this will take ms0:/seplugins/pspirkeyb.ini */ static int irkbd_ready = 0; -static SDL_Keycode keymap[256]; +static SDL_Scancode keymap[256]; #endif static enum PspHprmKeys hprm = 0; @@ -51,14 +51,14 @@ static int running = 0; static struct { enum PspHprmKeys id; - SDL_Keycode sym; + SDL_Scancode scancode; } keymap_psp[] = { - { PSP_HPRM_PLAYPAUSE, SDLK_F10 }, - { PSP_HPRM_FORWARD, SDLK_F11 }, - { PSP_HPRM_BACK, SDLK_F12 }, - { PSP_HPRM_VOL_UP, SDLK_F13 }, - { PSP_HPRM_VOL_DOWN, SDLK_F14 }, - { PSP_HPRM_HOLD, SDLK_F15 } + { PSP_HPRM_PLAYPAUSE, SDL_SCANCODE_F10 }, + { PSP_HPRM_FORWARD, SDL_SCANCODE_F11 }, + { PSP_HPRM_BACK, SDL_SCANCODE_F12 }, + { PSP_HPRM_VOL_UP, SDL_SCANCODE_F13 }, + { PSP_HPRM_VOL_DOWN, SDL_SCANCODE_F14 }, + { PSP_HPRM_HOLD, SDL_SCANCODE_F15 } }; int EventUpdate(void *data) @@ -90,7 +90,7 @@ void PSP_PumpEvents(SDL_VideoDevice *_this) if (changed) { for (i = 0; i < sizeof(keymap_psp) / sizeof(keymap_psp[0]); i++) { if (changed & keymap_psp[i].id) { - SDL_SendKeyboardKey(0, SDL_GLOBAL_KEYBOARD_ID, keymap_psp[i].id, SDL_GetScancodeFromKey(keymap_psp[i].sym), (keys & keymap_psp[i].id) ? SDL_PRESSED : SDL_RELEASED); + SDL_SendKeyboardKey(0, SDL_GLOBAL_KEYBOARD_ID, keymap_psp[i].id, keymap_psp[i].scancode, (keys & keymap_psp[i].id) ? SDL_PRESSED : SDL_RELEASED); } } } @@ -109,11 +109,7 @@ void PSP_PumpEvents(SDL_VideoDevice *_this) scanData = (SIrKeybScanCodeData *)buffer + i; raw = scanData->raw; pressed = scanData->pressed; - sym.scancode = raw; - sym.sym = keymap[raw]; - /* not tested */ - /* SDL_PrivateKeyboard(pressed?SDL_PRESSED:SDL_RELEASED, &sym); */ - SDL_SendKeyboardKey(0, SDL_GLOBAL_KEYBOARD_ID, raw, SDL_GetScancodeFromKey(keymap[raw]), (keys & keymap_psp[i].id) ? SDL_PRESSED : SDL_RELEASED); + SDL_SendKeyboardKey(0, SDL_GLOBAL_KEYBOARD_ID, raw, keymap[raw], pressed ? SDL_PRESSED : SDL_RELEASED); } } } @@ -129,109 +125,109 @@ void PSP_InitOSKeymap(SDL_VideoDevice *_this) #ifdef PSPIRKEYB int i; for (i = 0; i < SDL_arraysize(keymap); ++i) { - keymap[i] = SDLK_UNKNOWN; + keymap[i] = SDL_SCANCODE_UNKNOWN; } - keymap[KEY_ESC] = SDLK_ESCAPE; - - keymap[KEY_F1] = SDLK_F1; - keymap[KEY_F2] = SDLK_F2; - keymap[KEY_F3] = SDLK_F3; - keymap[KEY_F4] = SDLK_F4; - keymap[KEY_F5] = SDLK_F5; - keymap[KEY_F6] = SDLK_F6; - keymap[KEY_F7] = SDLK_F7; - keymap[KEY_F8] = SDLK_F8; - keymap[KEY_F9] = SDLK_F9; - keymap[KEY_F10] = SDLK_F10; - keymap[KEY_F11] = SDLK_F11; - keymap[KEY_F12] = SDLK_F12; - keymap[KEY_F13] = SDLK_PRINT; - keymap[KEY_F14] = SDLK_PAUSE; - - keymap[KEY_GRAVE] = SDLK_GRAVE; - keymap[KEY_1] = SDLK_1; - keymap[KEY_2] = SDLK_2; - keymap[KEY_3] = SDLK_3; - keymap[KEY_4] = SDLK_4; - keymap[KEY_5] = SDLK_5; - keymap[KEY_6] = SDLK_6; - keymap[KEY_7] = SDLK_7; - keymap[KEY_8] = SDLK_8; - keymap[KEY_9] = SDLK_9; - keymap[KEY_0] = SDLK_0; - keymap[KEY_MINUS] = SDLK_MINUS; - keymap[KEY_EQUAL] = SDLK_EQUALS; - keymap[KEY_BACKSPACE] = SDLK_BACKSPACE; - - keymap[KEY_TAB] = SDLK_TAB; - keymap[KEY_Q] = SDLK_q; - keymap[KEY_W] = SDLK_w; - keymap[KEY_E] = SDLK_e; - keymap[KEY_R] = SDLK_r; - keymap[KEY_T] = SDLK_t; - keymap[KEY_Y] = SDLK_y; - keymap[KEY_U] = SDLK_u; - keymap[KEY_I] = SDLK_i; - keymap[KEY_O] = SDLK_o; - keymap[KEY_P] = SDLK_p; - keymap[KEY_LEFTBRACE] = SDLK_LEFTBRACKET; - keymap[KEY_RIGHTBRACE] = SDLK_RIGHTBRACKET; - keymap[KEY_ENTER] = SDLK_RETURN; - - keymap[KEY_CAPSLOCK] = SDLK_CAPSLOCK; - keymap[KEY_A] = SDLK_a; - keymap[KEY_S] = SDLK_s; - keymap[KEY_D] = SDLK_d; - keymap[KEY_F] = SDLK_f; - keymap[KEY_G] = SDLK_g; - keymap[KEY_H] = SDLK_h; - keymap[KEY_J] = SDLK_j; - keymap[KEY_K] = SDLK_k; - keymap[KEY_L] = SDLK_l; - keymap[KEY_SEMICOLON] = SDLK_SEMICOLON; - keymap[KEY_APOSTROPHE] = SDLK_APOSTROPHE; - keymap[KEY_BACKSLASH] = SDLK_BACKSLASH; - - keymap[KEY_Z] = SDLK_z; - keymap[KEY_X] = SDLK_x; - keymap[KEY_C] = SDLK_c; - keymap[KEY_V] = SDLK_v; - keymap[KEY_B] = SDLK_b; - keymap[KEY_N] = SDLK_n; - keymap[KEY_M] = SDLK_m; - keymap[KEY_COMMA] = SDLK_COMMA; - keymap[KEY_DOT] = SDLK_PERIOD; - keymap[KEY_SLASH] = SDLK_SLASH; - - keymap[KEY_SPACE] = SDLK_SPACE; - - keymap[KEY_UP] = SDLK_UP; - keymap[KEY_DOWN] = SDLK_DOWN; - keymap[KEY_LEFT] = SDLK_LEFT; - keymap[KEY_RIGHT] = SDLK_RIGHT; - - keymap[KEY_HOME] = SDLK_HOME; - keymap[KEY_END] = SDLK_END; - keymap[KEY_INSERT] = SDLK_INSERT; - keymap[KEY_DELETE] = SDLK_DELETE; - - keymap[KEY_NUMLOCK] = SDLK_NUMLOCK; - keymap[KEY_LEFTMETA] = SDLK_LSUPER; - - keymap[KEY_KPSLASH] = SDLK_KP_DIVIDE; - keymap[KEY_KPASTERISK] = SDLK_KP_MULTIPLY; - keymap[KEY_KPMINUS] = SDLK_KP_MINUS; - keymap[KEY_KPPLUS] = SDLK_KP_PLUS; - keymap[KEY_KPDOT] = SDLK_KP_PERIOD; - keymap[KEY_KPEQUAL] = SDLK_KP_EQUALS; - - keymap[KEY_LEFTCTRL] = SDLK_LCTRL; - keymap[KEY_RIGHTCTRL] = SDLK_RCTRL; - keymap[KEY_LEFTALT] = SDLK_LALT; - keymap[KEY_RIGHTALT] = SDLK_RALT; - keymap[KEY_LEFTSHIFT] = SDLK_LSHIFT; - keymap[KEY_RIGHTSHIFT] = SDLK_RSHIFT; + keymap[KEY_ESC] = SDL_SCANCODE_ESCAPE; + + keymap[KEY_F1] = SDL_SCANCODE_F1; + keymap[KEY_F2] = SDL_SCANCODE_F2; + keymap[KEY_F3] = SDL_SCANCODE_F3; + keymap[KEY_F4] = SDL_SCANCODE_F4; + keymap[KEY_F5] = SDL_SCANCODE_F5; + keymap[KEY_F6] = SDL_SCANCODE_F6; + keymap[KEY_F7] = SDL_SCANCODE_F7; + keymap[KEY_F8] = SDL_SCANCODE_F8; + keymap[KEY_F9] = SDL_SCANCODE_F9; + keymap[KEY_F10] = SDL_SCANCODE_F10; + keymap[KEY_F11] = SDL_SCANCODE_F11; + keymap[KEY_F12] = SDL_SCANCODE_F12; + keymap[KEY_F13] = SDL_SCANCODE_PRINT; + keymap[KEY_F14] = SDL_SCANCODE_PAUSE; + + keymap[KEY_GRAVE] = SDL_SCANCODE_GRAVE; + keymap[KEY_1] = SDL_SCANCODE_1; + keymap[KEY_2] = SDL_SCANCODE_2; + keymap[KEY_3] = SDL_SCANCODE_3; + keymap[KEY_4] = SDL_SCANCODE_4; + keymap[KEY_5] = SDL_SCANCODE_5; + keymap[KEY_6] = SDL_SCANCODE_6; + keymap[KEY_7] = SDL_SCANCODE_7; + keymap[KEY_8] = SDL_SCANCODE_8; + keymap[KEY_9] = SDL_SCANCODE_9; + keymap[KEY_0] = SDL_SCANCODE_0; + keymap[KEY_MINUS] = SDL_SCANCODE_MINUS; + keymap[KEY_EQUAL] = SDL_SCANCODE_EQUALS; + keymap[KEY_BACKSPACE] = SDL_SCANCODE_BACKSPACE; + + keymap[KEY_TAB] = SDL_SCANCODE_TAB; + keymap[KEY_Q] = SDL_SCANCODE_q; + keymap[KEY_W] = SDL_SCANCODE_w; + keymap[KEY_E] = SDL_SCANCODE_e; + keymap[KEY_R] = SDL_SCANCODE_r; + keymap[KEY_T] = SDL_SCANCODE_t; + keymap[KEY_Y] = SDL_SCANCODE_y; + keymap[KEY_U] = SDL_SCANCODE_u; + keymap[KEY_I] = SDL_SCANCODE_i; + keymap[KEY_O] = SDL_SCANCODE_o; + keymap[KEY_P] = SDL_SCANCODE_p; + keymap[KEY_LEFTBRACE] = SDL_SCANCODE_LEFTBRACKET; + keymap[KEY_RIGHTBRACE] = SDL_SCANCODE_RIGHTBRACKET; + keymap[KEY_ENTER] = SDL_SCANCODE_RETURN; + + keymap[KEY_CAPSLOCK] = SDL_SCANCODE_CAPSLOCK; + keymap[KEY_A] = SDL_SCANCODE_a; + keymap[KEY_S] = SDL_SCANCODE_s; + keymap[KEY_D] = SDL_SCANCODE_d; + keymap[KEY_F] = SDL_SCANCODE_f; + keymap[KEY_G] = SDL_SCANCODE_g; + keymap[KEY_H] = SDL_SCANCODE_h; + keymap[KEY_J] = SDL_SCANCODE_j; + keymap[KEY_K] = SDL_SCANCODE_k; + keymap[KEY_L] = SDL_SCANCODE_l; + keymap[KEY_SEMICOLON] = SDL_SCANCODE_SEMICOLON; + keymap[KEY_APOSTROPHE] = SDL_SCANCODE_APOSTROPHE; + keymap[KEY_BACKSLASH] = SDL_SCANCODE_BACKSLASH; + + keymap[KEY_Z] = SDL_SCANCODE_z; + keymap[KEY_X] = SDL_SCANCODE_x; + keymap[KEY_C] = SDL_SCANCODE_c; + keymap[KEY_V] = SDL_SCANCODE_v; + keymap[KEY_B] = SDL_SCANCODE_b; + keymap[KEY_N] = SDL_SCANCODE_n; + keymap[KEY_M] = SDL_SCANCODE_m; + keymap[KEY_COMMA] = SDL_SCANCODE_COMMA; + keymap[KEY_DOT] = SDL_SCANCODE_PERIOD; + keymap[KEY_SLASH] = SDL_SCANCODE_SLASH; + + keymap[KEY_SPACE] = SDL_SCANCODE_SPACE; + + keymap[KEY_UP] = SDL_SCANCODE_UP; + keymap[KEY_DOWN] = SDL_SCANCODE_DOWN; + keymap[KEY_LEFT] = SDL_SCANCODE_LEFT; + keymap[KEY_RIGHT] = SDL_SCANCODE_RIGHT; + + keymap[KEY_HOME] = SDL_SCANCODE_HOME; + keymap[KEY_END] = SDL_SCANCODE_END; + keymap[KEY_INSERT] = SDL_SCANCODE_INSERT; + keymap[KEY_DELETE] = SDL_SCANCODE_DELETE; + + keymap[KEY_NUMLOCK] = SDL_SCANCODE_NUMLOCK; + keymap[KEY_LEFTMETA] = SDL_SCANCODE_LSUPER; + + keymap[KEY_KPSLASH] = SDL_SCANCODE_KP_DIVIDE; + keymap[KEY_KPASTERISK] = SDL_SCANCODE_KP_MULTIPLY; + keymap[KEY_KPMINUS] = SDL_SCANCODE_KP_MINUS; + keymap[KEY_KPPLUS] = SDL_SCANCODE_KP_PLUS; + keymap[KEY_KPDOT] = SDL_SCANCODE_KP_PERIOD; + keymap[KEY_KPEQUAL] = SDL_SCANCODE_KP_EQUALS; + + keymap[KEY_LEFTCTRL] = SDL_SCANCODE_LCTRL; + keymap[KEY_RIGHTCTRL] = SDL_SCANCODE_RCTRL; + keymap[KEY_LEFTALT] = SDL_SCANCODE_LALT; + keymap[KEY_RIGHTALT] = SDL_SCANCODE_RALT; + keymap[KEY_LEFTSHIFT] = SDL_SCANCODE_LSHIFT; + keymap[KEY_RIGHTSHIFT] = SDL_SCANCODE_RSHIFT; #endif } diff --git a/src/video/vita/SDL_vitavideo.c b/src/video/vita/SDL_vitavideo.c index 480ffd88ad34e..8a3d669f5838d 100644 --- a/src/video/vita/SDL_vitavideo.c +++ b/src/video/vita/SDL_vitavideo.c @@ -380,7 +380,6 @@ SceImeCaret caret_rev; void VITA_ImeEventHandler(void *arg, const SceImeEventData *e) { SDL_VideoData *videodata = (SDL_VideoData *)arg; - SDL_Scancode scancode; uint8_t utf8_buffer[SCE_IME_MAX_TEXT_LENGTH]; switch (e->id) { case SCE_IME_EVENT_UPDATE_TEXT: @@ -388,11 +387,10 @@ void VITA_ImeEventHandler(void *arg, const SceImeEventData *e) SDL_SendKeyboardKeyAutoRelease(0, SDL_SCANCODE_BACKSPACE); sceImeSetText((SceWChar16 *)libime_initval, 4); } else { - scancode = SDL_GetScancodeFromKey(*(SceWChar16 *)&libime_out[1]); - if (scancode == SDL_SCANCODE_SPACE) { + utf16_to_utf8((SceWChar16 *)&libime_out[1], utf8_buffer); + if (utf8_buffer[0] == ' ') { SDL_SendKeyboardKeyAutoRelease(0, SDL_SCANCODE_SPACE); } else { - utf16_to_utf8((SceWChar16 *)&libime_out[1], utf8_buffer); SDL_SendKeyboardText((const char *)utf8_buffer); } SDL_memset(&caret_rev, 0, sizeof(SceImeCaret)); diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c index b7f52154c83a1..72c16ef6b8a62 100644 --- a/src/video/wayland/SDL_waylandevents.c +++ b/src/video/wayland/SDL_waylandevents.c @@ -1107,7 +1107,7 @@ static void Wayland_keymap_iter(struct xkb_keymap *keymap, xkb_keycode_t key, vo /* Note: The default SDL keymap always sets this to right alt instead of AltGr/Mode, so handle it separately. */ if (syms[0] != XKB_KEY_ISO_Level3_Shift) { - keycode = SDL_GetDefaultKeyFromScancode(sc); + keycode = SDL_GetDefaultKeyFromScancode(sc, SDL_KMOD_NONE); } else { keycode = SDLK_MODE; } @@ -1218,13 +1218,13 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, if (input->xkb.current_group != XKB_GROUP_INVALID) { Wayland_Keymap keymap; keymap.layout = input->xkb.current_group; - SDL_GetDefaultKeymap(keymap.keymap); + //SDL_GetDefaultKeymap(keymap.keymap); if (!input->keyboard_is_virtual) { WAYLAND_xkb_keymap_key_for_each(input->xkb.keymap, Wayland_keymap_iter, &keymap); } - SDL_SetKeymap(0, keymap.keymap, SDL_NUM_SCANCODES, SDL_TRUE); + //SDL_SetKeymap(0, keymap.keymap, SDL_NUM_SCANCODES, SDL_TRUE); } /* @@ -1398,7 +1398,7 @@ static void Wayland_ReconcileModifiers(struct SDL_WaylandInput *input) static void Wayland_HandleModifierKeys(struct SDL_WaylandInput *input, SDL_Scancode scancode, SDL_bool pressed) { - const SDL_Keycode keycode = SDL_GetKeyFromScancode(scancode); + const SDL_Keycode keycode = SDL_GetKeyFromScancode(scancode, SDL_KMOD_NONE); SDL_Keymod mod; switch (keycode) { @@ -1475,7 +1475,7 @@ static void keyboard_handle_enter(void *data, struct wl_keyboard *keyboard, wl_array_for_each (key, keys) { const SDL_Scancode scancode = Wayland_get_scancode_from_key(input, *key + 8); - const SDL_Keycode keycode = SDL_GetKeyFromScancode(scancode); + const SDL_Keycode keycode = SDL_GetKeyFromScancode(scancode, SDL_KMOD_NONE); switch (keycode) { case SDLK_LSHIFT: @@ -1677,13 +1677,13 @@ static void keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard, /* The layout changed, remap and fire an event. Virtual keyboards use the default keymap. */ input->xkb.current_group = group; keymap.layout = group; - SDL_GetDefaultKeymap(keymap.keymap); + //SDL_GetDefaultKeymap(keymap.keymap); if (!input->keyboard_is_virtual) { WAYLAND_xkb_keymap_key_for_each(input->xkb.keymap, Wayland_keymap_iter, &keymap); } - SDL_SetKeymap(0, keymap.keymap, SDL_NUM_SCANCODES, SDL_TRUE); + //SDL_SetKeymap(0, keymap.keymap, SDL_NUM_SCANCODES, SDL_TRUE); } static void keyboard_handle_repeat_info(void *data, struct wl_keyboard *wl_keyboard, diff --git a/src/video/windows/SDL_windowskeyboard.c b/src/video/windows/SDL_windowskeyboard.c index feac17db30d99..a2206ea5a8eb9 100644 --- a/src/video/windows/SDL_windowskeyboard.c +++ b/src/video/windows/SDL_windowskeyboard.c @@ -111,57 +111,81 @@ void WIN_InitKeyboard(SDL_VideoDevice *_this) void WIN_UpdateKeymap(SDL_bool send_event) { - int i; SDL_Scancode scancode; - SDL_Keycode keymap[SDL_NUM_SCANCODES]; + SDL_Keymap *keymap; BYTE keyboardState[256] = { 0 }; WCHAR buffer[16]; + SDL_Keymod mods[] = { + SDL_KMOD_NONE, + SDL_KMOD_SHIFT, + SDL_KMOD_CAPS, + (SDL_KMOD_SHIFT | SDL_KMOD_CAPS), + SDL_KMOD_MODE, + (SDL_KMOD_MODE | SDL_KMOD_SHIFT), + (SDL_KMOD_MODE | SDL_KMOD_CAPS), + (SDL_KMOD_MODE | SDL_KMOD_SHIFT | SDL_KMOD_CAPS) + }; - SDL_GetDefaultKeymap(keymap); WIN_ResetDeadKeys(); - for (i = 0; i < SDL_arraysize(windows_scancode_table); i++) { - int vk, sc, result; - Uint32 *ch = 0; + keymap = SDL_CreateKeymap(); - /* Make sure this scancode is a valid character scancode */ - scancode = windows_scancode_table[i]; - if (scancode == SDL_SCANCODE_UNKNOWN) { - continue; - } + for (int m = 0; m < SDL_arraysize(mods); ++m) { + for (int i = 0; i < SDL_arraysize(windows_scancode_table); i++) { + int vk, sc, result; + Uint32 *ch = 0; - /* If this key is one of the non-mappable keys, ignore it */ - /* Uncomment the third part to re-enable the behavior of not mapping the "`"(grave) key to the users actual keyboard layout */ - if ((keymap[scancode] & SDLK_SCANCODE_MASK) || scancode == SDL_SCANCODE_DELETE /*|| scancode == SDL_SCANCODE_GRAVE*/) { - continue; - } + /* Make sure this scancode is a valid character scancode */ + scancode = windows_scancode_table[i]; + if (scancode == SDL_SCANCODE_UNKNOWN || + (SDL_GetDefaultKeyFromScancode(scancode, SDL_KMOD_NONE) & SDLK_SCANCODE_MASK)) { + continue; + } - /* Unpack the single byte index to make the scan code. */ - sc = MAKEWORD(i & 0x7f, (i & 0x80) ? 0xe0 : 0x00); - vk = LOBYTE(MapVirtualKey(sc, MAPVK_VSC_TO_VK)); - if (!vk) { - continue; - } + /* If this key is one of the non-mappable keys, ignore it */ + /* Uncomment the second part to re-enable the behavior of not mapping the "`"(grave) key to the users actual keyboard layout */ + if (scancode == SDL_SCANCODE_DELETE /*|| scancode == SDL_SCANCODE_GRAVE*/) { + continue; + } - result = ToUnicode(vk, sc, keyboardState, buffer, 16, 0); - buffer[SDL_abs(result)] = 0; - - /* Convert UTF-16 to UTF-32 code points */ - ch = (Uint32 *)SDL_iconv_string("UTF-32LE", "UTF-16LE", (const char *)buffer, (SDL_abs(result) + 1) * sizeof(WCHAR)); - if (ch) { - /* Windows keyboard layouts can emit several UTF-32 code points on a single key press. - * Use since we cannot fit into single SDL_Keycode value in SDL keymap. - * See https://kbdlayout.info/features/ligatures for a list of such keys. */ - keymap[scancode] = ch[1] == 0 ? ch[0] : 0xfffd; - SDL_free(ch); - } + /* Unpack the single byte index to make the scan code. */ + sc = MAKEWORD(i & 0x7f, (i & 0x80) ? 0xe0 : 0x00); + vk = LOBYTE(MapVirtualKey(sc, MAPVK_VSC_TO_VK)); + if (!vk) { + continue; + } + + // Update the keyboard state for the modifiers + keyboardState[VK_SHIFT] = (mods[m] & SDL_KMOD_SHIFT) ? 0x80 : 0x00; + keyboardState[VK_CAPITAL] = (mods[m] & SDL_KMOD_CAPS) ? 0x01 : 0x00; + keyboardState[VK_CONTROL] = (mods[m] & SDL_KMOD_MODE) ? 0x80 : 0x00; + keyboardState[VK_MENU] = (mods[m] & SDL_KMOD_MODE) ? 0x80 : 0x00; + + result = ToUnicode(vk, sc, keyboardState, buffer, 16, 0); + buffer[SDL_abs(result)] = 0; + + /* Convert UTF-16 to UTF-32 code points */ + ch = (Uint32 *)SDL_iconv_string("UTF-32LE", "UTF-16LE", (const char *)buffer, (SDL_abs(result) + 1) * sizeof(WCHAR)); + if (ch) { + /* Windows keyboard layouts can emit several UTF-32 code points on a single key press. + * Use since we cannot fit into single SDL_Keycode value in SDL keymap. + * See https://kbdlayout.info/features/ligatures for a list of such keys. */ + SDL_SetKeymapEntry(keymap, scancode, mods[m], ch[1] == 0 ? ch[0] : 0xfffd); + SDL_free(ch); + } else { + // The default keymap doesn't have any SDL_KMOD_MODE entries, so we don't need to override them + if (!(mods[m] & SDL_KMOD_MODE)) { + SDL_SetKeymapEntry(keymap, scancode, mods[m], SDLK_UNKNOWN); + } + } - if (result < 0) { - WIN_ResetDeadKeys(); + if (result < 0) { + WIN_ResetDeadKeys(); + } } } - SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES, send_event); + SDL_SetKeymap(keymap, send_event); } void WIN_QuitKeyboard(SDL_VideoDevice *_this) diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c index cc0164ae51362..b594cb598c4ae 100644 --- a/src/video/x11/SDL_x11events.c +++ b/src/video/x11/SDL_x11events.c @@ -428,7 +428,7 @@ void X11_ReconcileKeyboardState(SDL_VideoDevice *_this) if (x11KeyPressed && !sdlKeyPressed) { /* Only update modifier state for keys that are pressed in another application */ - switch (SDL_GetKeyFromScancode(scancode)) { + switch (SDL_GetKeyFromScancode(scancode, SDL_KMOD_NONE)) { case SDLK_LCTRL: case SDLK_RCTRL: case SDLK_LSHIFT: diff --git a/src/video/x11/SDL_x11keyboard.c b/src/video/x11/SDL_x11keyboard.c index 6f4851f568b10..ec0ba922361a5 100644 --- a/src/video/x11/SDL_x11keyboard.c +++ b/src/video/x11/SDL_x11keyboard.c @@ -274,7 +274,7 @@ int X11_InitKeyboard(SDL_VideoDevice *_this) However, there are a number of extended scancodes that have no standard location, so use the X11 mapping for all non-character keys. */ - SDL_GetDefaultKeymap(default_keymap); + //SDL_GetDefaultKeymap(default_keymap); for (i = min_keycode; i <= max_keycode; ++i) { SDL_Scancode scancode = X11_KeyCodeToSDLScancode(_this, i); @@ -343,7 +343,7 @@ void X11_UpdateKeymap(SDL_VideoDevice *_this, SDL_bool send_event) SDL_Keycode keymap[SDL_NUM_SCANCODES]; unsigned char group = 0; - SDL_GetDefaultKeymap(keymap); + //SDL_GetDefaultKeymap(keymap); #ifdef SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM if (data->xkb) { @@ -394,7 +394,7 @@ void X11_UpdateKeymap(SDL_VideoDevice *_this, SDL_bool send_event) } } } - SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES, send_event); + //SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES, send_event); } void X11_QuitKeyboard(SDL_VideoDevice *_this) diff --git a/test/checkkeys.c b/test/checkkeys.c index f89a91c86cfcc..bf29a71b7bd31 100644 --- a/test/checkkeys.c +++ b/test/checkkeys.c @@ -27,8 +27,7 @@ static SDLTest_CommonState *state; static SDLTest_TextWindow *textwin; static int done; -static void -print_string(char **text, size_t *maxlen, const char *fmt, ...) +static void print_string(char **text, size_t *maxlen, const char *fmt, ...) { int len; va_list ap; @@ -46,39 +45,52 @@ print_string(char **text, size_t *maxlen, const char *fmt, ...) va_end(ap); } -static void -print_modifiers(char **text, size_t *maxlen) +static void print_modifiers(char **text, size_t *maxlen, SDL_Keymod mod) { - int mod; print_string(text, maxlen, " modifiers:"); - mod = SDL_GetModState(); - if (!mod) { + if (mod == SDL_KMOD_NONE) { print_string(text, maxlen, " (none)"); return; } - if (mod & SDL_KMOD_LSHIFT) { - print_string(text, maxlen, " LSHIFT"); - } - if (mod & SDL_KMOD_RSHIFT) { - print_string(text, maxlen, " RSHIFT"); - } - if (mod & SDL_KMOD_LCTRL) { - print_string(text, maxlen, " LCTRL"); - } - if (mod & SDL_KMOD_RCTRL) { - print_string(text, maxlen, " RCTRL"); - } - if (mod & SDL_KMOD_LALT) { - print_string(text, maxlen, " LALT"); + if ((mod & SDL_KMOD_SHIFT) == SDL_KMOD_SHIFT) { + print_string(text, maxlen, " SHIFT"); + } else { + if (mod & SDL_KMOD_LSHIFT) { + print_string(text, maxlen, " LSHIFT"); + } + if (mod & SDL_KMOD_RSHIFT) { + print_string(text, maxlen, " RSHIFT"); + } } - if (mod & SDL_KMOD_RALT) { - print_string(text, maxlen, " RALT"); + if ((mod & SDL_KMOD_CTRL) == SDL_KMOD_CTRL) { + print_string(text, maxlen, " CTRL"); + } else { + if (mod & SDL_KMOD_LCTRL) { + print_string(text, maxlen, " LCTRL"); + } + if (mod & SDL_KMOD_RCTRL) { + print_string(text, maxlen, " RCTRL"); + } } - if (mod & SDL_KMOD_LGUI) { - print_string(text, maxlen, " LGUI"); + if ((mod & SDL_KMOD_ALT) == SDL_KMOD_ALT) { + print_string(text, maxlen, " ALT"); + } else { + if (mod & SDL_KMOD_LALT) { + print_string(text, maxlen, " LALT"); + } + if (mod & SDL_KMOD_RALT) { + print_string(text, maxlen, " RALT"); + } } - if (mod & SDL_KMOD_RGUI) { - print_string(text, maxlen, " RGUI"); + if ((mod & SDL_KMOD_GUI) == SDL_KMOD_GUI) { + print_string(text, maxlen, " GUI"); + } else { + if (mod & SDL_KMOD_LGUI) { + print_string(text, maxlen, " LGUI"); + } + if (mod & SDL_KMOD_RGUI) { + print_string(text, maxlen, " RGUI"); + } } if (mod & SDL_KMOD_NUM) { print_string(text, maxlen, " NUM"); @@ -94,8 +106,47 @@ print_modifiers(char **text, size_t *maxlen) } } -static void -PrintModifierState(void) +static void PrintKeymap(void) +{ + SDL_Keymod mods[] = { + SDL_KMOD_NONE, + SDL_KMOD_SHIFT, + SDL_KMOD_CAPS, + (SDL_KMOD_SHIFT | SDL_KMOD_CAPS), + SDL_KMOD_ALT, + (SDL_KMOD_ALT | SDL_KMOD_SHIFT), + (SDL_KMOD_ALT | SDL_KMOD_CAPS), + (SDL_KMOD_ALT | SDL_KMOD_SHIFT | SDL_KMOD_CAPS), + SDL_KMOD_MODE, + (SDL_KMOD_MODE | SDL_KMOD_SHIFT), + (SDL_KMOD_MODE | SDL_KMOD_CAPS), + (SDL_KMOD_MODE | SDL_KMOD_SHIFT | SDL_KMOD_CAPS) + }; + int i, m; + + SDL_Log("Differences from the default keymap:\n"); + for (m = 0; m < SDL_arraysize(mods); ++m) { + for (i = 0; i < SDL_NUM_SCANCODES; ++i) { + SDL_Keycode key = SDL_GetKeyFromScancode((SDL_Scancode)i, mods[m]); + SDL_Keycode default_key = SDL_GetDefaultKeyFromScancode((SDL_Scancode)i, mods[m]); + if (key != default_key) { + char message[512]; + char *spot; + size_t left; + + spot = message; + left = sizeof(message); + + print_string(&spot, &left, "Scancode %s", SDL_GetScancodeName((SDL_Scancode)i)); + print_modifiers(&spot, &left, mods[m]); + print_string(&spot, &left, ": %s 0x%x (default: %s 0x%x)", SDL_GetKeyName(key), key, SDL_GetKeyName(default_key), default_key); + SDL_Log("%s", message); + } + } + } +} + +static void PrintModifierState(void) { char message[512]; char *spot; @@ -104,12 +155,11 @@ PrintModifierState(void) spot = message; left = sizeof(message); - print_modifiers(&spot, &left); + print_modifiers(&spot, &left, SDL_GetModState()); SDL_Log("Initial state:%s\n", message); } -static void -PrintKey(SDL_Keysym *sym, SDL_bool pressed, SDL_bool repeat) +static void PrintKey(SDL_Keysym *sym, SDL_bool pressed, SDL_bool repeat) { char message[512]; char *spot; @@ -135,15 +185,14 @@ PrintKey(SDL_Keysym *sym, SDL_bool pressed, SDL_bool repeat) sym->scancode == SDL_SCANCODE_UNKNOWN ? "UNKNOWN" : SDL_GetScancodeName(sym->scancode), pressed ? "pressed " : "released"); } - print_modifiers(&spot, &left); + print_modifiers(&spot, &left, sym->mod); if (repeat) { print_string(&spot, &left, " (repeat)"); } SDL_Log("%s\n", message); } -static void -PrintText(const char *eventtype, const char *text) +static void PrintText(const char *eventtype, const char *text) { const char *spot; char expanded[1024]; @@ -225,6 +274,10 @@ static void loop(void) } } break; + case SDL_EVENT_KEYMAP_CHANGED: + SDL_Log("Keymap changed!\n"); + PrintKeymap(); + break; case SDL_EVENT_QUIT: done = 1; break; @@ -296,8 +349,9 @@ int main(int argc, char *argv[]) SDL_StartTextInput(); - /* Print initial modifier state */ + /* Print initial state */ SDL_PumpEvents(); + PrintKeymap(); PrintModifierState(); /* Watch keystrokes */ diff --git a/test/testautomation_keyboard.c b/test/testautomation_keyboard.c index 207115ad7a190..4652fb1b5a2da 100644 --- a/test/testautomation_keyboard.c +++ b/test/testautomation_keyboard.c @@ -124,12 +124,12 @@ static int keyboard_getKeyFromScancode(void *arg) SDL_Keycode result; /* Case where input is valid */ - result = SDL_GetKeyFromScancode(SDL_SCANCODE_A); + result = SDL_GetKeyFromScancode(SDL_SCANCODE_A, SDL_KMOD_NONE); SDLTest_AssertPass("Call to SDL_GetKeyFromScancode(valid)"); SDLTest_AssertCheck(result == SDLK_a, "Verify result from call, expected: %d, got: %" SDL_PRIs32, SDLK_a, result); /* Case where input is zero */ - result = SDL_GetKeyFromScancode(0); + result = SDL_GetKeyFromScancode(SDL_SCANCODE_UNKNOWN, SDL_KMOD_NONE); SDLTest_AssertPass("Call to SDL_GetKeyFromScancode(0)"); SDLTest_AssertCheck(result == SDLK_UNKNOWN, "Verify result from call is UNKNOWN, expected: %d, got: %" SDL_PRIs32, SDLK_UNKNOWN, result); @@ -138,13 +138,13 @@ static int keyboard_getKeyFromScancode(void *arg) SDLTest_AssertPass("Call to SDL_ClearError()"); /* Case where input is invalid (too small) */ - result = SDL_GetKeyFromScancode(-999); + result = SDL_GetKeyFromScancode((SDL_Scancode)-999, SDL_KMOD_NONE); SDLTest_AssertPass("Call to SDL_GetKeyFromScancode(-999)"); SDLTest_AssertCheck(result == SDLK_UNKNOWN, "Verify result from call is UNKNOWN, expected: %d, got: %" SDL_PRIs32, SDLK_UNKNOWN, result); checkInvalidScancodeError(); /* Case where input is invalid (too big) */ - result = SDL_GetKeyFromScancode(999); + result = SDL_GetKeyFromScancode((SDL_Scancode)999, SDL_KMOD_NONE); SDLTest_AssertPass("Call to SDL_GetKeyFromScancode(999)"); SDLTest_AssertCheck(result == SDLK_UNKNOWN, "Verify result from call is UNKNOWN, expected: %d, got: %" SDL_PRIs32, SDLK_UNKNOWN, result); checkInvalidScancodeError(); @@ -501,12 +501,12 @@ static int keyboard_getScancodeFromKey(void *arg) SDL_Scancode scancode; /* Regular key */ - scancode = SDL_GetScancodeFromKey(SDLK_4); + scancode = SDL_GetScancodeFromKey(SDLK_4, NULL); SDLTest_AssertPass("Call to SDL_GetScancodeFromKey(SDLK_4)"); SDLTest_AssertCheck(scancode == SDL_SCANCODE_4, "Validate return value from SDL_GetScancodeFromKey, expected: %d, got: %d", SDL_SCANCODE_4, scancode); /* Virtual key */ - scancode = SDL_GetScancodeFromKey(SDLK_PLUS); + scancode = SDL_GetScancodeFromKey(SDLK_PLUS, NULL); SDLTest_AssertPass("Call to SDL_GetScancodeFromKey(SDLK_PLUS)"); SDLTest_AssertCheck(scancode == 0, "Validate return value from SDL_GetScancodeFromKey, expected: 0, got: %d", scancode);