Fixed using more than one Xbox Bluetooth controller
authorSam Lantinga <slouken@libsdl.org>
Wed, 04 Mar 2020 09:42:08 -0800
changeset 135862f5e3f0be62c
parent 13585 32a52ab3133c
child 13587 9944a0c7c355
Fixed using more than one Xbox Bluetooth controller
Don't prevent duplicate devices using hidraw, instead libusb takes precedence and all hidraw devices that aren't handled by libusb are available
src/hidapi/SDL_hidapi.c
     1.1 --- a/src/hidapi/SDL_hidapi.c	Tue Mar 03 17:56:33 2020 -0800
     1.2 +++ b/src/hidapi/SDL_hidapi.c	Wed Mar 04 09:42:08 2020 -0800
     1.3 @@ -536,73 +536,52 @@
     1.4  
     1.5  struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id)
     1.6  {
     1.7 +#ifdef SDL_LIBUSB_DYNAMIC
     1.8 +    struct LIBUSB_hid_device_info *usb_devs = NULL;
     1.9 +    struct LIBUSB_hid_device_info *usb_dev;
    1.10 +#endif
    1.11  #if HAVE_PLATFORM_BACKEND
    1.12      struct PLATFORM_hid_device_info *raw_devs = NULL;
    1.13      struct PLATFORM_hid_device_info *raw_dev;
    1.14 -#endif /* HAVE_PLATFORM_BACKEND */
    1.15 +#endif
    1.16      struct hid_device_info *devs = NULL, *last = NULL, *new_dev;
    1.17 -    SDL_bool bFound;
    1.18  
    1.19      if (SDL_hidapi_wasinit == SDL_FALSE) {
    1.20          hid_init();
    1.21      }
    1.22  
    1.23 +#ifdef SDL_LIBUSB_DYNAMIC
    1.24 +    if (libusb_ctx.libhandle) {
    1.25 +        usb_devs = LIBUSB_hid_enumerate(vendor_id, product_id);
    1.26 +        for (usb_dev = usb_devs; usb_dev; usb_dev = usb_dev->next) {
    1.27 +            new_dev = (struct hid_device_info*) SDL_malloc(sizeof(struct hid_device_info));
    1.28 +            LIBUSB_CopyHIDDeviceInfo(usb_dev, new_dev);
    1.29 +
    1.30 +            if (last != NULL) {
    1.31 +                last->next = new_dev;
    1.32 +            } else {
    1.33 +                devs = new_dev;
    1.34 +            }
    1.35 +            last = new_dev;
    1.36 +        }
    1.37 +    }
    1.38 +#endif /* SDL_LIBUSB_DYNAMIC */
    1.39 +
    1.40  #if HAVE_PLATFORM_BACKEND
    1.41      if (udev_ctx) {
    1.42          raw_devs = PLATFORM_hid_enumerate(vendor_id, product_id);
    1.43 -    }
    1.44 -#endif /* HAVE_PLATFORM_BACKEND */
    1.45 -
    1.46 +        for (raw_dev = raw_devs; raw_dev; raw_dev = raw_dev->next) {
    1.47 +            SDL_bool bFound = SDL_FALSE;
    1.48  #ifdef SDL_LIBUSB_DYNAMIC
    1.49 -    if (libusb_ctx.libhandle) {
    1.50 -        struct LIBUSB_hid_device_info *usb_devs = LIBUSB_hid_enumerate(vendor_id, product_id);
    1.51 -        struct LIBUSB_hid_device_info *usb_dev;
    1.52 -        for (usb_dev = usb_devs; usb_dev; usb_dev = usb_dev->next) {
    1.53 -            bFound = SDL_FALSE;
    1.54 -#if HAVE_PLATFORM_BACKEND
    1.55 -            for (raw_dev = raw_devs; raw_dev; raw_dev = raw_dev->next) {
    1.56 -                if (raw_dev->vendor_id == 0x057e && raw_dev->product_id == 0x0337) {
    1.57 -                    /* The GameCube adapter is handled by the USB HIDAPI driver */
    1.58 -                    continue;
    1.59 -                }
    1.60 -                if (usb_dev->vendor_id == raw_dev->vendor_id &&
    1.61 -                    usb_dev->product_id == raw_dev->product_id &&
    1.62 -                    (raw_dev->interface_number < 0 || usb_dev->interface_number == raw_dev->interface_number)) {
    1.63 +            for (usb_dev = usb_devs; usb_dev; usb_dev = usb_dev->next) {
    1.64 +                if (raw_dev->vendor_id == usb_dev->vendor_id &&
    1.65 +                    raw_dev->product_id == usb_dev->product_id &&
    1.66 +                    (raw_dev->interface_number < 0 || raw_dev->interface_number == usb_dev->interface_number)) {
    1.67                      bFound = SDL_TRUE;
    1.68                      break;
    1.69                  }
    1.70              }
    1.71  #endif
    1.72 -
    1.73 -            if (!bFound) {
    1.74 -                new_dev = (struct hid_device_info*) SDL_malloc(sizeof(struct hid_device_info));
    1.75 -                LIBUSB_CopyHIDDeviceInfo(usb_dev, new_dev);
    1.76 -
    1.77 -                if (last != NULL) {
    1.78 -                    last->next = new_dev;
    1.79 -                } else {
    1.80 -                    devs = new_dev;
    1.81 -                }
    1.82 -                last = new_dev;
    1.83 -            }
    1.84 -        }
    1.85 -        LIBUSB_hid_free_enumeration(usb_devs);
    1.86 -    }
    1.87 -#endif /* SDL_LIBUSB_DYNAMIC */
    1.88 -
    1.89 -#if HAVE_PLATFORM_BACKEND
    1.90 -    if (udev_ctx) {
    1.91 -        for (raw_dev = raw_devs; raw_dev; raw_dev = raw_dev->next) {
    1.92 -            bFound = SDL_FALSE;
    1.93 -            for (new_dev = devs; new_dev; new_dev = new_dev->next) {
    1.94 -                if (raw_dev->vendor_id == new_dev->vendor_id &&
    1.95 -                    raw_dev->product_id == new_dev->product_id &&
    1.96 -                    raw_dev->interface_number == new_dev->interface_number) {
    1.97 -                    bFound = SDL_TRUE;
    1.98 -                    break;
    1.99 -                }
   1.100 -            }
   1.101 -
   1.102              if (!bFound) {
   1.103                  new_dev = (struct hid_device_info*) SDL_malloc(sizeof(struct hid_device_info));
   1.104                  PLATFORM_CopyHIDDeviceInfo(raw_dev, new_dev);
   1.105 @@ -620,6 +599,11 @@
   1.106      }
   1.107  #endif /* HAVE_PLATFORM_BACKEND */
   1.108  
   1.109 +#ifdef SDL_LIBUSB_DYNAMIC
   1.110 +    if (libusb_ctx.libhandle) {
   1.111 +        LIBUSB_hid_free_enumeration(usb_devs);
   1.112 +    }
   1.113 +#endif
   1.114      return devs;
   1.115  }
   1.116  
   1.117 @@ -764,3 +748,5 @@
   1.118  }
   1.119  
   1.120  #endif /* SDL_JOYSTICK_HIDAPI */
   1.121 +
   1.122 +/* vi: set sts=4 ts=4 sw=4 expandtab: */