From 281f0fae1cec348330080739417e5bfe13b18032 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
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 b66e3a7106fed..8d321430b274c 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 e8e98f241e9c3..5e0e8f519ebef 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 9221bce9cb5b9..7574adc6c0771 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 8e1ddd7d3c8e5..5e56816ed7ec8 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);
}