From c0f456555287623b935ab553404f0391b26389c4 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 22 Mar 2024 09:17:17 -0700 Subject: [PATCH] Added SDL_GetKeyboardName() and SDL_GetMouseName() --- include/SDL3/SDL_joystick.h | 20 ++-- include/SDL3/SDL_keyboard.h | 15 +++ include/SDL3/SDL_mouse.h | 15 +++ src/core/linux/SDL_evdev.c | 18 +++- src/core/openbsd/SDL_wscons_kbd.c | 2 +- src/core/openbsd/SDL_wscons_mouse.c | 2 +- src/dynapi/SDL_dynapi.sym | 2 + src/dynapi/SDL_dynapi_overrides.h | 2 + src/dynapi/SDL_dynapi_procs.h | 2 + src/events/SDL_keyboard.c | 61 ++++++------ src/events/SDL_keyboard_c.h | 2 +- src/events/SDL_mouse.c | 56 ++++++----- src/events/SDL_mouse_c.h | 2 +- src/video/cocoa/SDL_cocoavideo.m | 4 +- src/video/emscripten/SDL_emscriptenvideo.c | 4 +- src/video/haiku/SDL_bvideo.cc | 4 +- src/video/qnx/SDL_qnxvideo.c | 4 +- src/video/riscos/SDL_riscosvideo.c | 4 +- src/video/uikit/SDL_uikitevents.m | 4 +- src/video/vita/SDL_vitakeyboard.c | 2 +- src/video/vita/SDL_vitamouse.c | 2 +- src/video/wayland/SDL_waylandevents.c | 4 +- src/video/windows/SDL_windowsevents.c | 102 ++++++++++++++++----- src/video/winrt/SDL_winrtvideo.cpp | 4 +- src/video/x11/SDL_x11video.c | 4 +- src/video/x11/SDL_x11xinput2.c | 8 +- 26 files changed, 239 insertions(+), 110 deletions(-) diff --git a/include/SDL3/SDL_joystick.h b/include/SDL3/SDL_joystick.h index 4708aa7ba..44857c974 100644 --- a/include/SDL3/SDL_joystick.h +++ b/include/SDL3/SDL_joystick.h @@ -216,8 +216,8 @@ extern DECLSPEC int SDLCALL SDL_GetJoystickInstancePlayerIndex(SDL_JoystickID in * This can be called before any joysticks are opened. * * \param instance_id the joystick instance ID - * \returns the GUID of the selected joystick. If called on an invalid index, - * this function returns a zero GUID + * \returns the GUID of the selected joystick. If called with an invalid instance_id, + * this function returns a zero GUID. * * \since This function is available since SDL 3.0.0. * @@ -233,8 +233,8 @@ extern DECLSPEC SDL_JoystickGUID SDLCALL SDL_GetJoystickInstanceGUID(SDL_Joystic * available this function returns 0. * * \param instance_id the joystick instance ID - * \returns the USB vendor ID of the selected joystick. If called on an - * invalid index, this function returns zero + * \returns the USB vendor ID of the selected joystick. If called with an + * invalid instance_id, this function returns 0. * * \since This function is available since SDL 3.0.0. * @@ -250,8 +250,8 @@ extern DECLSPEC Uint16 SDLCALL SDL_GetJoystickInstanceVendor(SDL_JoystickID inst * available this function returns 0. * * \param instance_id the joystick instance ID - * \returns the USB product ID of the selected joystick. If called on an - * invalid index, this function returns zero + * \returns the USB product ID of the selected joystick. If called with an + * invalid instance_id, this function returns 0. * * \since This function is available since SDL 3.0.0. * @@ -267,8 +267,8 @@ extern DECLSPEC Uint16 SDLCALL SDL_GetJoystickInstanceProduct(SDL_JoystickID ins * isn't available this function returns 0. * * \param instance_id the joystick instance ID - * \returns the product version of the selected joystick. If called on an - * invalid index, this function returns zero + * \returns the product version of the selected joystick. If called with an + * invalid instance_id, this function returns 0. * * \since This function is available since SDL 3.0.0. * @@ -283,8 +283,8 @@ extern DECLSPEC Uint16 SDLCALL SDL_GetJoystickInstanceProductVersion(SDL_Joystic * This can be called before any joysticks are opened. * * \param instance_id the joystick instance ID - * \returns the SDL_JoystickType of the selected joystick. If called on an - * invalid index, this function returns `SDL_JOYSTICK_TYPE_UNKNOWN` + * \returns the SDL_JoystickType of the selected joystick. If called with an + * invalid instance_id, this function returns `SDL_JOYSTICK_TYPE_UNKNOWN`. * * \since This function is available since SDL 3.0.0. * diff --git a/include/SDL3/SDL_keyboard.h b/include/SDL3/SDL_keyboard.h index d2a8b1cfb..84e840983 100644 --- a/include/SDL3/SDL_keyboard.h +++ b/include/SDL3/SDL_keyboard.h @@ -77,10 +77,25 @@ extern DECLSPEC SDL_bool SDLCALL SDL_HasKeyboard(void); * * \since This function is available since SDL 3.0.0. * + * \sa SDL_GetKeyboardInstanceName * \sa SDL_HasKeyboard */ extern DECLSPEC SDL_KeyboardID *SDLCALL SDL_GetKeyboards(int *count); +/** + * Get the name of a keyboard. + * + * This function returns "" if the keyboard doesn't have a name. + * + * \param instance_id the keyboard instance ID + * \returns the name of the selected keyboard, or NULL on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_GetKeyboards + */ +extern DECLSPEC const char *SDLCALL SDL_GetKeyboardInstanceName(SDL_KeyboardID instance_id); + /** * Query the window which currently has keyboard focus. * diff --git a/include/SDL3/SDL_mouse.h b/include/SDL3/SDL_mouse.h index da1eb3b90..0c97fc1a5 100644 --- a/include/SDL3/SDL_mouse.h +++ b/include/SDL3/SDL_mouse.h @@ -102,10 +102,25 @@ extern DECLSPEC SDL_bool SDLCALL SDL_HasMouse(void); * * \since This function is available since SDL 3.0.0. * + * \sa SDL_GetMouseInstanceName * \sa SDL_HasMouse */ extern DECLSPEC SDL_MouseID *SDLCALL SDL_GetMice(int *count); +/** + * Get the name of a mouse. + * + * This function returns "" if the mouse doesn't have a name. + * + * \param instance_id the mouse instance ID + * \returns the name of the selected mouse, or NULL on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_GetMice + */ +extern DECLSPEC const char *SDLCALL SDL_GetMouseInstanceName(SDL_MouseID instance_id); + /** * Get the window which currently has mouse focus. * diff --git a/src/core/linux/SDL_evdev.c b/src/core/linux/SDL_evdev.c index fa9b14131..b39630d92 100644 --- a/src/core/linux/SDL_evdev.c +++ b/src/core/linux/SDL_evdev.c @@ -607,17 +607,22 @@ static SDL_Scancode SDL_EVDEV_translate_keycode(int keycode) static int SDL_EVDEV_init_keyboard(SDL_evdevlist_item *item, int udev_class) { - SDL_AddKeyboard((SDL_KeyboardID)item->fd, SDL_TRUE); + SDL_AddKeyboard((SDL_KeyboardID)item->fd, NULL, SDL_TRUE); return 0; } +static void SDL_EVDEV_destroy_keyboard(SDL_evdevlist_item *item) +{ + SDL_RemoveKeyboard((SDL_KeyboardID)item->fd); +} + static int SDL_EVDEV_init_mouse(SDL_evdevlist_item *item, int udev_class) { int ret; struct input_absinfo abs_info; - SDL_AddMouse((SDL_MouseID)item->fd, SDL_TRUE); + SDL_AddMouse((SDL_MouseID)item->fd, NULL, SDL_TRUE); ret = ioctl(item->fd, EVIOCGABS(ABS_X), &abs_info); if (ret < 0) { @@ -640,6 +645,11 @@ static int SDL_EVDEV_init_mouse(SDL_evdevlist_item *item, int udev_class) return 0; } +static void SDL_EVDEV_destroy_mouse(SDL_evdevlist_item *item) +{ + SDL_RemoveMouse((SDL_MouseID)item->fd); +} + static int SDL_EVDEV_init_touchscreen(SDL_evdevlist_item *item, int udev_class) { int ret; @@ -974,6 +984,10 @@ static int SDL_EVDEV_device_removed(const char *dev_path) } if (item->is_touchscreen) { SDL_EVDEV_destroy_touchscreen(item); + } else if (item->udev_class & SDL_UDEV_DEVICE_MOUSE) { + SDL_EVDEV_destroy_mouse(item); + } else if (item->udev_class & SDL_UDEV_DEVICE_KEYBOARD) { + SDL_EVDEV_destroy_keyboard(item); } close(item->fd); SDL_free(item->path); diff --git a/src/core/openbsd/SDL_wscons_kbd.c b/src/core/openbsd/SDL_wscons_kbd.c index 541ad2cbe..81f94448c 100644 --- a/src/core/openbsd/SDL_wscons_kbd.c +++ b/src/core/openbsd/SDL_wscons_kbd.c @@ -433,7 +433,7 @@ static SDL_WSCONS_input_data *SDL_WSCONS_Init_Keyboard(const char *dev) } input->keyboardID = SDL_GetNextObjectID(); - SDL_AddKeyboard(input->keyboardID, SDL_FALSE); + SDL_AddKeyboard(input->keyboardID, NULL, SDL_FALSE); input->keymap.map = SDL_calloc(sizeof(struct wscons_keymap), KS_NUMKEYCODES); if (!input->keymap.map) { diff --git a/src/core/openbsd/SDL_wscons_mouse.c b/src/core/openbsd/SDL_wscons_mouse.c index 435de1e09..6b0c96261 100644 --- a/src/core/openbsd/SDL_wscons_mouse.c +++ b/src/core/openbsd/SDL_wscons_mouse.c @@ -52,7 +52,7 @@ SDL_WSCONS_mouse_input_data *SDL_WSCONS_Init_Mouse() } input->mouseID = SDL_GetNextObjectID(); - SDL_AddMouse(input->mouseID, SDL_FALSE); + SDL_AddMouse(input->mouseID, NULL, SDL_FALSE); #ifdef WSMOUSEIO_SETMODE ioctl(input->fd, WSMOUSEIO_SETMODE, WSMOUSE_COMPAT); diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym index be498a820..5d065e4a5 100644 --- a/src/dynapi/SDL_dynapi.sym +++ b/src/dynapi/SDL_dynapi.sym @@ -319,6 +319,7 @@ SDL3_0.0.0 { SDL_GetKeyFromScancode; SDL_GetKeyName; SDL_GetKeyboardFocus; + SDL_GetKeyboardInstanceName; SDL_GetKeyboardState; SDL_GetKeyboards; SDL_GetLogOutputFunction; @@ -329,6 +330,7 @@ SDL3_0.0.0 { SDL_GetMice; SDL_GetModState; SDL_GetMouseFocus; + SDL_GetMouseInstanceName; SDL_GetMouseState; SDL_GetNaturalDisplayOrientation; SDL_GetNumAllocations; diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index 8f140360d..935170151 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -344,6 +344,7 @@ #define SDL_GetKeyFromScancode SDL_GetKeyFromScancode_REAL #define SDL_GetKeyName SDL_GetKeyName_REAL #define SDL_GetKeyboardFocus SDL_GetKeyboardFocus_REAL +#define SDL_GetKeyboardInstanceName SDL_GetKeyboardInstanceName_REAL #define SDL_GetKeyboardState SDL_GetKeyboardState_REAL #define SDL_GetKeyboards SDL_GetKeyboards_REAL #define SDL_GetLogOutputFunction SDL_GetLogOutputFunction_REAL @@ -354,6 +355,7 @@ #define SDL_GetMice SDL_GetMice_REAL #define SDL_GetModState SDL_GetModState_REAL #define SDL_GetMouseFocus SDL_GetMouseFocus_REAL +#define SDL_GetMouseInstanceName SDL_GetMouseInstanceName_REAL #define SDL_GetMouseState SDL_GetMouseState_REAL #define SDL_GetNaturalDisplayOrientation SDL_GetNaturalDisplayOrientation_REAL #define SDL_GetNumAllocations SDL_GetNumAllocations_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 8a2804a24..8f7b319ea 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -382,6 +382,7 @@ 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(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) SDL_DYNAPI_PROC(const Uint8*,SDL_GetKeyboardState,(int *a),(a),return) SDL_DYNAPI_PROC(SDL_MouseID*,SDL_GetKeyboards,(int *a),(a),return) SDL_DYNAPI_PROC(void,SDL_GetLogOutputFunction,(SDL_LogOutputFunction *a, void **b),(a,b),) @@ -392,6 +393,7 @@ SDL_DYNAPI_PROC(void,SDL_GetMemoryFunctions,(SDL_malloc_func *a, SDL_calloc_func SDL_DYNAPI_PROC(SDL_MouseID*,SDL_GetMice,(int *a),(a),return) SDL_DYNAPI_PROC(SDL_Keymod,SDL_GetModState,(void),(),return) SDL_DYNAPI_PROC(SDL_Window*,SDL_GetMouseFocus,(void),(),return) +SDL_DYNAPI_PROC(const char*,SDL_GetMouseInstanceName,(SDL_MouseID a),(a),return) SDL_DYNAPI_PROC(Uint32,SDL_GetMouseState,(float *a, float *b),(a,b),return) SDL_DYNAPI_PROC(SDL_DisplayOrientation,SDL_GetNaturalDisplayOrientation,(SDL_DisplayID a),(a),return) SDL_DYNAPI_PROC(int,SDL_GetNumAllocations,(void),(),return) diff --git a/src/events/SDL_keyboard.c b/src/events/SDL_keyboard.c index 1e5eb02a0..577e6ba5f 100644 --- a/src/events/SDL_keyboard.c +++ b/src/events/SDL_keyboard.c @@ -40,9 +40,13 @@ typedef enum #define KEYBOARD_SOURCE_MASK (KEYBOARD_HARDWARE | KEYBOARD_AUTORELEASE) -typedef struct SDL_Keyboard SDL_Keyboard; +typedef struct SDL_KeyboardInstance +{ + SDL_KeyboardID instance_id; + char *name; +} SDL_KeyboardInstance; -struct SDL_Keyboard +typedef struct SDL_Keyboard { /* Data common to all keyboards */ SDL_Window *focus; @@ -52,11 +56,11 @@ struct SDL_Keyboard SDL_Keycode keymap[SDL_NUM_SCANCODES]; SDL_bool autorelease_pending; Uint64 hardware_timestamp; -}; +} SDL_Keyboard; static SDL_Keyboard SDL_keyboard; static int SDL_keyboard_count; -static SDL_KeyboardID *SDL_keyboards; +static SDL_KeyboardInstance *SDL_keyboards; static const SDL_Keycode SDL_default_keymap[SDL_NUM_SCANCODES] = { /* 0 */ SDLK_UNKNOWN, @@ -691,29 +695,33 @@ SDL_bool SDL_IsKeyboard(Uint16 vendor, Uint16 product, int num_keys) return SDL_TRUE; } -void SDL_AddKeyboard(SDL_KeyboardID keyboardID, SDL_bool send_event) +static int SDL_GetKeyboardIndex(SDL_KeyboardID keyboardID) { - int keyboard_index = -1; - - SDL_assert(keyboardID != 0); - for (int i = 0; i < SDL_keyboard_count; ++i) { - if (keyboardID == SDL_keyboards[i]) { - keyboard_index = i; - break; + if (keyboardID == SDL_keyboards[i].instance_id) { + return i; } } + return -1; +} +void SDL_AddKeyboard(SDL_KeyboardID keyboardID, const char *name, SDL_bool send_event) +{ + int keyboard_index = SDL_GetKeyboardIndex(keyboardID); if (keyboard_index >= 0) { /* We already know about this keyboard */ return; } - SDL_KeyboardID *keyboards = (SDL_KeyboardID *)SDL_realloc(SDL_keyboards, (SDL_keyboard_count + 1) * sizeof(*keyboards)); + SDL_assert(keyboardID != 0); + + SDL_KeyboardInstance *keyboards = (SDL_KeyboardInstance *)SDL_realloc(SDL_keyboards, (SDL_keyboard_count + 1) * sizeof(*keyboards)); if (!keyboards) { return; } - keyboards[SDL_keyboard_count] = keyboardID; + SDL_KeyboardInstance *instance = &keyboards[SDL_keyboard_count]; + instance->instance_id = keyboardID; + instance->name = SDL_strdup(name ? name : ""); SDL_keyboards = keyboards; ++SDL_keyboard_count; @@ -728,22 +736,14 @@ void SDL_AddKeyboard(SDL_KeyboardID keyboardID, SDL_bool send_event) void SDL_RemoveKeyboard(SDL_KeyboardID keyboardID) { - int keyboard_index = -1; - - SDL_assert(keyboardID != 0); - - for (int i = 0; i < SDL_keyboard_count; ++i) { - if (keyboardID == SDL_keyboards[i]) { - keyboard_index = i; - break; - } - } - + int keyboard_index = SDL_GetKeyboardIndex(keyboardID); if (keyboard_index < 0) { /* We don't know about this keyboard */ return; } + SDL_free(SDL_keyboards[keyboard_index].name); + if (keyboard_index != SDL_keyboard_count - 1) { SDL_memcpy(&SDL_keyboards[keyboard_index], &SDL_keyboards[keyboard_index + 1], (SDL_keyboard_count - keyboard_index - 1) * sizeof(SDL_keyboards[keyboard_index])); } @@ -773,7 +773,7 @@ SDL_KeyboardID *SDL_GetKeyboards(int *count) } for (i = 0; i < SDL_keyboard_count; ++i) { - keyboards[i] = SDL_keyboards[i]; + keyboards[i] = SDL_keyboards[i].instance_id; } keyboards[i] = 0; } else { @@ -785,6 +785,15 @@ SDL_KeyboardID *SDL_GetKeyboards(int *count) return keyboards; } +const char *SDL_GetKeyboardInstanceName(SDL_KeyboardID instance_id) +{ + int keyboard_index = SDL_GetKeyboardIndex(instance_id); + if (keyboard_index < 0) { + return NULL; + } + return SDL_keyboards[keyboard_index].name; +} + void SDL_ResetKeyboard(void) { SDL_Keyboard *keyboard = &SDL_keyboard; diff --git a/src/events/SDL_keyboard_c.h b/src/events/SDL_keyboard_c.h index 584951a94..b44ec8276 100644 --- a/src/events/SDL_keyboard_c.h +++ b/src/events/SDL_keyboard_c.h @@ -30,7 +30,7 @@ extern int SDL_InitKeyboard(void); extern SDL_bool SDL_IsKeyboard(Uint16 vendor, Uint16 product, int num_keys); /* A keyboard has been added to the system */ -extern void SDL_AddKeyboard(SDL_KeyboardID keyboardID, SDL_bool send_event); +extern void SDL_AddKeyboard(SDL_KeyboardID keyboardID, const char *name, SDL_bool send_event); /* A keyboard has been removed from the system */ extern void SDL_RemoveKeyboard(SDL_KeyboardID keyboardID); diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c index 616115bf7..1edaab464 100644 --- a/src/events/SDL_mouse.c +++ b/src/events/SDL_mouse.c @@ -33,10 +33,16 @@ /* #define DEBUG_MOUSE */ +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_MouseID *SDL_mice; +static SDL_MouseInstance *SDL_mice; /* for mapping mouse events to touch */ static SDL_bool track_mouse_down = SDL_FALSE; @@ -235,29 +241,33 @@ SDL_bool SDL_IsMouse(Uint16 vendor, Uint16 product) return SDL_TRUE; } -void SDL_AddMouse(SDL_MouseID mouseID, SDL_bool send_event) +static int SDL_GetMouseIndex(SDL_MouseID mouseID) { - int mouse_index = -1; - - SDL_assert(mouseID != 0); - for (int i = 0; i < SDL_mouse_count; ++i) { - if (mouseID == SDL_mice[i]) { - mouse_index = i; - break; + if (mouseID == SDL_mice[i].instance_id) { + return i; } } + return -1; +} +void SDL_AddMouse(SDL_MouseID mouseID, const char *name, SDL_bool send_event) +{ + int mouse_index = SDL_GetMouseIndex(mouseID); if (mouse_index >= 0) { /* We already know about this mouse */ return; } - SDL_MouseID *mice = (SDL_MouseID *)SDL_realloc(SDL_mice, (SDL_mouse_count + 1) * sizeof(*mice)); + SDL_assert(mouseID != 0); + + SDL_MouseInstance *mice = (SDL_MouseInstance *)SDL_realloc(SDL_mice, (SDL_mouse_count + 1) * sizeof(*mice)); if (!mice) { return; } - mice[SDL_mouse_count] = mouseID; + SDL_MouseInstance *instance = &mice[SDL_mouse_count]; + instance->instance_id = mouseID; + instance->name = SDL_strdup(name ? name : ""); SDL_mice = mice; ++SDL_mouse_count; @@ -272,22 +282,14 @@ void SDL_AddMouse(SDL_MouseID mouseID, SDL_bool send_event) void SDL_RemoveMouse(SDL_MouseID mouseID) { - int mouse_index = -1; - - SDL_assert(mouseID != 0); - - for (int i = 0; i < SDL_mouse_count; ++i) { - if (mouseID == SDL_mice[i]) { - mouse_index = i; - break; - } - } - + int mouse_index = SDL_GetMouseIndex(mouseID); if (mouse_index < 0) { /* We don't know about this mouse */ return; } + SDL_free(SDL_mice[mouse_index].name); + if (mouse_index != SDL_mouse_count - 1) { SDL_memcpy(&SDL_mice[mouse_index], &SDL_mice[mouse_index + 1], (SDL_mouse_count - mouse_index - 1) * sizeof(SDL_mice[mouse_index])); } @@ -330,7 +332,7 @@ SDL_MouseID *SDL_GetMice(int *count) } for (i = 0; i < SDL_mouse_count; ++i) { - mice[i] = SDL_mice[i]; + mice[i] = SDL_mice[i].instance_id; } mice[i] = 0; } else { @@ -342,6 +344,14 @@ SDL_MouseID *SDL_GetMice(int *count) return mice; } +const char *SDL_GetMouseInstanceName(SDL_MouseID instance_id) +{ + int mouse_index = SDL_GetMouseIndex(instance_id); + if (mouse_index < 0) { + return NULL; + } + return SDL_mice[mouse_index].name; +} void SDL_SetDefaultCursor(SDL_Cursor *cursor) { diff --git a/src/events/SDL_mouse_c.h b/src/events/SDL_mouse_c.h index ea700a30b..f02811a5e 100644 --- a/src/events/SDL_mouse_c.h +++ b/src/events/SDL_mouse_c.h @@ -131,7 +131,7 @@ extern void SDL_PostInitMouse(void); extern SDL_bool SDL_IsMouse(Uint16 vendor, Uint16 product); /* A mouse has been added to the system */ -extern void SDL_AddMouse(SDL_MouseID mouseID, SDL_bool send_event); +extern void SDL_AddMouse(SDL_MouseID mouseID, const char *name, SDL_bool send_event); /* A mouse has been removed from the system */ extern void SDL_RemoveMouse(SDL_MouseID mouseID); diff --git a/src/video/cocoa/SDL_cocoavideo.m b/src/video/cocoa/SDL_cocoavideo.m index 20c46b5ca..eb96d3526 100644 --- a/src/video/cocoa/SDL_cocoavideo.m +++ b/src/video/cocoa/SDL_cocoavideo.m @@ -204,9 +204,9 @@ int Cocoa_VideoInit(SDL_VideoDevice *_this) // Assume we have a mouse and keyboard // We could use GCMouse and GCKeyboard if we needed to, as is done in SDL_uikitevents.m data.keyboardID = SDL_GetNextObjectID(); - SDL_AddKeyboard(data.keyboardID, SDL_FALSE); + SDL_AddKeyboard(data.keyboardID, NULL, SDL_FALSE); data.mouseID = SDL_GetNextObjectID(); - SDL_AddMouse(data.mouseID, SDL_FALSE); + SDL_AddMouse(data.mouseID, NULL, SDL_FALSE); data.allow_spaces = SDL_GetHintBoolean(SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES, SDL_TRUE); data.trackpad_is_touch_only = SDL_GetHintBoolean(SDL_HINT_TRACKPAD_IS_TOUCH_ONLY, SDL_FALSE); diff --git a/src/video/emscripten/SDL_emscriptenvideo.c b/src/video/emscripten/SDL_emscriptenvideo.c index 67bf34075..1437b0a66 100644 --- a/src/video/emscripten/SDL_emscriptenvideo.c +++ b/src/video/emscripten/SDL_emscriptenvideo.c @@ -137,8 +137,8 @@ int Emscripten_VideoInit(SDL_VideoDevice *_this) Emscripten_InitMouse(); /* Assume we have a mouse and keyboard */ - SDL_AddKeyboard(EMSCRIPTEN_KEYBOARD_ID, SDL_FALSE); - SDL_AddMouse(EMSCRIPTEN_MOUSE_ID, SDL_FALSE); + SDL_AddKeyboard(EMSCRIPTEN_KEYBOARD_ID, NULL, SDL_FALSE); + SDL_AddMouse(EMSCRIPTEN_MOUSE_ID, NULL, SDL_FALSE); /* We're done! */ return 0; diff --git a/src/video/haiku/SDL_bvideo.cc b/src/video/haiku/SDL_bvideo.cc index ea495af7a..9720e41d6 100644 --- a/src/video/haiku/SDL_bvideo.cc +++ b/src/video/haiku/SDL_bvideo.cc @@ -282,8 +282,8 @@ int HAIKU_VideoInit(SDL_VideoDevice *_this) HAIKU_MouseInit(_this); /* Assume we have a mouse and keyboard */ - SDL_AddKeyboard(BAPP_KEYBOARD_ID, SDL_FALSE); - SDL_AddMouse(BAPP_MOUSE_ID, SDL_FALSE); + SDL_AddKeyboard(BAPP_KEYBOARD_ID, NULL, SDL_FALSE); + SDL_AddMouse(BAPP_MOUSE_ID, NULL, SDL_FALSE); #ifdef SDL_VIDEO_OPENGL /* testgl application doesn't load library, just tries to load symbols */ diff --git a/src/video/qnx/SDL_qnxvideo.c b/src/video/qnx/SDL_qnxvideo.c index b0cd9fd79..43e8a5ec0 100644 --- a/src/video/qnx/SDL_qnxvideo.c +++ b/src/video/qnx/SDL_qnxvideo.c @@ -53,8 +53,8 @@ static int videoInit(SDL_VideoDevice *_this) } /* Assume we have a mouse and keyboard */ - SDL_AddKeyboard(QNX_KEYBOARD_ID, SDL_FALSE); - SDL_AddMouse(QNX_MOUSE_ID, SDL_FALSE); + SDL_AddKeyboard(QNX_KEYBOARD_ID, NULL, SDL_FALSE); + SDL_AddMouse(QNX_MOUSE_ID, NULL, SDL_FALSE); return 0; } diff --git a/src/video/riscos/SDL_riscosvideo.c b/src/video/riscos/SDL_riscosvideo.c index 02b0abbc4..2068f17c4 100644 --- a/src/video/riscos/SDL_riscosvideo.c +++ b/src/video/riscos/SDL_riscosvideo.c @@ -110,9 +110,9 @@ static int RISCOS_VideoInit(SDL_VideoDevice *_this) /* Assume we have a mouse and keyboard */ data->keyboardID = SDL_GetNextObjectID(); - SDL_AddKeyboard(data->keyboardID, SDL_FALSE); + SDL_AddKeyboard(data->keyboardID, NULL, SDL_FALSE); data->mouseID = SDL_GetNextObjectID(); - SDL_AddMouse(data->mouseID, SDL_FALSE); + SDL_AddMouse(data->mouseID, NULL, SDL_FALSE); if (RISCOS_InitModes(_this) < 0) { return -1; diff --git a/src/video/uikit/SDL_uikitevents.m b/src/video/uikit/SDL_uikitevents.m index 233216486..5c025e0b4 100644 --- a/src/video/uikit/SDL_uikitevents.m +++ b/src/video/uikit/SDL_uikitevents.m @@ -178,7 +178,7 @@ static void OnGCKeyboardConnected(GCKeyboard *keyboard) API_AVAILABLE(macos(11.0 { SDL_KeyboardID keyboardID = (SDL_KeyboardID)(uintptr_t)keyboard; - SDL_AddKeyboard(keyboardID, SDL_TRUE); + SDL_AddKeyboard(keyboardID, NULL, SDL_TRUE); keyboard.keyboardInput.keyChangedHandler = ^(GCKeyboardInput *kbrd, GCControllerButtonInput *key, GCKeyCode keyCode, BOOL pressed) { SDL_SendKeyboardKey(0, keyboardID, pressed ? SDL_PRESSED : SDL_RELEASED, (SDL_Scancode)keyCode); @@ -319,7 +319,7 @@ static void OnGCMouseConnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14 { SDL_MouseID mouseID = (SDL_MouseID)(uintptr_t)mouse; - SDL_AddMouse(mouseID, SDL_TRUE); + SDL_AddMouse(mouseID, NULL, SDL_TRUE); mouse.mouseInput.leftButton.pressedChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) { OnGCMouseButtonChanged(mouseID, SDL_BUTTON_LEFT, pressed); diff --git a/src/video/vita/SDL_vitakeyboard.c b/src/video/vita/SDL_vitakeyboard.c index cb0ccc4e9..93dffc8f2 100644 --- a/src/video/vita/SDL_vitakeyboard.c +++ b/src/video/vita/SDL_vitakeyboard.c @@ -45,7 +45,7 @@ void VITA_InitKeyboard(void) sceHidKeyboardEnumerate(&keyboard_hid_handle, 1); if (keyboard_hid_handle > 0) { - SDL_AddKeyboard((SDL_KeyboardID)keyboard_hid_handle, SDL_FALSE); + SDL_AddKeyboard((SDL_KeyboardID)keyboard_hid_handle, NULL, SDL_FALSE); } } diff --git a/src/video/vita/SDL_vitamouse.c b/src/video/vita/SDL_vitamouse.c index 46d736252..dfac1601f 100644 --- a/src/video/vita/SDL_vitamouse.c +++ b/src/video/vita/SDL_vitamouse.c @@ -39,7 +39,7 @@ void VITA_InitMouse(void) sceHidMouseEnumerate(&mouse_hid_handle, 1); if (mouse_hid_handle > 0) { - SDL_AddMouse((SDL_MouseID)mouse_hid_handle, SDL_FALSE); + SDL_AddMouse((SDL_MouseID)mouse_hid_handle, NULL, SDL_FALSE); } } diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c index 24dde270f..a6f94d01b 100644 --- a/src/video/wayland/SDL_waylandevents.c +++ b/src/video/wayland/SDL_waylandevents.c @@ -1715,7 +1715,7 @@ static void seat_handle_capabilities(void *data, struct wl_seat *seat, wl_pointer_add_listener(input->pointer, &pointer_listener, input); input->pointer_id = SDL_GetNextObjectID(); - SDL_AddMouse(input->pointer_id, SDL_TRUE); + SDL_AddMouse(input->pointer_id, NULL, SDL_TRUE); } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && input->pointer) { if (input->cursor_shape) { wp_cursor_shape_device_v1_destroy(input->cursor_shape); @@ -1748,7 +1748,7 @@ static void seat_handle_capabilities(void *data, struct wl_seat *seat, input); input->keyboard_id = SDL_GetNextObjectID(); - SDL_AddKeyboard(input->keyboard_id, SDL_TRUE); + SDL_AddKeyboard(input->keyboard_id, NULL, SDL_TRUE); } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && input->keyboard) { wl_keyboard_destroy(input->keyboard); input->keyboard = NULL; diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c index f6d80544e..11f31eb30 100644 --- a/src/video/windows/SDL_windowsevents.c +++ b/src/video/windows/SDL_windowsevents.c @@ -32,6 +32,9 @@ /* Dropfile support */ #include +/* Device names */ +#include + /* For GET_X_LPARAM, GET_Y_LPARAM. */ #include @@ -720,6 +723,33 @@ static SDL_bool HasDeviceID(Uint32 deviceID, Uint32 *list, int count) return SDL_FALSE; } +static void GetDeviceName(HDEVINFO devinfo, const char *instance, char *name, size_t len) +{ + name[0] = '\0'; + + SP_DEVINFO_DATA data; + SDL_zero(data); + data.cbSize = sizeof(data); + for (DWORD i = 0;; ++i) { + if (!SetupDiEnumDeviceInfo(devinfo, i, &data)) { + if (GetLastError() == ERROR_NO_MORE_ITEMS) { + break; + } else { + continue; + } + } + + char DeviceInstanceId[64]; + if (!SetupDiGetDeviceInstanceIdA(devinfo, &data, DeviceInstanceId, sizeof(DeviceInstanceId), NULL)) + continue; + + if (SDL_strcasecmp(instance, DeviceInstanceId) == 0) { + SetupDiGetDeviceRegistryPropertyA(devinfo, &data, SPDRP_DEVICEDESC, NULL, (PBYTE)name, len, NULL); + return; + } + } +} + void WIN_CheckKeyboardAndMouseHotplug(SDL_VideoDevice *_this, SDL_bool initial_check) { SDL_VideoData *data = _this->driverdata; @@ -759,76 +789,106 @@ void WIN_CheckKeyboardAndMouseHotplug(SDL_VideoDevice *_this, SDL_bool initial_c return; /* oh well. */ } + HDEVINFO devinfo = SetupDiGetClassDevsA(NULL, NULL, NULL, (DIGCF_ALLCLASSES | DIGCF_PRESENT)); + + old_keyboards = SDL_GetKeyboards(&old_keyboard_count); + old_mice = SDL_GetMice(&old_mouse_count); + for (UINT i = 0; i < raw_device_count; i++) { RID_DEVICE_INFO rdi; char devName[MAX_PATH] = { 0 }; UINT rdiSize = sizeof(rdi); UINT nameSize = SDL_arraysize(devName); int vendor = 0, product = 0; + DWORD dwType = raw_devices[i].dwType; + char *instance, *ptr, name[64]; + + if (dwType != RIM_TYPEKEYBOARD && dwType != RIM_TYPEMOUSE) { + continue; + } rdi.cbSize = sizeof(rdi); - if (GetRawInputDeviceInfoA(raw_devices[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) == ((UINT)-1) || GetRawInputDeviceInfoA(raw_devices[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) == ((UINT)-1)) { continue; } - SDL_sscanf(devName, "\\\\?\\HID#VID_%X&PID_%X&", &vendor, &product); + /* Extract the device instance */ + instance = devName; + while (*instance == '\\' || *instance == '?') { + ++instance; + } + for (ptr = instance; *ptr; ++ptr) { + if (*ptr == '#') { + *ptr = '\\'; + } + if (*ptr == '{') { + if (ptr > instance && ptr[-1] == '\\') { + --ptr; + } + break; + } + } + *ptr = '\0'; - switch (raw_devices[i].dwType) { + SDL_sscanf(instance, "HID\\VID_%X&PID_%X&", &vendor, &product); + + switch (dwType) { case RIM_TYPEKEYBOARD: if (SDL_IsKeyboard((Uint16)vendor, (Uint16)product, rdi.keyboard.dwNumberOfKeysTotal)) { - AddDeviceID((Uint32)(uintptr_t)raw_devices[i].hDevice, &new_keyboards, &new_keyboard_count); + SDL_KeyboardID keyboardID = (Uint32)(uintptr_t)raw_devices[i].hDevice; + AddDeviceID(keyboardID, &new_keyboards, &new_keyboard_count); + if (!HasDeviceID(keyboardID, old_keyboards, old_keyboard_count)) { + GetDeviceName(devinfo, instance, name, sizeof(name)); + SDL_AddKeyboard(keyboardID, name, send_event); + } } break; case RIM_TYPEMOUSE: if (SDL_IsMouse((Uint16)vendor, (Uint16)product)) { - AddDeviceID((Uint32)(uintptr_t)raw_devices[i].hDevice, &new_mice, &new_mouse_count); + SDL_MouseID mouseID = (Uint32)(uintptr_t)raw_devices[i].hDevice; + AddDeviceID(mouseID, &new_mice, &new_mouse_count); + if (!HasDeviceID(mouseID, old_mice, old_mouse_count)) { + GetDeviceName(devinfo, instance, name, sizeof(name)); + SDL_AddMouse(mouseID, name, send_event); + } } break; default: break; } } - SDL_free(raw_devices); - old_keyboards = SDL_GetKeyboards(&old_keyboard_count); for (int i = old_keyboard_count; i--;) { if (!HasDeviceID(old_keyboards[i], new_keyboards, new_keyboard_count)) { SDL_RemoveKeyboard(old_keyboards[i]); } } - for (int i = 0; i < new_keyboard_count; ++i) { - if (!HasDeviceID(new_keyboards[i], old_keyboards, old_keyboard_count)) { - SDL_AddKeyboard(new_keyboards[i], send_event); - } - } if (new_keyboard_count > 0) { data->keyboardID = new_keyboards[0]; } else { data->keyboardID = 0; } - SDL_free(new_keyboards); - SDL_free(old_keyboards); - old_mice = SDL_GetMice(&old_mouse_count); for (int i = old_mouse_count; i--;) { if (!HasDeviceID(old_mice[i], new_mice, new_mouse_count)) { SDL_RemoveMouse(old_mice[i]); } } - for (int i = 0; i < new_mouse_count; ++i) { - if (!HasDeviceID(new_mice[i], old_mice, old_mouse_count)) { - SDL_AddMouse(new_mice[i], send_event); - } - } if (new_mouse_count > 0) { data->mouseID = new_mice[0]; } else { data->mouseID = 0; } - SDL_free(new_mice); + + SDL_free(old_keyboards); SDL_free(old_mice); + SDL_free(new_keyboards); + SDL_free(new_mice); + + SetupDiDestroyDeviceInfoList(devinfo); + + SDL_free(raw_devices); } LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) diff --git a/src/video/winrt/SDL_winrtvideo.cpp b/src/video/winrt/SDL_winrtvideo.cpp index dd39b9511..b40681852 100644 --- a/src/video/winrt/SDL_winrtvideo.cpp +++ b/src/video/winrt/SDL_winrtvideo.cpp @@ -240,8 +240,8 @@ int WINRT_VideoInit(SDL_VideoDevice *_this) } /* Assume we have a mouse and keyboard */ - SDL_AddKeyboard(WINRT_KEYBOARD_ID, SDL_FALSE); - SDL_AddMouse(WINRT_MOUSE_ID, SDL_FALSE); + SDL_AddKeyboard(WINRT_KEYBOARD_ID, NULL, SDL_FALSE); + SDL_AddMouse(WINRT_MOUSE_ID, NULL, SDL_FALSE); return 0; } diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index 2e6cce79a..662e96cf4 100644 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -420,9 +420,9 @@ int X11_VideoInit(SDL_VideoDevice *_this) if (!X11_InitXinput2(_this)) { /* Assume a mouse and keyboard are attached */ data->keyboardID = SDL_GetNextObjectID(); - SDL_AddKeyboard(data->keyboardID, SDL_FALSE); + SDL_AddKeyboard(data->keyboardID, NULL, SDL_FALSE); data->mouseID = SDL_GetNextObjectID(); - SDL_AddMouse(data->mouseID, SDL_FALSE); + SDL_AddMouse(data->mouseID, NULL, SDL_FALSE); } #ifdef SDL_VIDEO_DRIVER_X11_XFIXES diff --git a/src/video/x11/SDL_x11xinput2.c b/src/video/x11/SDL_x11xinput2.c index 38fb75ed3..f3029949d 100644 --- a/src/video/x11/SDL_x11xinput2.c +++ b/src/video/x11/SDL_x11xinput2.c @@ -108,17 +108,17 @@ static void xinput2_init_device_list(SDL_VideoData *videodata) switch (dev->use) { case XIMasterKeyboard: videodata->keyboardID = (SDL_KeyboardID)dev->deviceid; - SDL_AddKeyboard((SDL_KeyboardID)dev->deviceid, SDL_FALSE); + SDL_AddKeyboard((SDL_KeyboardID)dev->deviceid, dev->name, SDL_FALSE); break; case XISlaveKeyboard: - SDL_AddKeyboard((SDL_KeyboardID)dev->deviceid, SDL_FALSE); + SDL_AddKeyboard((SDL_KeyboardID)dev->deviceid, dev->name, SDL_FALSE); break; case XIMasterPointer: videodata->mouseID = (SDL_MouseID)dev->deviceid; - SDL_AddMouse((SDL_MouseID)dev->deviceid, SDL_FALSE); + SDL_AddMouse((SDL_MouseID)dev->deviceid, dev->name, SDL_FALSE); break; case XISlavePointer: - SDL_AddMouse((SDL_MouseID)dev->deviceid, SDL_FALSE); + SDL_AddMouse((SDL_MouseID)dev->deviceid, dev->name, SDL_FALSE); break; default: break;