Commit 1031231b2922142940eaa2c26d9debe17e5e5f09

Sam Lantinga 2020-12-03T18:17:03

Fixed duplicating a device between XInput and HIDAPI

diff --git a/src/joystick/hidapi/SDL_hidapijoystick.c b/src/joystick/hidapi/SDL_hidapijoystick.c
index 53442b5..5684e55 100644
--- a/src/joystick/hidapi/SDL_hidapijoystick.c
+++ b/src/joystick/hidapi/SDL_hidapijoystick.c
@@ -443,7 +443,7 @@ HIDAPI_GetDeviceDriver(SDL_HIDAPI_Device *device)
         return NULL;
     }
 
-	if (device->vendor_id != USB_VENDOR_VALVE) {
+    if (device->vendor_id != USB_VENDOR_VALVE) {
         if (device->usage_page && device->usage_page != USAGE_PAGE_GENERIC_DESKTOP) {
             return NULL;
         }
@@ -587,7 +587,7 @@ HIDAPI_JoystickInit(void)
     }
 
 #if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__TVOS__)
-	/* The hidapi framwork is weak-linked on Apple platforms */
+    /* The hidapi framwork is weak-linked on Apple platforms */
     int HID_API_EXPORT HID_API_CALL hid_init(void) __attribute__((weak_import));
 
     if (hid_init == NULL) {
@@ -897,16 +897,23 @@ HIDAPI_IsEquivalentToDevice(Uint16 vendor_id, Uint16 product_id, SDL_HIDAPI_Devi
 
     if (vendor_id == USB_VENDOR_MICROSOFT) {
         /* If we're looking for the wireless XBox 360 controller, also look for the dongle */
-       if (product_id == 0x02a1 && device->product_id == 0x0719) {
-           return SDL_TRUE;
-       }
-
-       /* If we're looking for the raw input Xbox One controller, match it against any other Xbox One controller */
-       if (vendor_id == USB_VENDOR_MICROSOFT &&
-           product_id == USB_PRODUCT_XBOX_ONE_RAW_INPUT_CONTROLLER &&
-           SDL_GetJoystickGameControllerType(device->name, device->vendor_id, device->product_id, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol) == SDL_CONTROLLER_TYPE_XBOXONE) {
-           return SDL_TRUE;
-       }
+        if (product_id == 0x02a1 && device->product_id == 0x0719) {
+            return SDL_TRUE;
+        }
+
+        /* If we're looking for the raw input Xbox One controller, match it against any other Xbox One controller */
+        if (product_id == USB_PRODUCT_XBOX_ONE_RAW_INPUT_CONTROLLER &&
+            SDL_GetJoystickGameControllerType(device->name, device->vendor_id, device->product_id, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol) == SDL_CONTROLLER_TYPE_XBOXONE) {
+            return SDL_TRUE;
+        }
+
+        /* If we're looking for an XInput controller, match it against any other Xbox controller */
+        if (product_id == USB_PRODUCT_XBOX_ONE_XINPUT_CONTROLLER) {
+            SDL_GameControllerType type = SDL_GetJoystickGameControllerType(device->name, device->vendor_id, device->product_id, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol);
+            if (type == SDL_CONTROLLER_TYPE_XBOX360 || type == SDL_CONTROLLER_TYPE_XBOXONE) {
+                return SDL_TRUE;
+            }
+        }
     }
     return SDL_FALSE;
 }
diff --git a/src/joystick/usb_ids.h b/src/joystick/usb_ids.h
index 32e7362..c39ff69 100644
--- a/src/joystick/usb_ids.h
+++ b/src/joystick/usb_ids.h
@@ -53,6 +53,7 @@
 #define USB_PRODUCT_XBOX_ONE_SERIES_X                   0x0b12
 #define USB_PRODUCT_XBOX_ONE_SERIES_X_BLUETOOTH         0x0b13
 #define USB_PRODUCT_XBOX_ONE_RAW_INPUT_CONTROLLER       0x02ff
+#define USB_PRODUCT_XBOX_ONE_XINPUT_CONTROLLER          0x02fe    /* Made up product ID for XInput */
 
 /* USB usage pages */
 #define USB_USAGEPAGE_GENERIC_DESKTOP   0x0001
diff --git a/src/joystick/windows/SDL_xinputjoystick.c b/src/joystick/windows/SDL_xinputjoystick.c
index bd71c54..77e06a6 100644
--- a/src/joystick/windows/SDL_xinputjoystick.c
+++ b/src/joystick/windows/SDL_xinputjoystick.c
@@ -294,7 +294,8 @@ AddXInputDevice(Uint8 userid, BYTE SubType, JoyStick_DeviceData **pContext)
     }
 
 #ifdef SDL_JOYSTICK_HIDAPI
-    if (HIDAPI_IsDevicePresent(vendor, product, version, pNewJoystick->joystickname)) {
+    /* Since we're guessing about the VID/PID, use a hard-coded VID/PID to represent XInput */
+    if (HIDAPI_IsDevicePresent(USB_VENDOR_MICROSOFT, USB_PRODUCT_XBOX_ONE_XINPUT_CONTROLLER, version, pNewJoystick->joystickname)) {
         /* The HIDAPI driver is taking care of this device */
         SDL_free(pNewJoystick);
         return;