From c44473ba733153b3b33f0697f7e0dfea3114d135 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 12 Mar 2020 19:47:30 -0700 Subject: [PATCH] Unified code to standardize joystick names --- src/joystick/SDL_joystick.c | 132 +++++++++++++++++----- src/joystick/SDL_joystick_c.h | 9 +- src/joystick/android/SDL_sysjoystick.c | 4 +- src/joystick/darwin/SDL_sysjoystick.c | 40 ++----- src/joystick/emscripten/SDL_sysjoystick.c | 2 +- src/joystick/haiku/SDL_haikujoystick.cc | 2 +- src/joystick/hidapi/SDL_hidapijoystick.c | 32 +----- src/joystick/iphoneos/SDL_sysjoystick.m | 2 +- src/joystick/linux/SDL_sysjoystick.c | 58 ++++------ src/joystick/windows/SDL_dinputjoystick.c | 60 +++++----- src/joystick/windows/SDL_xinputjoystick.c | 14 +-- 11 files changed, 182 insertions(+), 173 deletions(-) diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index 95aac9c6f67f7..d010c7efe4c0c 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -278,23 +278,6 @@ SDL_GetDriverAndJoystickIndex(int device_index, SDL_JoystickDriver **driver, int return SDL_FALSE; } -/* - * Perform any needed fixups for joystick names - */ -static const char * -SDL_FixupJoystickName(const char *name) -{ - if (name) { - const char *skip_prefix = "NVIDIA Corporation "; - - if (SDL_strncmp(name, skip_prefix, SDL_strlen(skip_prefix)) == 0) { - name += SDL_strlen(skip_prefix); - } - } - return name; -} - - /* * Get the implementation dependent name of a joystick */ @@ -306,7 +289,7 @@ SDL_JoystickNameForIndex(int device_index) SDL_LockJoysticks(); if (SDL_GetDriverAndJoystickIndex(device_index, &driver, &device_index)) { - name = SDL_FixupJoystickName(driver->GetDeviceName(device_index)); + name = driver->GetDeviceName(device_index); } SDL_UnlockJoysticks(); @@ -721,7 +704,7 @@ SDL_JoystickName(SDL_Joystick * joystick) return NULL; } - return SDL_FixupJoystickName(joystick->name); + return joystick->name; } /** @@ -1369,23 +1352,112 @@ void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *prod } } -const char * -SDL_GetCustomJoystickManufacturer(const char *manufacturer) +static int +PrefixMatch(const char *a, const char *b) { - if (manufacturer) { - if (SDL_strcmp(manufacturer, "Performance Designed Products") == 0) { - return "PDP"; - } else if (SDL_strcmp(manufacturer, "HORI CO.,LTD") == 0) { - return "HORI"; + int matchlen = 0; + while (*a && *b) { + if (*a++ == *b++) { + ++matchlen; + } else { + break; } } - return manufacturer; + return matchlen; } -const char * -SDL_GetCustomJoystickName(Uint16 vendor, Uint16 product) +char * +SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, const char *product_name) { - return GuessControllerName(vendor, product); + static struct { + const char *prefix; + const char *replacement; + } replacements[] = { + { "NVIDIA Corporation ", "" }, + { "Performance Designed Products", "PDP" }, + { "HORI CO.,LTD", "HORI" }, + }; + const char *custom_name; + char *name; + size_t i, len; + + custom_name = GuessControllerName(vendor, product); + if (custom_name) { + return SDL_strdup(custom_name); + } + + 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) { + return NULL; + } + SDL_snprintf(name, len, "%s %s", vendor_name, product_name); + } else if (*product_name) { + name = SDL_strdup(product_name); + } else if (vendor || product) { + len = (6 + 1 + 6 + 1); + name = (char *)SDL_malloc(len); + if (!name) { + return NULL; + } + SDL_snprintf(name, len, "0x%.4x/0x%.4x", vendor, product); + } else { + name = SDL_strdup("Controller"); + } + + /* 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; + } + } + + /* Remove duplicate manufacturer in the name */ + for (i = 0; i < (len - 1); ++i) { + int matchlen = PrefixMatch(name, &name[i]); + if (matchlen > 0 && name[matchlen - 1] == ' ') { + SDL_memmove(name, name+matchlen, len-matchlen+1); + len -= matchlen; + break; + } + } + + /* 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); + SDL_memcpy(name, replacements[i].replacement, replacementlen); + SDL_memmove(name+replacementlen, name+prefixlen, (len-prefixlen+1)); + break; + } + } + + return name; } SDL_GameControllerType diff --git a/src/joystick/SDL_joystick_c.h b/src/joystick/SDL_joystick_c.h index 1ba4dee441a9a..e03bdd26bb364 100644 --- a/src/joystick/SDL_joystick_c.h +++ b/src/joystick/SDL_joystick_c.h @@ -52,11 +52,10 @@ extern int SDL_JoystickGetDeviceIndexFromInstanceID(SDL_JoystickID instance_id); /* Function to extract information from an SDL joystick GUID */ extern void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *product, Uint16 *version); -/* Function to get a custom name for a controller manufacturer, if it's available */ -extern const char *SDL_GetCustomJoystickManufacturer(const char *manufacturer); - -/* Function to get a custom name for a controller, if it's available */ -extern const char *SDL_GetCustomJoystickName(Uint16 vendor, Uint16 product); +/* Function to standardize the name for a controller + This should be freed with SDL_free() when no longer needed + */ +extern char *SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, const char *product_name); /* Function to return the type of a controller */ extern SDL_GameControllerType SDL_GetJoystickGameControllerTypeFromGUID(SDL_JoystickGUID guid, const char *name); diff --git a/src/joystick/android/SDL_sysjoystick.c b/src/joystick/android/SDL_sysjoystick.c index d0c6262d6c1d1..6b8b3bbc11a8c 100644 --- a/src/joystick/android/SDL_sysjoystick.c +++ b/src/joystick/android/SDL_sysjoystick.c @@ -410,7 +410,7 @@ Android_AddJoystick(int device_id, const char *name, const char *desc, int vendo SDL_zerop(item); item->guid = guid; item->device_id = device_id; - item->name = SDL_strdup(name); + item->name = SDL_CreateJoystickName(vendor_id, product_id, NULL, name); if (item->name == NULL) { SDL_free(item); return -1; @@ -443,7 +443,7 @@ Android_AddJoystick(int device_id, const char *name, const char *desc, int vendo SDL_PrivateJoystickAdded(item->device_instance); #ifdef DEBUG_JOYSTICK - SDL_Log("Added joystick %s with device_id %d", name, device_id); + SDL_Log("Added joystick %s with device_id %d", item->name, device_id); #endif return numjoysticks; diff --git a/src/joystick/darwin/SDL_sysjoystick.c b/src/joystick/darwin/SDL_sysjoystick.c index 461a85f18bf31..f2240a2ab7673 100644 --- a/src/joystick/darwin/SDL_sysjoystick.c +++ b/src/joystick/darwin/SDL_sysjoystick.c @@ -404,7 +404,7 @@ GetDeviceInfo(IOHIDDeviceRef hidDevice, recDevice *pDevice) Sint32 vendor = 0; Sint32 product = 0; Sint32 version = 0; - const char *name; + char *name; const char *manufacturer_remapped; char manufacturer_string[256]; char product_string[256]; @@ -460,36 +460,18 @@ GetDeviceInfo(IOHIDDeviceRef hidDevice, recDevice *pDevice) } /* get device name */ - name = SDL_GetCustomJoystickName(vendor, product); + refCF = IOHIDDeviceGetProperty(hidDevice, CFSTR(kIOHIDManufacturerKey)); + if ((!refCF) || (!CFStringGetCString(refCF, manufacturer_string, sizeof(manufacturer_string), kCFStringEncodingUTF8))) { + manufacturer_string[0] = '\0'; + } + refCF = IOHIDDeviceGetProperty(hidDevice, CFSTR(kIOHIDProductKey)); + if ((!refCF) || (!CFStringGetCString(refCF, product_string, sizeof(product_string), kCFStringEncodingUTF8))) { + product_string[0] = '\0'; + } + name = SDL_CreateJoystickName(vendor, product, manufacturer_string, product_string); if (name) { SDL_strlcpy(pDevice->product, name, sizeof(pDevice->product)); - } else { - refCF = IOHIDDeviceGetProperty(hidDevice, CFSTR(kIOHIDManufacturerKey)); - if ((!refCF) || (!CFStringGetCString(refCF, manufacturer_string, sizeof(manufacturer_string), kCFStringEncodingUTF8))) { - manufacturer_string[0] = '\0'; - } - refCF = IOHIDDeviceGetProperty(hidDevice, CFSTR(kIOHIDProductKey)); - if ((!refCF) || (!CFStringGetCString(refCF, product_string, sizeof(product_string), kCFStringEncodingUTF8))) { - SDL_strlcpy(product_string, "Unidentified joystick", sizeof(product_string)); - } - for (i = (int)SDL_strlen(manufacturer_string) - 1; i > 0; --i) { - if (SDL_isspace(manufacturer_string[i])) { - manufacturer_string[i] = '\0'; - } else { - break; - } - } - - manufacturer_remapped = SDL_GetCustomJoystickManufacturer(manufacturer_string); - if (manufacturer_remapped != manufacturer_string) { - SDL_strlcpy(manufacturer_string, manufacturer_remapped, sizeof(manufacturer_string)); - } - - if (SDL_strncasecmp(manufacturer_string, product_string, SDL_strlen(manufacturer_string)) == 0) { - SDL_strlcpy(pDevice->product, product_string, sizeof(pDevice->product)); - } else { - SDL_snprintf(pDevice->product, sizeof(pDevice->product), "%s %s", manufacturer_string, product_string); - } + SDL_free(name); } #ifdef SDL_JOYSTICK_HIDAPI diff --git a/src/joystick/emscripten/SDL_sysjoystick.c b/src/joystick/emscripten/SDL_sysjoystick.c index 97b8a9e0cebb2..a9fd38b09383a 100644 --- a/src/joystick/emscripten/SDL_sysjoystick.c +++ b/src/joystick/emscripten/SDL_sysjoystick.c @@ -60,7 +60,7 @@ Emscripten_JoyStickConnected(int eventType, const EmscriptenGamepadEvent *gamepa SDL_zerop(item); item->index = gamepadEvent->index; - item->name = SDL_strdup(gamepadEvent->id); + item->name = SDL_CreateJoystickName(0, 0, NULL, gamepadEvent->id); if ( item->name == NULL ) { SDL_free(item); return 1; diff --git a/src/joystick/haiku/SDL_haikujoystick.cc b/src/joystick/haiku/SDL_haikujoystick.cc index ae8754e5afc4a..70eefba4717a4 100644 --- a/src/joystick/haiku/SDL_haikujoystick.cc +++ b/src/joystick/haiku/SDL_haikujoystick.cc @@ -75,7 +75,7 @@ extern "C" BString stick_name; joystick.GetControllerName(&stick_name); SDL_joyport[numjoysticks] = SDL_strdup(name); - SDL_joyname[numjoysticks] = SDL_strdup(stick_name.String()); + SDL_joyname[numjoysticks] = SDL_CreateJoystickName(0, 0, NULL, stick_name.String()); numjoysticks++; joystick.Close(); } diff --git a/src/joystick/hidapi/SDL_hidapijoystick.c b/src/joystick/hidapi/SDL_hidapijoystick.c index 579d0965c2166..65bb7ff270b8f 100644 --- a/src/joystick/hidapi/SDL_hidapijoystick.c +++ b/src/joystick/hidapi/SDL_hidapijoystick.c @@ -698,14 +698,7 @@ HIDAPI_AddDevice(struct hid_device_info *info) device->dev_lock = SDL_CreateMutex(); /* Need the device name before getting the driver to know whether to ignore this device */ - if (!device->name) { - const char *name = SDL_GetCustomJoystickName(device->vendor_id, device->product_id); - if (name) { - device->name = SDL_strdup(name); - } - } - if (!device->name && info->manufacturer_string && info->product_string) { - const char *manufacturer_remapped; + { char *manufacturer_string = SDL_iconv_string("UTF-8", "WCHAR_T", (char*)info->manufacturer_string, (SDL_wcslen(info->manufacturer_string)+1)*sizeof(wchar_t)); char *product_string = SDL_iconv_string("UTF-8", "WCHAR_T", (char*)info->product_string, (SDL_wcslen(info->product_string)+1)*sizeof(wchar_t)); if (!manufacturer_string && !product_string) { @@ -718,39 +711,20 @@ HIDAPI_AddDevice(struct hid_device_info *info) } } - manufacturer_remapped = SDL_GetCustomJoystickManufacturer(manufacturer_string); - if (manufacturer_remapped != manufacturer_string) { - SDL_free(manufacturer_string); - manufacturer_string = SDL_strdup(manufacturer_remapped); - } + device->name = SDL_CreateJoystickName(device->vendor_id, device->product_id, manufacturer_string, product_string); - if (manufacturer_string && product_string) { - size_t name_size = (SDL_strlen(manufacturer_string) + 1 + SDL_strlen(product_string) + 1); - device->name = (char *)SDL_malloc(name_size); - if (device->name) { - if (SDL_strncasecmp(manufacturer_string, product_string, SDL_strlen(manufacturer_string)) == 0) { - SDL_strlcpy(device->name, product_string, name_size); - } else { - SDL_snprintf(device->name, name_size, "%s %s", manufacturer_string, product_string); - } - } - } if (manufacturer_string) { SDL_free(manufacturer_string); } if (product_string) { SDL_free(product_string); } - } - if (!device->name) { - size_t name_size = (6 + 1 + 6 + 1); - device->name = (char *)SDL_malloc(name_size); + if (!device->name) { SDL_free(device->path); SDL_free(device); return; } - SDL_snprintf(device->name, name_size, "0x%.4x/0x%.4x", info->vendor_id, info->product_id); } /* Add it to the list */ diff --git a/src/joystick/iphoneos/SDL_sysjoystick.m b/src/joystick/iphoneos/SDL_sysjoystick.m index d14e047bb56dc..12657ff10783a 100644 --- a/src/joystick/iphoneos/SDL_sysjoystick.m +++ b/src/joystick/iphoneos/SDL_sysjoystick.m @@ -125,7 +125,7 @@ @interface GCMicroGamepad (SDL) name = "MFi Gamepad"; } - device->name = SDL_strdup(name); + device->name = SDL_CreateJoystickName(0, 0, NULL, name); if (controller.extendedGamepad) { GCExtendedGamepad *gamepad = controller.extendedGamepad; diff --git a/src/joystick/linux/SDL_sysjoystick.c b/src/joystick/linux/SDL_sysjoystick.c index fcfc0f3ba8333..2321ba23d6544 100644 --- a/src/joystick/linux/SDL_sysjoystick.c +++ b/src/joystick/linux/SDL_sysjoystick.c @@ -88,20 +88,6 @@ static time_t last_input_dir_mtime; (((1UL << ((nr) % (sizeof(long) * 8))) & ((addr)[(nr) / (sizeof(long) * 8)])) != 0) #define NBITS(x) ((((x)-1)/(sizeof(long) * 8))+1) -static int -PrefixMatch(const char *a, const char *b) -{ - int matchlen = 0; - while (*a && *b) { - if (*a++ == *b++) { - ++matchlen; - } else { - break; - } - } - return matchlen; -} - static void FixupDeviceInfoForMapping(int fd, struct input_id *inpid) { @@ -120,12 +106,12 @@ FixupDeviceInfoForMapping(int fd, struct input_id *inpid) static int -IsJoystick(int fd, char *namebuf, const size_t namebuflen, SDL_JoystickGUID *guid) +IsJoystick(int fd, char **name_return, SDL_JoystickGUID *guid) { struct input_id inpid; Uint16 *guid16 = (Uint16 *)guid->data; - const char *name; - const char *spot; + char *name; + char product_string[128]; #if !SDL_USE_LIBUDEV /* When udev is enabled we only get joystick devices here, so there's no need to test them */ @@ -149,27 +135,19 @@ IsJoystick(int fd, char *namebuf, const size_t namebuflen, SDL_JoystickGUID *gui return 0; } - name = SDL_GetCustomJoystickName(inpid.vendor, inpid.product); - if (name) { - SDL_strlcpy(namebuf, name, namebuflen); - } else { - if (ioctl(fd, EVIOCGNAME(namebuflen), namebuf) < 0) { - return 0; - } + if (ioctl(fd, EVIOCGNAME(sizeof(product_string)), product_string) < 0) { + return 0; + } - /* Remove duplicate manufacturer in the name */ - for (spot = namebuf + 1; *spot; ++spot) { - int matchlen = PrefixMatch(namebuf, spot); - if (matchlen > 0 && spot[matchlen - 1] == ' ') { - SDL_memmove(namebuf, spot, SDL_strlen(spot)+1); - break; - } - } + name = SDL_CreateJoystickName(inpid.vendor, inpid.product, NULL, product_string); + if (!name) { + return 0; } #ifdef SDL_JOYSTICK_HIDAPI - if (HIDAPI_IsDevicePresent(inpid.vendor, inpid.product, inpid.version, namebuf)) { + if (HIDAPI_IsDevicePresent(inpid.vendor, inpid.product, inpid.version, name)) { /* The HIDAPI driver is taking care of this device */ + SDL_free(name); return 0; } #endif @@ -177,7 +155,7 @@ IsJoystick(int fd, char *namebuf, const size_t namebuflen, SDL_JoystickGUID *gui FixupDeviceInfoForMapping(fd, &inpid); #ifdef DEBUG_JOYSTICK - printf("Joystick: %s, bustype = %d, vendor = 0x%.4x, product = 0x%.4x, version = %d\n", namebuf, inpid.bustype, inpid.vendor, inpid.product, inpid.version); + printf("Joystick: %s, bustype = %d, vendor = 0x%.4x, product = 0x%.4x, version = %d\n", name, inpid.bustype, inpid.vendor, inpid.product, inpid.version); #endif SDL_memset(guid->data, 0, sizeof(guid->data)); @@ -195,12 +173,14 @@ IsJoystick(int fd, char *namebuf, const size_t namebuflen, SDL_JoystickGUID *gui *guid16++ = SDL_SwapLE16(inpid.version); *guid16++ = 0; } else { - SDL_strlcpy((char*)guid16, namebuf, sizeof(guid->data) - 4); + SDL_strlcpy((char*)guid16, name, sizeof(guid->data) - 4); } - if (SDL_ShouldIgnoreJoystick(namebuf, *guid)) { + if (SDL_ShouldIgnoreJoystick(name, *guid)) { + SDL_free(name); return 0; } + *name_return = name; return 1; } @@ -236,7 +216,7 @@ MaybeAddDevice(const char *path) struct stat sb; int fd = -1; int isstick = 0; - char namebuf[128]; + char *name = NULL; SDL_JoystickGUID guid; SDL_joylist_item *item; @@ -264,7 +244,7 @@ MaybeAddDevice(const char *path) printf("Checking %s\n", path); #endif - isstick = IsJoystick(fd, namebuf, sizeof (namebuf), &guid); + isstick = IsJoystick(fd, &name, &guid); close(fd); if (!isstick) { return -1; @@ -278,7 +258,7 @@ MaybeAddDevice(const char *path) SDL_zerop(item); item->devnum = sb.st_rdev; item->path = SDL_strdup(path); - item->name = SDL_strdup(namebuf); + item->name = name; item->guid = guid; if ((item->path == NULL) || (item->name == NULL)) { diff --git a/src/joystick/windows/SDL_dinputjoystick.c b/src/joystick/windows/SDL_dinputjoystick.c index 5c5e21e8889db..d1307710ad534 100644 --- a/src/joystick/windows/SDL_dinputjoystick.c +++ b/src/joystick/windows/SDL_dinputjoystick.c @@ -244,7 +244,7 @@ static const IID CLSID_WbemLocator = { 0x4590f811, 0x1d3a, 0x11d0,{ 0x89, 0x1f, static const IID IID_IWbemLocator = { 0xdc12a687, 0x737f, 0x11cf,{ 0x88, 0x4d, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24 } }; static SDL_bool -WIN_IsXInputDevice(const GUID* pGuidProductFromDirectInput) +WIN_IsXInputDevice(LPTSTR *name, const GUID* pGuidProductFromDirectInput) { IWbemLocator* pIWbemLocator = NULL; IEnumWbemClassObject* pEnumDevices = NULL; @@ -259,6 +259,17 @@ WIN_IsXInputDevice(const GUID* pGuidProductFromDirectInput) VARIANT var; HRESULT hr; + if (!SDL_XINPUT_Enabled()) { + return SDL_FALSE; + } + + if (SDL_wcsstr(name, " XINPUT ") != NULL) { + /* This is a duplicate interface for a controller that will show up with XInput, + e.g. Xbox One Elite Series 2 in Bluetooth mode. + */ + return SDL_TRUE; + } + SDL_zeroa(pDevices); // Create WMI @@ -363,7 +374,7 @@ WIN_IsXInputDevice(const GUID* pGuidProductFromDirectInput) #endif /* 0 */ static SDL_bool -SDL_IsXInputDevice(const GUID* pGuidProductFromDirectInput) +SDL_IsXInputDevice(LPTSTR *name, const GUID* pGuidProductFromDirectInput) { UINT i; @@ -371,6 +382,13 @@ SDL_IsXInputDevice(const GUID* pGuidProductFromDirectInput) return SDL_FALSE; } + if (SDL_wcsstr(name, " XINPUT ") != NULL) { + /* This is a duplicate interface for a controller that will show up with XInput, + e.g. Xbox One Elite Series 2 in Bluetooth mode. + */ + return SDL_TRUE; + } + if (SDL_memcmp(&pGuidProductFromDirectInput->Data4[2], "PIDVID", 6) == 0) { Uint16 vendor_id = (Uint16)LOWORD(pGuidProductFromDirectInput->Data1); Uint16 product_id = (Uint16)HIWORD(pGuidProductFromDirectInput->Data1); @@ -521,7 +539,7 @@ EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) Uint16 product = 0; Uint16 version = 0; WCHAR hidPath[MAX_PATH]; - const char *name; + char *name; if (devtype == DI8DEVTYPE_SUPPLEMENTAL) { /* Add any supplemental devices that should be ignored here */ @@ -539,7 +557,7 @@ EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) } } - if (SDL_IsXInputDevice(&pdidInstance->guidProduct)) { + if (SDL_IsXInputDevice(pdidInstance->tszProductName, &pdidInstance->guidProduct)) { return DIENUM_CONTINUE; /* ignore XInput devices here, keep going. */ } @@ -609,12 +627,22 @@ EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) SDL_memcpy(&pNewJoystick->dxdevice, pdidInstance, sizeof(DIDEVICEINSTANCE)); SDL_memset(pNewJoystick->guid.data, 0, sizeof(pNewJoystick->guid.data)); - guid16 = (Uint16 *)pNewJoystick->guid.data; if (SDL_memcmp(&pdidInstance->guidProduct.Data4[2], "PIDVID", 6) == 0) { vendor = (Uint16)LOWORD(pdidInstance->guidProduct.Data1); product = (Uint16)HIWORD(pdidInstance->guidProduct.Data1); - version = 0; + } + + name = WIN_StringToUTF8(pdidInstance->tszProductName); + pNewJoystick->joystickname = SDL_CreateJoystickName(vendor, product, NULL, name); + SDL_free(name); + if (!pNewJoystick->joystickname) { + SDL_free(pNewJoystick); + return DIENUM_CONTINUE; /* better luck next time? */ + } + + guid16 = (Uint16 *)pNewJoystick->guid.data; + if (SDL_memcmp(&pdidInstance->guidProduct.Data4[2], "PIDVID", 6) == 0) { *guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_USB); *guid16++ = 0; *guid16++ = SDL_SwapLE16(vendor); @@ -629,26 +657,6 @@ EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) SDL_strlcpy((char*)guid16, pNewJoystick->joystickname, sizeof(pNewJoystick->guid.data) - 4); } - name = SDL_GetCustomJoystickName(vendor, product); - if (name) { - pNewJoystick->joystickname = SDL_strdup(name); - } else { - pNewJoystick->joystickname = WIN_StringToUTF8(pdidInstance->tszProductName); - } - if (!pNewJoystick->joystickname) { - SDL_free(pNewJoystick); - return DIENUM_CONTINUE; /* better luck next time? */ - } - - if (SDL_strstr(pNewJoystick->joystickname, " XINPUT ") != NULL) { - /* This is a duplicate interface for a controller that will show up with XInput, - e.g. Xbox One Elite Series 2 in Bluetooth mode. - */ - SDL_free(pNewJoystick->joystickname); - SDL_free(pNewJoystick); - return DIENUM_CONTINUE; - } - if (SDL_ShouldIgnoreJoystick(pNewJoystick->joystickname, pNewJoystick->guid)) { SDL_free(pNewJoystick->joystickname); SDL_free(pNewJoystick); diff --git a/src/joystick/windows/SDL_xinputjoystick.c b/src/joystick/windows/SDL_xinputjoystick.c index c863b0259f011..1df7c256244b5 100644 --- a/src/joystick/windows/SDL_xinputjoystick.c +++ b/src/joystick/windows/SDL_xinputjoystick.c @@ -71,10 +71,10 @@ SDL_XINPUT_JoystickInit(void) return 0; } -static char * +static const char * GetXInputName(const Uint8 userid, BYTE SubType) { - char name[32]; + static char name[32]; if (SDL_XInputUseOldJoystickMapping()) { SDL_snprintf(name, sizeof(name), "X360 Controller #%u", 1 + userid); @@ -111,7 +111,7 @@ GetXInputName(const Uint8 userid, BYTE SubType) break; } } - return SDL_strdup(name); + return name; } /* We can't really tell what device is being used for XInput, but we can guess @@ -274,13 +274,7 @@ AddXInputDevice(Uint8 userid, BYTE SubType, JoyStick_DeviceData **pContext) } pNewJoystick->SubType = SubType; pNewJoystick->XInputUserId = userid; - - name = SDL_GetCustomJoystickName(vendor, product); - if (name) { - pNewJoystick->joystickname = SDL_strdup(name); - } else { - pNewJoystick->joystickname = GetXInputName(userid, SubType); - } + pNewJoystick->joystickname = SDL_CreateJoystickName(vendor, product, NULL, GetXInputName(userid, SubType)); if (!pNewJoystick->joystickname) { SDL_free(pNewJoystick); return; /* better luck next time? */