From 007c36e5138706e47bec56f6aaee158b1499201e Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 24 May 2023 22:37:38 -0700 Subject: [PATCH] Added SDL_HINT_HIDAPI_IGNORE_DEVICES to specify devices that should be ignored in SDL_hid_enumerate() --- src/hidapi/SDL_hidapi.c | 39 +++++++++++++++++++++++++++++++++ src/hidapi/SDL_hidapi_c.h | 6 +++-- src/hidapi/SDL_hidapi_windows.h | 3 --- src/hidapi/android/hid.cpp | 13 +++++------ src/hidapi/ios/hid.m | 11 +++------- src/hidapi/libusb/hid.c | 7 ++++++ src/hidapi/linux/hid.c | 10 +++++++++ src/hidapi/mac/hid.c | 9 ++++++++ src/hidapi/windows/hid.c | 7 ++++++ 9 files changed, 84 insertions(+), 21 deletions(-) diff --git a/src/hidapi/SDL_hidapi.c b/src/hidapi/SDL_hidapi.c index f0c62634a..3d21e7884 100644 --- a/src/hidapi/SDL_hidapi.c +++ b/src/hidapi/SDL_hidapi.c @@ -527,6 +527,8 @@ static void HIDAPI_ShutdownDiscovery(void) /* Platform HIDAPI Implementation */ +#define HIDAPI_IGNORE_DEVICE(VID, PID) SDL_HIDAPI_ShouldIgnoreDevice(VID, PID) + struct PLATFORM_hid_device_; typedef struct PLATFORM_hid_device_ PLATFORM_hid_device; @@ -1029,6 +1031,7 @@ static void CopyHIDDeviceInfo(struct hid_device_info *pSrc, struct SDL_hid_devic #undef WCOPY_IF_EXISTS static int SDL_hidapi_refcount = 0; +static char *SDL_hidapi_ignored_devices = NULL; static void SDL_SetHIDAPIError(const wchar_t *error) { @@ -1041,6 +1044,33 @@ static void SDL_SetHIDAPIError(const wchar_t *error) } } +static void SDLCALL IgnoredDevicesChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + if (SDL_hidapi_ignored_devices) { + SDL_free(SDL_hidapi_ignored_devices); + } + if (hint && *hint) { + SDL_hidapi_ignored_devices = SDL_strdup(hint); + } else { + SDL_hidapi_ignored_devices = NULL; + } +} + +SDL_bool SDL_HIDAPI_ShouldIgnoreDevice(Uint16 vendor_id, Uint16 product_id) +{ + /* See if there are any devices we should skip in enumeration */ + if (SDL_hidapi_ignored_devices) { + char vendor_match[16], product_match[16]; + SDL_snprintf(vendor_match, sizeof(vendor_match), "0x%.4x/0x0000", vendor_id); + SDL_snprintf(product_match, sizeof(product_match), "0x%.4x/0x%.4x", vendor_id, product_id); + if (SDL_strcasestr(SDL_hidapi_ignored_devices, vendor_match) || + SDL_strcasestr(SDL_hidapi_ignored_devices, product_match)) { + return SDL_TRUE; + } + } + return SDL_FALSE; +} + int SDL_hid_init(void) { int attempts = 0, success = 0; @@ -1050,6 +1080,8 @@ int SDL_hid_init(void) return 0; } + SDL_AddHintCallback(SDL_HINT_HIDAPI_IGNORE_DEVICES, IgnoredDevicesChanged, NULL); + #ifdef SDL_USE_LIBUDEV if (SDL_getenv("SDL_HIDAPI_JOYSTICK_DISABLE_UDEV") != NULL) { SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, @@ -1193,6 +1225,13 @@ int SDL_hid_exit(void) } #endif /* HAVE_LIBUSB */ + SDL_DelHintCallback(SDL_HINT_HIDAPI_IGNORE_DEVICES, IgnoredDevicesChanged, NULL); + + if (SDL_hidapi_ignored_devices) { + SDL_free(SDL_hidapi_ignored_devices); + SDL_hidapi_ignored_devices = NULL; + } + return result; } diff --git a/src/hidapi/SDL_hidapi_c.h b/src/hidapi/SDL_hidapi_c.h index 2b9b7d21c..8f69cba4c 100644 --- a/src/hidapi/SDL_hidapi_c.h +++ b/src/hidapi/SDL_hidapi_c.h @@ -20,8 +20,11 @@ */ #include "SDL_internal.h" -#ifdef SDL_JOYSTICK_HIDAPI +/* Return true if the HIDAPI should ignore a device during enumeration */ +extern SDL_bool SDL_HIDAPI_ShouldIgnoreDevice(Uint16 vendor_id, Uint16 product_id); + +#ifdef SDL_JOYSTICK_HIDAPI #ifdef HAVE_LIBUSB #define HAVE_ENABLE_GAMECUBE_ADAPTORS #endif @@ -29,5 +32,4 @@ #ifdef HAVE_ENABLE_GAMECUBE_ADAPTORS extern void SDL_EnableGameCubeAdaptors(void); #endif - #endif /* SDL_JOYSTICK_HIDAPI */ diff --git a/src/hidapi/SDL_hidapi_windows.h b/src/hidapi/SDL_hidapi_windows.h index b1b6b4d67..b09b0457e 100644 --- a/src/hidapi/SDL_hidapi_windows.h +++ b/src/hidapi/SDL_hidapi_windows.h @@ -25,9 +25,6 @@ #define free SDL_free #define malloc SDL_malloc #define memcmp SDL_memcmp -#define snprintf SDL_snprintf -#define strlen SDL_strlen -#define _strnicmp SDL_strncasecmp #define swprintf SDL_swprintf #define towupper SDL_toupper #define wcscmp SDL_wcscmp diff --git a/src/hidapi/android/hid.cpp b/src/hidapi/android/hid.cpp index ae4b40c60..6a8dac407 100644 --- a/src/hidapi/android/hid.cpp +++ b/src/hidapi/android/hid.cpp @@ -51,6 +51,9 @@ #ifndef SDL_HIDAPI_DISABLED +extern "C" { +#include "../SDL_hidapi_c.h" +} #include "../../core/android/SDL_android.h" #define hid_close PLATFORM_hid_close @@ -1064,7 +1067,6 @@ 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 ) @@ -1072,13 +1074,8 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor 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 (SDL_HIDAPI_ShouldIgnoreDevice(info->vendor_id, info->product_id)) { + continue; } if ( ( vendor_id == 0x0 || info->vendor_id == vendor_id ) && diff --git a/src/hidapi/ios/hid.m b/src/hidapi/ios/hid.m index 8ec0e6f19..d67fc1a4f 100644 --- a/src/hidapi/ios/hid.m +++ b/src/hidapi/ios/hid.m @@ -22,6 +22,7 @@ #ifndef SDL_HIDAPI_DISABLED +#include "../SDL_hidapi_c.h" #define hid_close PLATFORM_hid_close #define hid_device PLATFORM_hid_device @@ -856,16 +857,10 @@ static struct hid_device_info *create_device_info_for_hid_device(HIDBLEDevice *d 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 (SDL_HIDAPI_ShouldIgnoreDevice(VALVE_USB_VID, D0G_BLE2_PID)) { + return NULL; } if ( ( vendor_id == 0 && product_id == 0 ) || diff --git a/src/hidapi/libusb/hid.c b/src/hidapi/libusb/hid.c index 47a3e3e1b..cc4850422 100644 --- a/src/hidapi/libusb/hid.c +++ b/src/hidapi/libusb/hid.c @@ -1085,6 +1085,13 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, continue; } +#ifdef HIDAPI_IGNORE_DEVICE + /* See if there are any devices we should skip in enumeration */ + if (HIDAPI_IGNORE_DEVICE(dev_vid, dev_pid)) { + continue; + } +#endif + res = libusb_get_active_config_descriptor(dev, &conf_desc); if (res < 0) libusb_get_config_descriptor(dev, 0, &conf_desc); diff --git a/src/hidapi/linux/hid.c b/src/hidapi/linux/hid.c index 265f42474..9498a8556 100644 --- a/src/hidapi/linux/hid.c +++ b/src/hidapi/linux/hid.c @@ -960,6 +960,16 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, continue; } +#ifdef HIDAPI_IGNORE_DEVICE + /* See if there are any devices we should skip in enumeration */ + if (!parse_hid_vid_pid_from_sysfs(sysfs_path, &bus_type, &dev_vid, &dev_pid)) + continue; + + if (HIDAPI_IGNORE_DEVICE(dev_vid, dev_pid)) { + continue; + } +#endif + raw_dev = udev_device_new_from_syspath(udev, sysfs_path); if (!raw_dev) continue; diff --git a/src/hidapi/mac/hid.c b/src/hidapi/mac/hid.c index 4801579b8..9bc4d52cf 100644 --- a/src/hidapi/mac/hid.c +++ b/src/hidapi/mac/hid.c @@ -833,6 +833,15 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, continue; } +#ifdef HIDAPI_IGNORE_DEVICE + /* See if there are any devices we should skip in enumeration */ + unsigned short dev_vid = get_vendor_id(dev); + unsigned short dev_pid = get_product_id(dev); + if (HIDAPI_IGNORE_DEVICE(dev_vid, dev_pid)) { + continue; + } +#endif + struct hid_device_info *tmp = create_device_info(dev); if (tmp == NULL) { continue; diff --git a/src/hidapi/windows/hid.c b/src/hidapi/windows/hid.c index ed25280b5..7c98f5392 100644 --- a/src/hidapi/windows/hid.c +++ b/src/hidapi/windows/hid.c @@ -872,6 +872,13 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor goto cont_close; } +#ifdef HIDAPI_IGNORE_DEVICE + /* See if there are any devices we should skip in enumeration */ + if (HIDAPI_IGNORE_DEVICE(attrib.VendorID, attrib.ProductID)) { + goto cont_close; + } +#endif + /* Check the VID/PID to see if we should add this device to the enumeration list. */ if ((vendor_id == 0x0 || attrib.VendorID == vendor_id) &&