From 15a9890919448cb463ab27f0e69be950be11ea87 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 5 Nov 2022 16:44:52 -0700 Subject: [PATCH] Added SDL_HINT_HIDAPI_IGNORE_DEVICES to specify devices that should be ignored in SDL_hid_enumerate() --- include/SDL_hints.h | 8 ++++++++ src/hidapi/android/hid.cpp | 13 +++++++++++++ src/hidapi/ios/hid.m | 13 ++++++++++++- src/hidapi/libusb/hid.c | 13 +++++++++++++ src/hidapi/linux/hid.c | 13 +++++++++++++ src/hidapi/mac/hid.c | 13 +++++++++++++ src/hidapi/windows/hid.c | 13 +++++++++++++ 7 files changed, 85 insertions(+), 1 deletion(-) diff --git a/include/SDL_hints.h b/include/SDL_hints.h index 8bc4828fa..ce2225440 100644 --- a/include/SDL_hints.h +++ b/include/SDL_hints.h @@ -539,6 +539,14 @@ extern "C" { */ #define SDL_HINT_GRAB_KEYBOARD "SDL_GRAB_KEYBOARD" +/** + * \brief A variable containing a list of devices to ignore in SDL_hid_enumerate() + * + * For example, to ignore the Shanwan DS3 controller and any Valve controller, you might + * have the string "0x2563/0x0523,0x28de/0x0000" + */ +#define SDL_HINT_HIDAPI_IGNORE_DEVICES "SDL_HIDAPI_IGNORE_DEVICES" + /** * \brief A variable controlling whether the idle timer is disabled on iOS. * diff --git a/src/hidapi/android/hid.cpp b/src/hidapi/android/hid.cpp index 2b2af72db..34fda42d3 100644 --- a/src/hidapi/android/hid.cpp +++ b/src/hidapi/android/hid.cpp @@ -1085,10 +1085,23 @@ int hid_init(void) struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id) { struct hid_device_info *root = NULL; + const char *hint = SDL_GetHint(SDL_HINT_HIDAPI_IGNORE_DEVICES); + hid_mutex_guard l( &g_DevicesMutex ); for ( hid_device_ref pDevice = g_Devices; pDevice; pDevice = pDevice->next ) { const hid_device_info *info = pDevice->GetDeviceInfo(); + + /* See if there are any devices we should skip in enumeration */ + if (hint) { + char vendor_match[16], product_match[16]; + SDL_snprintf(vendor_match, sizeof(vendor_match), "0x%.4x/0x0000", info->vendor_id); + SDL_snprintf(product_match, sizeof(product_match), "0x%.4x/0x%.4x", info->vendor_id, info->product_id); + if (SDL_strcasestr(hint, vendor_match) || SDL_strcasestr(hint, product_match)) { + continue; + } + } + if ( ( vendor_id == 0x0 || info->vendor_id == vendor_id ) && ( product_id == 0x0 || info->product_id == product_id ) ) { diff --git a/src/hidapi/ios/hid.m b/src/hidapi/ios/hid.m index 111b8f236..55845701a 100644 --- a/src/hidapi/ios/hid.m +++ b/src/hidapi/ios/hid.m @@ -836,7 +836,18 @@ int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock) struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id) { @autoreleasepool { struct hid_device_info *root = NULL; - + const char *hint = SDL_GetHint(SDL_HINT_HIDAPI_IGNORE_DEVICES); + + /* See if there are any devices we should skip in enumeration */ + if (hint) { + char vendor_match[16], product_match[16]; + SDL_snprintf(vendor_match, sizeof(vendor_match), "0x%.4x/0x0000", VALVE_USB_VID); + SDL_snprintf(product_match, sizeof(product_match), "0x%.4x/0x%.4x", VALVE_USB_VID, D0G_BLE2_PID); + if (SDL_strcasestr(hint, vendor_match) || SDL_strcasestr(hint, product_match)) { + return NULL; + } + } + if ( ( vendor_id == 0 && product_id == 0 ) || ( vendor_id == VALVE_USB_VID && product_id == D0G_BLE2_PID ) ) { diff --git a/src/hidapi/libusb/hid.c b/src/hidapi/libusb/hid.c index e86aa51cb..1f08aedfa 100644 --- a/src/hidapi/libusb/hid.c +++ b/src/hidapi/libusb/hid.c @@ -29,6 +29,7 @@ #include "../../SDL_internal.h" #include "../../thread/SDL_systhread.h" +#include "SDL_hints.h" #include "SDL_mutex.h" #include "SDL_thread.h" @@ -761,6 +762,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, struct hid_device_info *root = NULL; /* return object */ struct hid_device_info *cur_dev = NULL; + const char *hint = SDL_GetHint(SDL_HINT_HIDAPI_IGNORE_DEVICES); if(hid_init() < 0) return NULL; @@ -778,10 +780,21 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short dev_vid = desc.idVendor; unsigned short dev_pid = desc.idProduct; + /* See if there are any devices we should skip in enumeration */ + if (hint) { + char vendor_match[16], product_match[16]; + SDL_snprintf(vendor_match, sizeof(vendor_match), "0x%.4x/0x0000", dev_vid); + SDL_snprintf(product_match, sizeof(product_match), "0x%.4x/0x%.4x", dev_vid, dev_pid); + if (SDL_strcasestr(hint, vendor_match) || SDL_strcasestr(hint, product_match)) { + continue; + } + } + res = libusb_get_active_config_descriptor(dev, &conf_desc); if (res < 0) libusb_get_config_descriptor(dev, 0, &conf_desc); if (conf_desc) { + for (j = 0; j < conf_desc->bNumInterfaces; j++) { const struct libusb_interface *intf = &conf_desc->interface[j]; for (k = 0; k < intf->num_altsetting; k++) { diff --git a/src/hidapi/linux/hid.c b/src/hidapi/linux/hid.c index 6507dde71..fbd010144 100644 --- a/src/hidapi/linux/hid.c +++ b/src/hidapi/linux/hid.c @@ -22,6 +22,8 @@ ********************************************************/ #include "../../SDL_internal.h" +#include "SDL_hints.h" + #ifndef _GNU_SOURCE #define _GNU_SOURCE /* needed for wcsdup() before glibc 2.10 */ #endif @@ -481,6 +483,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, struct hid_device_info *root = NULL; /* return object */ struct hid_device_info *cur_dev = NULL; struct hid_device_info *prev_dev = NULL; /* previous device */ + const char *hint = SDL_GetHint(SDL_HINT_HIDAPI_IGNORE_DEVICES); hid_init(); @@ -552,6 +555,16 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, goto next; } + /* See if there are any devices we should skip in enumeration */ + if (hint) { + char vendor_match[16], product_match[16]; + SDL_snprintf(vendor_match, sizeof(vendor_match), "0x%.4x/0x0000", dev_vid); + SDL_snprintf(product_match, sizeof(product_match), "0x%.4x/0x%.4x", dev_vid, dev_pid); + if (SDL_strcasestr(hint, vendor_match) || SDL_strcasestr(hint, product_match)) { + continue; + } + } + /* Check the VID/PID against the arguments */ if ((vendor_id == 0x0 || vendor_id == dev_vid) && (product_id == 0x0 || product_id == dev_pid)) { diff --git a/src/hidapi/mac/hid.c b/src/hidapi/mac/hid.c index d52b94f0a..d5dfbc296 100644 --- a/src/hidapi/mac/hid.c +++ b/src/hidapi/mac/hid.c @@ -21,6 +21,8 @@ ********************************************************/ #include "../../SDL_internal.h" +#include "SDL_hints.h" + /* See Apple Technical Note TN2187 for details on IOHidManager. */ #include @@ -517,6 +519,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, CFSetRef device_set; IOHIDDeviceRef *device_array; int i; + const char *hint = SDL_GetHint(SDL_HINT_HIDAPI_IGNORE_DEVICES); /* Set up the HID Manager if it hasn't been done */ if (hid_init() < 0) @@ -567,6 +570,16 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, dev_vid = get_vendor_id(dev); dev_pid = get_product_id(dev); + /* See if there are any devices we should skip in enumeration */ + if (hint) { + char vendor_match[16], product_match[16]; + SDL_snprintf(vendor_match, sizeof(vendor_match), "0x%.4x/0x0000", dev_vid); + SDL_snprintf(product_match, sizeof(product_match), "0x%.4x/0x%.4x", dev_vid, dev_pid); + if (SDL_strcasestr(hint, vendor_match) || SDL_strcasestr(hint, product_match)) { + continue; + } + } + /* Check the VID/PID against the arguments */ if ((vendor_id == 0x0 || dev_vid == vendor_id) && (product_id == 0x0 || dev_pid == product_id)) { diff --git a/src/hidapi/windows/hid.c b/src/hidapi/windows/hid.c index 8dfd11d05..27c09e52e 100644 --- a/src/hidapi/windows/hid.c +++ b/src/hidapi/windows/hid.c @@ -21,6 +21,8 @@ ********************************************************/ #include "../../SDL_internal.h" +#include "SDL_hints.h" + #include #ifndef _WIN32_WINNT_WIN8 @@ -371,6 +373,7 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor SP_DEVICE_INTERFACE_DETAIL_DATA_A *device_interface_detail_data = NULL; HDEVINFO device_info_set = INVALID_HANDLE_VALUE; int device_index = 0; + const char *hint = SDL_GetHint(SDL_HINT_HIDAPI_IGNORE_DEVICES); if (hid_init() < 0) return NULL; @@ -488,6 +491,16 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor HidD_GetAttributes(write_handle, &attrib); //wprintf(L"Product/Vendor: %x %x\n", attrib.ProductID, attrib.VendorID); + /* See if there are any devices we should skip in enumeration */ + if (hint) { + char vendor_match[16], product_match[16]; + SDL_snprintf(vendor_match, sizeof(vendor_match), "0x%.4x/0x0000", attrib.VendorID); + SDL_snprintf(product_match, sizeof(product_match), "0x%.4x/0x%.4x", attrib.VendorID, attrib.ProductID); + if (SDL_strcasestr(hint, vendor_match) || SDL_strcasestr(hint, product_match)) { + continue; + } + } + /* Check the VID/PID to see if we should add this device to the enumeration list. */ if ((vendor_id == 0x0 || attrib.VendorID == vendor_id) &&