Browse Source

Unified code to standardize joystick names

Sam Lantinga 5 years ago
parent
commit
c44473ba73

+ 102 - 30
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

+ 4 - 5
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);

+ 2 - 2
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;

+ 11 - 29
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

+ 1 - 1
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;

+ 1 - 1
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();
                 }

+ 3 - 29
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 */

+ 1 - 1
src/joystick/iphoneos/SDL_sysjoystick.m

@@ -125,7 +125,7 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle
         name = "MFi Gamepad";
     }
 
-    device->name = SDL_strdup(name);
+    device->name = SDL_CreateJoystickName(0, 0, NULL, name);
 
     if (controller.extendedGamepad) {
         GCExtendedGamepad *gamepad = controller.extendedGamepad;

+ 19 - 39
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)) {

+ 34 - 26
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 @@ LCleanup:
 #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);

+ 4 - 10
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? */