From 281f0fae1cec348330080739417e5bfe13b18032 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 26 Feb 2025 12:53:39 -0800 Subject: [PATCH] Include the VID/PID of generic keyboard/mouse devices on Windows --- src/SDL_utils.c | 8 +++--- src/SDL_utils_c.h | 2 +- src/joystick/SDL_joystick.c | 2 +- src/video/windows/SDL_windowsevents.c | 37 ++++++++++++++++++--------- 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/src/SDL_utils.c b/src/SDL_utils.c index b66e3a7106..8d321430b2 100644 --- a/src/SDL_utils.c +++ b/src/SDL_utils.c @@ -413,7 +413,7 @@ static int PrefixMatch(const char *a, const char *b) return matchlen; } -char *SDL_CreateDeviceName(Uint16 vendor, Uint16 product, const char *vendor_name, const char *product_name) +char *SDL_CreateDeviceName(Uint16 vendor, Uint16 product, const char *vendor_name, const char *product_name, const char *default_name) { static struct { @@ -434,7 +434,7 @@ char *SDL_CreateDeviceName(Uint16 vendor, Uint16 product, const char *vendor_nam { "QANBA USA,LLC", "Qanba" }, { "Unknown ", "" }, }; - char *name; + char *name = NULL; size_t i, len; if (!vendor_name) { @@ -488,8 +488,8 @@ char *SDL_CreateDeviceName(Uint16 vendor, Uint16 product, const char *vendor_nam } break; } - } else { - name = SDL_strdup("Controller"); + } else if (default_name) { + name = SDL_strdup(default_name); } if (!name) { diff --git a/src/SDL_utils_c.h b/src/SDL_utils_c.h index e8e98f241e..5e0e8f519e 100644 --- a/src/SDL_utils_c.h +++ b/src/SDL_utils_c.h @@ -73,6 +73,6 @@ extern void SDL_SetObjectsInvalid(void); extern const char *SDL_GetPersistentString(const char *string); -extern char *SDL_CreateDeviceName(Uint16 vendor, Uint16 product, const char *vendor_name, const char *product_name); +extern char *SDL_CreateDeviceName(Uint16 vendor, Uint16 product, const char *vendor_name, const char *product_name, const char *default_name); #endif // SDL_utils_h_ diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index 9221bce9cb..7574adc6c0 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -2553,7 +2553,7 @@ char *SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_n return SDL_strdup(custom_name); } - return SDL_CreateDeviceName(vendor, product, vendor_name, product_name); + return SDL_CreateDeviceName(vendor, product, vendor_name, product_name, "Controller"); } SDL_GUID SDL_CreateJoystickGUID(Uint16 bus, Uint16 vendor, Uint16 product, Uint16 version, const char *vendor_name, const char *product_name, Uint8 driver_signature, Uint8 driver_data) diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c index 8e1ddd7d3c..5e56816ed7 100644 --- a/src/video/windows/SDL_windowsevents.c +++ b/src/video/windows/SDL_windowsevents.c @@ -861,8 +861,10 @@ static bool HasDeviceID(Uint32 deviceID, const Uint32 *list, int count) } #if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) -static char *GetDeviceName(HANDLE hDevice, HDEVINFO devinfo, const char *instance, bool hid_loaded) +static char *GetDeviceName(HANDLE hDevice, HDEVINFO devinfo, const char *instance, const char *default_name, bool hid_loaded) { + char *vendor_name = NULL; + char *product_name = NULL; char *name = NULL; // These are 126 for USB, but can be longer for Bluetooth devices @@ -870,6 +872,7 @@ static char *GetDeviceName(HANDLE hDevice, HDEVINFO devinfo, const char *instanc vend[0] = 0; prod[0] = 0; + HIDD_ATTRIBUTES attr; attr.VendorID = 0; attr.ProductID = 0; @@ -895,7 +898,13 @@ static char *GetDeviceName(HANDLE hDevice, HDEVINFO devinfo, const char *instanc } } - if (!prod[0]) { + if (vend[0]) { + vendor_name = WIN_StringToUTF8W(vend); + } + + if (prod[0]) { + product_name = WIN_StringToUTF8W(prod); + } else { SP_DEVINFO_DATA data; SDL_zero(data); data.cbSize = sizeof(data); @@ -922,21 +931,25 @@ static char *GetDeviceName(HANDLE hDevice, HDEVINFO devinfo, const char *instanc size = (SDL_arraysize(prod) - 1); } prod[size] = 0; + + if (attr.VendorID || attr.ProductID) { + SDL_asprintf(&product_name, "%S (0x%.4x/0x%.4x)", prod, attr.VendorID, attr.ProductID); + } else { + product_name = WIN_StringToUTF8W(prod); + } } break; } } } - if (prod[0]) { - char *vendor_name = vend[0] ? WIN_StringToUTF8W(vend) : NULL; - char *product_name = WIN_StringToUTF8W(prod); - if (product_name) { - name = SDL_CreateDeviceName(attr.VendorID, attr.ProductID, vendor_name, product_name); - } - SDL_free(vendor_name); - SDL_free(product_name); + if (!product_name && (attr.VendorID || attr.ProductID)) { + SDL_asprintf(&product_name, "%s (0x%.4x/0x%.4x)", default_name, attr.VendorID, attr.ProductID); } + name = SDL_CreateDeviceName(attr.VendorID, attr.ProductID, vendor_name, product_name, default_name); + SDL_free(vendor_name); + SDL_free(product_name); + return name; } @@ -1029,7 +1042,7 @@ void WIN_CheckKeyboardAndMouseHotplug(SDL_VideoDevice *_this, bool initial_check 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)) { - name = GetDeviceName(raw_devices[i].hDevice, devinfo, instance, hid_loaded); + name = GetDeviceName(raw_devices[i].hDevice, devinfo, instance, "Keyboard", hid_loaded); SDL_AddKeyboard(keyboardID, name, send_event); SDL_free(name); } @@ -1040,7 +1053,7 @@ void WIN_CheckKeyboardAndMouseHotplug(SDL_VideoDevice *_this, bool initial_check 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)) { - name = GetDeviceName(raw_devices[i].hDevice, devinfo, instance, hid_loaded); + name = GetDeviceName(raw_devices[i].hDevice, devinfo, instance, "Mouse", hid_loaded); SDL_AddMouse(mouseID, name, send_event); SDL_free(name); }