diff --git a/src/events/SDL_keyboard.c b/src/events/SDL_keyboard.c index 4551ac755f..59aba36670 100644 --- a/src/events/SDL_keyboard.c +++ b/src/events/SDL_keyboard.c @@ -44,12 +44,6 @@ #define KEYCODE_OPTION_LATIN_LETTERS 0x04 #define DEFAULT_KEYCODE_OPTIONS (KEYCODE_OPTION_FRENCH_NUMBERS | KEYCODE_OPTION_LATIN_LETTERS) -typedef struct SDL_KeyboardInstance -{ - SDL_KeyboardID instance_id; - char *name; -} SDL_KeyboardInstance; - typedef struct SDL_Keyboard { // Data common to all keyboards @@ -65,7 +59,8 @@ typedef struct SDL_Keyboard static SDL_Keyboard SDL_keyboard; static int SDL_keyboard_count; -static SDL_KeyboardInstance *SDL_keyboards; +static SDL_KeyboardID *SDL_keyboards; +static SDL_HashTable *SDL_keyboard_names; static bool SDL_keyboard_quitting; static void SDLCALL SDL_KeycodeOptionsChanged(void *userdata, const char *name, const char *oldValue, const char *hint) @@ -95,6 +90,9 @@ bool SDL_InitKeyboard(void) { SDL_AddHintCallback(SDL_HINT_KEYCODE_OPTIONS, SDL_KeycodeOptionsChanged, &SDL_keyboard); + + SDL_keyboard_names = SDL_CreateHashTable(0, true, SDL_HashID, SDL_KeyMatchID, SDL_DestroyHashValue, NULL); + return true; } @@ -112,7 +110,7 @@ bool SDL_IsKeyboard(Uint16 vendor, Uint16 product, int num_keys) static int SDL_GetKeyboardIndex(SDL_KeyboardID keyboardID) { for (int i = 0; i < SDL_keyboard_count; ++i) { - if (keyboardID == SDL_keyboards[i].instance_id) { + if (keyboardID == SDL_keyboards[i]) { return i; } } @@ -129,16 +127,19 @@ void SDL_AddKeyboard(SDL_KeyboardID keyboardID, const char *name) SDL_assert(keyboardID != 0); - SDL_KeyboardInstance *keyboards = (SDL_KeyboardInstance *)SDL_realloc(SDL_keyboards, (SDL_keyboard_count + 1) * sizeof(*keyboards)); + SDL_KeyboardID *keyboards = (SDL_KeyboardID *)SDL_realloc(SDL_keyboards, (SDL_keyboard_count + 1) * sizeof(*keyboards)); if (!keyboards) { return; } - SDL_KeyboardInstance *instance = &keyboards[SDL_keyboard_count]; - instance->instance_id = keyboardID; - instance->name = SDL_strdup(name ? name : ""); + keyboards[SDL_keyboard_count] = keyboardID; SDL_keyboards = keyboards; ++SDL_keyboard_count; + if (!name) { + name = "Keyboard"; + } + SDL_InsertIntoHashTable(SDL_keyboard_names, (const void *)(uintptr_t)keyboardID, SDL_strdup(name), true); + SDL_Event event; SDL_zero(event); event.type = SDL_EVENT_KEYBOARD_ADDED; @@ -154,8 +155,6 @@ void SDL_RemoveKeyboard(SDL_KeyboardID keyboardID) return; } - SDL_free(SDL_keyboards[keyboard_index].name); - if (keyboard_index != SDL_keyboard_count - 1) { SDL_memmove(&SDL_keyboards[keyboard_index], &SDL_keyboards[keyboard_index + 1], (SDL_keyboard_count - keyboard_index - 1) * sizeof(SDL_keyboards[keyboard_index])); } @@ -187,7 +186,7 @@ SDL_KeyboardID *SDL_GetKeyboards(int *count) } for (i = 0; i < SDL_keyboard_count; ++i) { - keyboards[i] = SDL_keyboards[i].instance_id; + keyboards[i] = SDL_keyboards[i]; } keyboards[i] = 0; } else { @@ -201,12 +200,17 @@ SDL_KeyboardID *SDL_GetKeyboards(int *count) const char *SDL_GetKeyboardNameForID(SDL_KeyboardID instance_id) { - int keyboard_index = SDL_GetKeyboardIndex(instance_id); - if (keyboard_index < 0) { + const char *name = NULL; + if (!SDL_FindInHashTable(SDL_keyboard_names, (const void *)(uintptr_t)instance_id, (const void **)&name)) { SDL_SetError("Keyboard %" SDL_PRIu32 " not found", instance_id); return NULL; } - return SDL_GetPersistentString(SDL_keyboards[keyboard_index].name); + if (!name) { + // SDL_strdup() failed during insert + SDL_OutOfMemory(); + return NULL; + } + return name; } void SDL_ResetKeyboard(void) @@ -871,11 +875,14 @@ void SDL_QuitKeyboard(void) SDL_keyboard_quitting = true; for (int i = SDL_keyboard_count; i--;) { - SDL_RemoveKeyboard(SDL_keyboards[i].instance_id); + SDL_RemoveKeyboard(SDL_keyboards[i]); } SDL_free(SDL_keyboards); SDL_keyboards = NULL; + SDL_DestroyHashTable(SDL_keyboard_names); + SDL_keyboard_names = NULL; + if (SDL_keyboard.keymap && SDL_keyboard.keymap->auto_release) { SDL_DestroyKeymap(SDL_keyboard.keymap); SDL_keyboard.keymap = NULL; diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c index 93240803ae..23f8017449 100644 --- a/src/events/SDL_mouse.c +++ b/src/events/SDL_mouse.c @@ -34,16 +34,11 @@ #define WARP_EMULATION_THRESHOLD_NS SDL_MS_TO_NS(30) -typedef struct SDL_MouseInstance -{ - SDL_MouseID instance_id; - char *name; -} SDL_MouseInstance; - // The mouse state static SDL_Mouse SDL_mouse; static int SDL_mouse_count; -static SDL_MouseInstance *SDL_mice; +static SDL_MouseID *SDL_mice; +static SDL_HashTable *SDL_mouse_names; static bool SDL_mouse_quitting; // for mapping mouse events to touch @@ -311,6 +306,8 @@ bool SDL_PreInitMouse(void) mouse->cursor_visible = true; + SDL_mouse_names = SDL_CreateHashTable(0, true, SDL_HashID, SDL_KeyMatchID, SDL_DestroyHashValue, NULL); + return true; } @@ -340,7 +337,7 @@ bool SDL_IsMouse(Uint16 vendor, Uint16 product) static int SDL_GetMouseIndex(SDL_MouseID mouseID) { for (int i = 0; i < SDL_mouse_count; ++i) { - if (mouseID == SDL_mice[i].instance_id) { + if (mouseID == SDL_mice[i]) { return i; } } @@ -357,16 +354,19 @@ void SDL_AddMouse(SDL_MouseID mouseID, const char *name) SDL_assert(mouseID != 0); - SDL_MouseInstance *mice = (SDL_MouseInstance *)SDL_realloc(SDL_mice, (SDL_mouse_count + 1) * sizeof(*mice)); + SDL_MouseID *mice = (SDL_MouseID *)SDL_realloc(SDL_mice, (SDL_mouse_count + 1) * sizeof(*mice)); if (!mice) { return; } - SDL_MouseInstance *instance = &mice[SDL_mouse_count]; - instance->instance_id = mouseID; - instance->name = SDL_strdup(name ? name : ""); + mice[SDL_mouse_count] = mouseID; SDL_mice = mice; ++SDL_mouse_count; + if (!name) { + name = "Mouse"; + } + SDL_InsertIntoHashTable(SDL_mouse_names, (const void *)(uintptr_t)mouseID, SDL_strdup(name), true); + SDL_Event event; SDL_zero(event); event.type = SDL_EVENT_MOUSE_ADDED; @@ -382,8 +382,6 @@ void SDL_RemoveMouse(SDL_MouseID mouseID) return; } - SDL_free(SDL_mice[mouse_index].name); - if (mouse_index != SDL_mouse_count - 1) { SDL_memmove(&SDL_mice[mouse_index], &SDL_mice[mouse_index + 1], (SDL_mouse_count - mouse_index - 1) * sizeof(SDL_mice[mouse_index])); } @@ -429,7 +427,7 @@ SDL_MouseID *SDL_GetMice(int *count) } for (i = 0; i < SDL_mouse_count; ++i) { - mice[i] = SDL_mice[i].instance_id; + mice[i] = SDL_mice[i]; } mice[i] = 0; } else { @@ -443,12 +441,17 @@ SDL_MouseID *SDL_GetMice(int *count) const char *SDL_GetMouseNameForID(SDL_MouseID instance_id) { - int mouse_index = SDL_GetMouseIndex(instance_id); - if (mouse_index < 0) { + const char *name = NULL; + if (!SDL_FindInHashTable(SDL_mouse_names, (const void *)(uintptr_t)instance_id, (const void **)&name)) { SDL_SetError("Mouse %" SDL_PRIu32 " not found", instance_id); return NULL; } - return SDL_GetPersistentString(SDL_mice[mouse_index].name); + if (!name) { + // SDL_strdup() failed during insert + SDL_OutOfMemory(); + return NULL; + } + return name; } void SDL_SetDefaultCursor(SDL_Cursor *cursor) @@ -1165,11 +1168,14 @@ void SDL_QuitMouse(void) SDL_MouseIntegerModeChanged, mouse); for (int i = SDL_mouse_count; i--; ) { - SDL_RemoveMouse(SDL_mice[i].instance_id); + SDL_RemoveMouse(SDL_mice[i]); } SDL_free(SDL_mice); SDL_mice = NULL; + SDL_DestroyHashTable(SDL_mouse_names); + SDL_mouse_names = NULL; + if (mouse->internal) { SDL_free(mouse->internal); mouse->internal = NULL; diff --git a/src/test/SDL_test_common.c b/src/test/SDL_test_common.c index 5f1ab6b920..bffa61527c 100644 --- a/src/test/SDL_test_common.c +++ b/src/test/SDL_test_common.c @@ -1733,12 +1733,12 @@ void SDLTest_PrintEvent(const SDL_Event *event) SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " HDR %s", event->window.windowID, event->window.data1 ? "enabled" : "disabled"); break; case SDL_EVENT_KEYBOARD_ADDED: - SDL_Log("SDL EVENT: Keyboard %" SDL_PRIu32 " attached", - event->kdevice.which); + SDL_Log("SDL EVENT: Keyboard %" SDL_PRIu32 " (%s) attached", + event->kdevice.which, SDL_GetKeyboardNameForID(event->kdevice.which)); break; case SDL_EVENT_KEYBOARD_REMOVED: - SDL_Log("SDL EVENT: Keyboard %" SDL_PRIu32 " removed", - event->kdevice.which); + SDL_Log("SDL EVENT: Keyboard %" SDL_PRIu32 " (%s) removed", + event->kdevice.which, SDL_GetKeyboardNameForID(event->kdevice.which)); break; case SDL_EVENT_KEY_DOWN: case SDL_EVENT_KEY_UP: { @@ -1775,12 +1775,12 @@ void SDLTest_PrintEvent(const SDL_Event *event) SDL_Log("SDL EVENT: Keymap changed"); break; case SDL_EVENT_MOUSE_ADDED: - SDL_Log("SDL EVENT: Mouse %" SDL_PRIu32 " attached", - event->mdevice.which); + SDL_Log("SDL EVENT: Mouse %" SDL_PRIu32 " (%s) attached", + event->mdevice.which, SDL_GetMouseNameForID(event->mdevice.which)); break; case SDL_EVENT_MOUSE_REMOVED: - SDL_Log("SDL EVENT: Mouse %" SDL_PRIu32 " removed", - event->mdevice.which); + SDL_Log("SDL EVENT: Mouse %" SDL_PRIu32 " (%s) removed", + event->mdevice.which, SDL_GetMouseNameForID(event->mdevice.which)); break; case SDL_EVENT_MOUSE_MOTION: SDL_Log("SDL EVENT: Mouse: moved to %g,%g (%g,%g) in window %" SDL_PRIu32,