Refactored SDL_CreateJoystickName() into a general SDL_CreateDeviceName()
This commit is contained in:
parent
3293eb1a16
commit
5d776c070a
4 changed files with 237 additions and 267 deletions
151
src/SDL_utils.c
151
src/SDL_utils.c
|
@ -24,6 +24,9 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "joystick/SDL_joystick_c.h" // For SDL_GetGamepadTypeFromVIDPID()
|
||||||
|
|
||||||
|
|
||||||
// Common utility functions that aren't in the public API
|
// Common utility functions that aren't in the public API
|
||||||
|
|
||||||
int SDL_powerof2(int x)
|
int SDL_powerof2(int x)
|
||||||
|
@ -396,3 +399,151 @@ const char *SDL_GetPersistentString(const char *string)
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int PrefixMatch(const char *a, const char *b)
|
||||||
|
{
|
||||||
|
int matchlen = 0;
|
||||||
|
while (*a && *b) {
|
||||||
|
if (SDL_tolower((unsigned char)*a++) == SDL_tolower((unsigned char)*b++)) {
|
||||||
|
++matchlen;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return matchlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *SDL_CreateDeviceName(Uint16 vendor, Uint16 product, const char *vendor_name, const char *product_name)
|
||||||
|
{
|
||||||
|
static struct
|
||||||
|
{
|
||||||
|
const char *prefix;
|
||||||
|
const char *replacement;
|
||||||
|
} replacements[] = {
|
||||||
|
{ "ASTRO Gaming", "ASTRO" },
|
||||||
|
{ "Bensussen Deutsch & Associates,Inc.(BDA)", "BDA" },
|
||||||
|
{ "Guangzhou Chicken Run Network Technology Co., Ltd.", "GameSir" },
|
||||||
|
{ "HORI CO.,LTD", "HORI" },
|
||||||
|
{ "HORI CO.,LTD.", "HORI" },
|
||||||
|
{ "Mad Catz Inc.", "Mad Catz" },
|
||||||
|
{ "Nintendo Co., Ltd.", "Nintendo" },
|
||||||
|
{ "NVIDIA Corporation ", "" },
|
||||||
|
{ "Performance Designed Products", "PDP" },
|
||||||
|
{ "QANBA USA, LLC", "Qanba" },
|
||||||
|
{ "QANBA USA,LLC", "Qanba" },
|
||||||
|
{ "Unknown ", "" },
|
||||||
|
};
|
||||||
|
char *name;
|
||||||
|
size_t i, len;
|
||||||
|
|
||||||
|
if (!vendor_name) {
|
||||||
|
vendor_name = "";
|
||||||
|
}
|
||||||
|
if (!product_name) {
|
||||||
|
product_name = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*vendor_name == ' ') {
|
||||||
|
++vendor_name;
|
||||||
|
}
|
||||||
|
while (*product_name == ' ') {
|
||||||
|
++product_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*vendor_name && *product_name) {
|
||||||
|
len = (SDL_strlen(vendor_name) + 1 + SDL_strlen(product_name) + 1);
|
||||||
|
name = (char *)SDL_malloc(len);
|
||||||
|
if (name) {
|
||||||
|
(void)SDL_snprintf(name, len, "%s %s", vendor_name, product_name);
|
||||||
|
}
|
||||||
|
} else if (*product_name) {
|
||||||
|
name = SDL_strdup(product_name);
|
||||||
|
} else if (vendor || product) {
|
||||||
|
// Couldn't find a controller name, try to give it one based on device type
|
||||||
|
switch (SDL_GetGamepadTypeFromVIDPID(vendor, product, NULL, true)) {
|
||||||
|
case SDL_GAMEPAD_TYPE_XBOX360:
|
||||||
|
name = SDL_strdup("Xbox 360 Controller");
|
||||||
|
break;
|
||||||
|
case SDL_GAMEPAD_TYPE_XBOXONE:
|
||||||
|
name = SDL_strdup("Xbox One Controller");
|
||||||
|
break;
|
||||||
|
case SDL_GAMEPAD_TYPE_PS3:
|
||||||
|
name = SDL_strdup("PS3 Controller");
|
||||||
|
break;
|
||||||
|
case SDL_GAMEPAD_TYPE_PS4:
|
||||||
|
name = SDL_strdup("PS4 Controller");
|
||||||
|
break;
|
||||||
|
case SDL_GAMEPAD_TYPE_PS5:
|
||||||
|
name = SDL_strdup("DualSense Wireless Controller");
|
||||||
|
break;
|
||||||
|
case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO:
|
||||||
|
name = SDL_strdup("Nintendo Switch Pro Controller");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
len = (6 + 1 + 6 + 1);
|
||||||
|
name = (char *)SDL_malloc(len);
|
||||||
|
if (name) {
|
||||||
|
(void)SDL_snprintf(name, len, "0x%.4x/0x%.4x", vendor, product);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
name = SDL_strdup("Controller");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!name) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trim trailing whitespace
|
||||||
|
for (len = SDL_strlen(name); (len > 0 && name[len - 1] == ' '); --len) {
|
||||||
|
// continue
|
||||||
|
}
|
||||||
|
name[len] = '\0';
|
||||||
|
|
||||||
|
// Compress duplicate spaces
|
||||||
|
for (i = 0; i < (len - 1);) {
|
||||||
|
if (name[i] == ' ' && name[i + 1] == ' ') {
|
||||||
|
SDL_memmove(&name[i], &name[i + 1], (len - i));
|
||||||
|
--len;
|
||||||
|
} else {
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform any manufacturer replacements
|
||||||
|
for (i = 0; i < SDL_arraysize(replacements); ++i) {
|
||||||
|
size_t prefixlen = SDL_strlen(replacements[i].prefix);
|
||||||
|
if (SDL_strncasecmp(name, replacements[i].prefix, prefixlen) == 0) {
|
||||||
|
size_t replacementlen = SDL_strlen(replacements[i].replacement);
|
||||||
|
if (replacementlen <= prefixlen) {
|
||||||
|
SDL_memcpy(name, replacements[i].replacement, replacementlen);
|
||||||
|
SDL_memmove(name + replacementlen, name + prefixlen, (len - prefixlen) + 1);
|
||||||
|
len -= (prefixlen - replacementlen);
|
||||||
|
} else {
|
||||||
|
// FIXME: Need to handle the expand case by reallocating the string
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove duplicate manufacturer or product in the name
|
||||||
|
* e.g. Razer Razer Raiju Tournament Edition Wired
|
||||||
|
*/
|
||||||
|
for (i = 1; i < (len - 1); ++i) {
|
||||||
|
int matchlen = PrefixMatch(name, &name[i]);
|
||||||
|
while (matchlen > 0) {
|
||||||
|
if (name[matchlen] == ' ' || name[matchlen] == '-') {
|
||||||
|
SDL_memmove(name, name + matchlen + 1, len - matchlen);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
--matchlen;
|
||||||
|
}
|
||||||
|
if (matchlen > 0) {
|
||||||
|
// We matched the manufacturer's name and removed it
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
|
@ -73,4 +73,6 @@ extern void SDL_SetObjectsInvalid(void);
|
||||||
|
|
||||||
extern const char *SDL_GetPersistentString(const char *string);
|
extern const char *SDL_GetPersistentString(const char *string);
|
||||||
|
|
||||||
|
extern char *SDL_CreateDeviceName(Uint16 vendor, Uint16 product, const char *vendor_name, const char *product_name);
|
||||||
|
|
||||||
#endif // SDL_utils_h_
|
#endif // SDL_utils_h_
|
||||||
|
|
|
@ -2546,158 +2546,14 @@ void SDL_GetJoystickGUIDInfo(SDL_GUID guid, Uint16 *vendor, Uint16 *product, Uin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int PrefixMatch(const char *a, const char *b)
|
|
||||||
{
|
|
||||||
int matchlen = 0;
|
|
||||||
while (*a && *b) {
|
|
||||||
if (SDL_tolower((unsigned char)*a++) == SDL_tolower((unsigned char)*b++)) {
|
|
||||||
++matchlen;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return matchlen;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, const char *product_name)
|
char *SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, const char *product_name)
|
||||||
{
|
{
|
||||||
static struct
|
const char *custom_name = GuessControllerName(vendor, product);
|
||||||
{
|
|
||||||
const char *prefix;
|
|
||||||
const char *replacement;
|
|
||||||
} replacements[] = {
|
|
||||||
{ "ASTRO Gaming", "ASTRO" },
|
|
||||||
{ "Bensussen Deutsch & Associates,Inc.(BDA)", "BDA" },
|
|
||||||
{ "Guangzhou Chicken Run Network Technology Co., Ltd.", "GameSir" },
|
|
||||||
{ "HORI CO.,LTD", "HORI" },
|
|
||||||
{ "HORI CO.,LTD.", "HORI" },
|
|
||||||
{ "Mad Catz Inc.", "Mad Catz" },
|
|
||||||
{ "Nintendo Co., Ltd.", "Nintendo" },
|
|
||||||
{ "NVIDIA Corporation ", "" },
|
|
||||||
{ "Performance Designed Products", "PDP" },
|
|
||||||
{ "QANBA USA, LLC", "Qanba" },
|
|
||||||
{ "QANBA USA,LLC", "Qanba" },
|
|
||||||
{ "Unknown ", "" },
|
|
||||||
};
|
|
||||||
const char *custom_name;
|
|
||||||
char *name;
|
|
||||||
size_t i, len;
|
|
||||||
|
|
||||||
custom_name = GuessControllerName(vendor, product);
|
|
||||||
if (custom_name) {
|
if (custom_name) {
|
||||||
return SDL_strdup(custom_name);
|
return SDL_strdup(custom_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vendor_name) {
|
return SDL_CreateDeviceName(vendor, product, vendor_name, product_name);
|
||||||
vendor_name = "";
|
|
||||||
}
|
|
||||||
if (!product_name) {
|
|
||||||
product_name = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
while (*vendor_name == ' ') {
|
|
||||||
++vendor_name;
|
|
||||||
}
|
|
||||||
while (*product_name == ' ') {
|
|
||||||
++product_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*vendor_name && *product_name) {
|
|
||||||
len = (SDL_strlen(vendor_name) + 1 + SDL_strlen(product_name) + 1);
|
|
||||||
name = (char *)SDL_malloc(len);
|
|
||||||
if (name) {
|
|
||||||
(void)SDL_snprintf(name, len, "%s %s", vendor_name, product_name);
|
|
||||||
}
|
|
||||||
} else if (*product_name) {
|
|
||||||
name = SDL_strdup(product_name);
|
|
||||||
} else if (vendor || product) {
|
|
||||||
// Couldn't find a controller name, try to give it one based on device type
|
|
||||||
switch (SDL_GetGamepadTypeFromVIDPID(vendor, product, NULL, true)) {
|
|
||||||
case SDL_GAMEPAD_TYPE_XBOX360:
|
|
||||||
name = SDL_strdup("Xbox 360 Controller");
|
|
||||||
break;
|
|
||||||
case SDL_GAMEPAD_TYPE_XBOXONE:
|
|
||||||
name = SDL_strdup("Xbox One Controller");
|
|
||||||
break;
|
|
||||||
case SDL_GAMEPAD_TYPE_PS3:
|
|
||||||
name = SDL_strdup("PS3 Controller");
|
|
||||||
break;
|
|
||||||
case SDL_GAMEPAD_TYPE_PS4:
|
|
||||||
name = SDL_strdup("PS4 Controller");
|
|
||||||
break;
|
|
||||||
case SDL_GAMEPAD_TYPE_PS5:
|
|
||||||
name = SDL_strdup("DualSense Wireless Controller");
|
|
||||||
break;
|
|
||||||
case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO:
|
|
||||||
name = SDL_strdup("Nintendo Switch Pro Controller");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
len = (6 + 1 + 6 + 1);
|
|
||||||
name = (char *)SDL_malloc(len);
|
|
||||||
if (name) {
|
|
||||||
(void)SDL_snprintf(name, len, "0x%.4x/0x%.4x", vendor, product);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
name = SDL_strdup("Controller");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!name) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trim trailing whitespace
|
|
||||||
for (len = SDL_strlen(name); (len > 0 && name[len - 1] == ' '); --len) {
|
|
||||||
// continue
|
|
||||||
}
|
|
||||||
name[len] = '\0';
|
|
||||||
|
|
||||||
// Compress duplicate spaces
|
|
||||||
for (i = 0; i < (len - 1);) {
|
|
||||||
if (name[i] == ' ' && name[i + 1] == ' ') {
|
|
||||||
SDL_memmove(&name[i], &name[i + 1], (len - i));
|
|
||||||
--len;
|
|
||||||
} else {
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perform any manufacturer replacements
|
|
||||||
for (i = 0; i < SDL_arraysize(replacements); ++i) {
|
|
||||||
size_t prefixlen = SDL_strlen(replacements[i].prefix);
|
|
||||||
if (SDL_strncasecmp(name, replacements[i].prefix, prefixlen) == 0) {
|
|
||||||
size_t replacementlen = SDL_strlen(replacements[i].replacement);
|
|
||||||
if (replacementlen <= prefixlen) {
|
|
||||||
SDL_memcpy(name, replacements[i].replacement, replacementlen);
|
|
||||||
SDL_memmove(name + replacementlen, name + prefixlen, (len - prefixlen) + 1);
|
|
||||||
len -= (prefixlen - replacementlen);
|
|
||||||
} else {
|
|
||||||
// FIXME: Need to handle the expand case by reallocating the string
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove duplicate manufacturer or product in the name
|
|
||||||
* e.g. Razer Razer Raiju Tournament Edition Wired
|
|
||||||
*/
|
|
||||||
for (i = 1; i < (len - 1); ++i) {
|
|
||||||
int matchlen = PrefixMatch(name, &name[i]);
|
|
||||||
while (matchlen > 0) {
|
|
||||||
if (name[matchlen] == ' ' || name[matchlen] == '-') {
|
|
||||||
SDL_memmove(name, name + matchlen + 1, len - matchlen);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
--matchlen;
|
|
||||||
}
|
|
||||||
if (matchlen > 0) {
|
|
||||||
// We matched the manufacturer's name and removed it
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
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)
|
||||||
|
|
|
@ -861,10 +861,51 @@ static bool HasDeviceID(Uint32 deviceID, const Uint32 *list, int count)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
|
#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
|
||||||
static void GetDeviceName(HANDLE hDevice, HDEVINFO devinfo, const char *instance, char *name, size_t len)
|
static char *GetDeviceName(HANDLE hDevice, HDEVINFO devinfo, const char *instance, bool hid_loaded)
|
||||||
{
|
{
|
||||||
name[0] = '\0';
|
char *name = NULL;
|
||||||
|
|
||||||
|
// These are 126 for USB, but can be longer for Bluetooth devices
|
||||||
|
WCHAR vend[256], prod[256];
|
||||||
|
vend[0] = 0;
|
||||||
|
prod[0] = 0;
|
||||||
|
|
||||||
|
HIDD_ATTRIBUTES attr;
|
||||||
|
attr.VendorID = 0;
|
||||||
|
attr.ProductID = 0;
|
||||||
|
attr.Size = sizeof(attr);
|
||||||
|
|
||||||
|
if (hid_loaded) {
|
||||||
|
char devName[MAX_PATH + 1];
|
||||||
|
UINT cap = sizeof(devName) - 1;
|
||||||
|
UINT len = GetRawInputDeviceInfoA(hDevice, RIDI_DEVICENAME, devName, &cap);
|
||||||
|
if (len != (UINT)-1) {
|
||||||
|
devName[len] = '\0';
|
||||||
|
|
||||||
|
// important: for devices with exclusive access mode as per
|
||||||
|
// https://learn.microsoft.com/en-us/windows-hardware/drivers/hid/top-level-collections-opened-by-windows-for-system-use
|
||||||
|
// they can only be opened with a desired access of none instead of generic read.
|
||||||
|
HANDLE hFile = CreateFileA(devName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
if (hFile != INVALID_HANDLE_VALUE) {
|
||||||
|
SDL_HidD_GetAttributes(hFile, &attr);
|
||||||
|
SDL_HidD_GetManufacturerString(hFile, vend, sizeof(vend));
|
||||||
|
SDL_HidD_GetProductString(hFile, prod, sizeof(prod));
|
||||||
|
CloseHandle(hFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prod[0]) {
|
||||||
|
char *vendor_name = WIN_StringToUTF8W(vend);
|
||||||
|
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 (!name) {
|
||||||
SP_DEVINFO_DATA data;
|
SP_DEVINFO_DATA data;
|
||||||
SDL_zero(data);
|
SDL_zero(data);
|
||||||
data.cbSize = sizeof(data);
|
data.cbSize = sizeof(data);
|
||||||
|
@ -882,109 +923,23 @@ static void GetDeviceName(HANDLE hDevice, HDEVINFO devinfo, const char *instance
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (SDL_strcasecmp(instance, DeviceInstanceId) == 0) {
|
if (SDL_strcasecmp(instance, DeviceInstanceId) == 0) {
|
||||||
SetupDiGetDeviceRegistryPropertyA(devinfo, &data, SPDRP_DEVICEDESC, NULL, (PBYTE)name, (DWORD)len, NULL);
|
DWORD size = 0;
|
||||||
|
if (SetupDiGetDeviceRegistryPropertyW(devinfo, &data, SPDRP_DEVICEDESC, NULL, (PBYTE)prod, sizeof(prod), &size)) {
|
||||||
|
// Make sure the device description is null terminated
|
||||||
|
size /= sizeof(*prod);
|
||||||
|
if (size >= SDL_arraysize(prod)) {
|
||||||
|
// Truncated description...
|
||||||
|
size = (SDL_arraysize(prod) - 1);
|
||||||
|
}
|
||||||
|
prod[size] = 0;
|
||||||
|
|
||||||
|
name = WIN_StringToUTF8W(prod);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t desc_len = 0;
|
|
||||||
for (size_t i = 0; i < len; i++) {
|
|
||||||
if (name[i] == '\0') {
|
|
||||||
desc_len = i;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
return name;
|
||||||
|
|
||||||
char devName[MAX_PATH + 1];
|
|
||||||
devName[MAX_PATH] = '\0';
|
|
||||||
UINT devName_cap = MAX_PATH;
|
|
||||||
UINT devName_len = GetRawInputDeviceInfoA(hDevice, RIDI_DEVICENAME, devName, &devName_cap);
|
|
||||||
if (0 != ~devName_len) {
|
|
||||||
devName[devName_len] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (desc_len + 3 < len && WIN_LoadHIDDLL()) { // reference counted
|
|
||||||
// important: for devices with exclusive access mode as per
|
|
||||||
// https://learn.microsoft.com/en-us/windows-hardware/drivers/hid/top-level-collections-opened-by-windows-for-system-use
|
|
||||||
// they can only be opened with a desired access of none instead of generic read.
|
|
||||||
HANDLE hFile = CreateFileA(devName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
|
||||||
if (hFile != INVALID_HANDLE_VALUE) {
|
|
||||||
HIDD_ATTRIBUTES attr;
|
|
||||||
WCHAR vend[128], prod[128];
|
|
||||||
attr.VendorID = 0;
|
|
||||||
attr.ProductID = 0;
|
|
||||||
attr.Size = sizeof(attr);
|
|
||||||
vend[0] = 0;
|
|
||||||
prod[0] = 0;
|
|
||||||
SDL_HidD_GetAttributes(hFile, &attr);
|
|
||||||
SDL_HidD_GetManufacturerString(hFile, vend, sizeof(vend));
|
|
||||||
SDL_HidD_GetProductString(hFile, prod, sizeof(prod));
|
|
||||||
CloseHandle(hFile);
|
|
||||||
|
|
||||||
size_t vend_len, prod_len;
|
|
||||||
for (vend_len = 0; vend_len < 128; vend_len++) {
|
|
||||||
if (vend[vend_len] == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (prod_len = 0; prod_len < 128; prod_len++) {
|
|
||||||
if (prod[prod_len] == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (vend_len > 0 || prod_len > 0) {
|
|
||||||
name[desc_len] = ' ';
|
|
||||||
name[desc_len+1] = '(';
|
|
||||||
size_t start = desc_len + 2;
|
|
||||||
size_t n = start;
|
|
||||||
for (size_t i = 0; i < vend_len; i++) {
|
|
||||||
n = start + i;
|
|
||||||
if (n < len) {
|
|
||||||
name[n] = (char)(vend[i] & 0x7f); // TODO: do proper WCHAR conversion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (vend_len > 0) {
|
|
||||||
n += 1;
|
|
||||||
if (n < len) {
|
|
||||||
name[n] = ' ';
|
|
||||||
}
|
|
||||||
n += 1;
|
|
||||||
}
|
|
||||||
size_t m = n;
|
|
||||||
for (size_t i = 0; i < prod_len; i++) {
|
|
||||||
m = n + i;
|
|
||||||
if (m < len) {
|
|
||||||
name[m] = (char)(prod[i] & 0x7f); // TODO: do proper WCHAR conversion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
m += 1;
|
|
||||||
if (m < len) {
|
|
||||||
name[m] = ')';
|
|
||||||
}
|
|
||||||
m += 1;
|
|
||||||
if (m < len) {
|
|
||||||
name[m] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (attr.VendorID && attr.ProductID) {
|
|
||||||
char buf[17];
|
|
||||||
int written = SDL_snprintf(buf, sizeof(buf), " (0x%.4x/0x%.4x)", attr.VendorID, attr.ProductID);
|
|
||||||
buf[16] = '\0'; // just to be safe
|
|
||||||
if (written > 0 && desc_len > 0) {
|
|
||||||
for (size_t i = 0; i < sizeof(buf); i++) {
|
|
||||||
size_t j = desc_len + i;
|
|
||||||
if (j < len) {
|
|
||||||
name[j] = buf[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
WIN_UnloadHIDDLL();
|
|
||||||
}
|
|
||||||
|
|
||||||
name[len-1] = '\0'; // just to be safe
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WIN_CheckKeyboardAndMouseHotplug(SDL_VideoDevice *_this, bool initial_check)
|
void WIN_CheckKeyboardAndMouseHotplug(SDL_VideoDevice *_this, bool initial_check)
|
||||||
|
@ -1030,6 +985,7 @@ void WIN_CheckKeyboardAndMouseHotplug(SDL_VideoDevice *_this, bool initial_check
|
||||||
old_keyboards = SDL_GetKeyboards(&old_keyboard_count);
|
old_keyboards = SDL_GetKeyboards(&old_keyboard_count);
|
||||||
old_mice = SDL_GetMice(&old_mouse_count);
|
old_mice = SDL_GetMice(&old_mouse_count);
|
||||||
|
|
||||||
|
bool hid_loaded = WIN_LoadHIDDLL();
|
||||||
for (UINT i = 0; i < raw_device_count; i++) {
|
for (UINT i = 0; i < raw_device_count; i++) {
|
||||||
RID_DEVICE_INFO rdi;
|
RID_DEVICE_INFO rdi;
|
||||||
char devName[MAX_PATH] = { 0 };
|
char devName[MAX_PATH] = { 0 };
|
||||||
|
@ -1037,7 +993,7 @@ void WIN_CheckKeyboardAndMouseHotplug(SDL_VideoDevice *_this, bool initial_check
|
||||||
UINT nameSize = SDL_arraysize(devName);
|
UINT nameSize = SDL_arraysize(devName);
|
||||||
int vendor = 0, product = 0;
|
int vendor = 0, product = 0;
|
||||||
DWORD dwType = raw_devices[i].dwType;
|
DWORD dwType = raw_devices[i].dwType;
|
||||||
char *instance, *ptr, name[256];
|
char *instance, *ptr, *name;
|
||||||
|
|
||||||
if (dwType != RIM_TYPEKEYBOARD && dwType != RIM_TYPEMOUSE) {
|
if (dwType != RIM_TYPEKEYBOARD && dwType != RIM_TYPEMOUSE) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -1075,8 +1031,9 @@ void WIN_CheckKeyboardAndMouseHotplug(SDL_VideoDevice *_this, bool initial_check
|
||||||
SDL_KeyboardID keyboardID = (Uint32)(uintptr_t)raw_devices[i].hDevice;
|
SDL_KeyboardID keyboardID = (Uint32)(uintptr_t)raw_devices[i].hDevice;
|
||||||
AddDeviceID(keyboardID, &new_keyboards, &new_keyboard_count);
|
AddDeviceID(keyboardID, &new_keyboards, &new_keyboard_count);
|
||||||
if (!HasDeviceID(keyboardID, old_keyboards, old_keyboard_count)) {
|
if (!HasDeviceID(keyboardID, old_keyboards, old_keyboard_count)) {
|
||||||
GetDeviceName(raw_devices[i].hDevice, devinfo, instance, name, sizeof(name));
|
name = GetDeviceName(raw_devices[i].hDevice, devinfo, instance, hid_loaded);
|
||||||
SDL_AddKeyboard(keyboardID, name, send_event);
|
SDL_AddKeyboard(keyboardID, name, send_event);
|
||||||
|
SDL_free(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1085,8 +1042,9 @@ void WIN_CheckKeyboardAndMouseHotplug(SDL_VideoDevice *_this, bool initial_check
|
||||||
SDL_MouseID mouseID = (Uint32)(uintptr_t)raw_devices[i].hDevice;
|
SDL_MouseID mouseID = (Uint32)(uintptr_t)raw_devices[i].hDevice;
|
||||||
AddDeviceID(mouseID, &new_mice, &new_mouse_count);
|
AddDeviceID(mouseID, &new_mice, &new_mouse_count);
|
||||||
if (!HasDeviceID(mouseID, old_mice, old_mouse_count)) {
|
if (!HasDeviceID(mouseID, old_mice, old_mouse_count)) {
|
||||||
GetDeviceName(raw_devices[i].hDevice, devinfo, instance, name, sizeof(name));
|
name = GetDeviceName(raw_devices[i].hDevice, devinfo, instance, hid_loaded);
|
||||||
SDL_AddMouse(mouseID, name, send_event);
|
SDL_AddMouse(mouseID, name, send_event);
|
||||||
|
SDL_free(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1094,6 +1052,9 @@ void WIN_CheckKeyboardAndMouseHotplug(SDL_VideoDevice *_this, bool initial_check
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (hid_loaded) {
|
||||||
|
WIN_UnloadHIDDLL();
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = old_keyboard_count; i--;) {
|
for (int i = old_keyboard_count; i--;) {
|
||||||
if (!HasDeviceID(old_keyboards[i], new_keyboards, new_keyboard_count)) {
|
if (!HasDeviceID(old_keyboards[i], new_keyboards, new_keyboard_count)) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue