diff --git a/src/hidapi/mac/hid.c b/src/hidapi/mac/hid.c index 8b9645ab90..e58b9a990f 100644 --- a/src/hidapi/mac/hid.c +++ b/src/hidapi/mac/hid.c @@ -573,6 +573,7 @@ static struct hid_device_info *create_device_info_with_usage(IOHIDDeviceRef dev, { unsigned short dev_vid; unsigned short dev_pid; + unsigned short dev_version; int BUF_LEN = 256; wchar_t buf[BUF_LEN]; CFTypeRef transport_prop; @@ -593,6 +594,7 @@ static struct hid_device_info *create_device_info_with_usage(IOHIDDeviceRef dev, dev_vid = get_vendor_id(dev); dev_pid = get_product_id(dev); + dev_version = get_int_property(dev, CFSTR(kIOHIDVersionNumberKey)); #ifdef HIDAPI_IGNORE_DEVICE /* See if there are any devices we should skip in enumeration */ @@ -602,6 +604,19 @@ static struct hid_device_info *create_device_info_with_usage(IOHIDDeviceRef dev, } #endif +#ifdef HIDAPI_USING_SDL_RUNTIME + if (IOHIDDeviceGetProperty(dev, CFSTR(kIOHIDVirtualHIDevice)) == kCFBooleanTrue) { + /* Steam virtual gamepads always have kIOHIDVirtualHIDevice property unlike real devices */ + if (SDL_IsJoystickSteamVirtualGamepad(dev_vid, dev_pid, dev_version)) { + const char *allow_steam_virtual_gamepad = SDL_getenv_unsafe("SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD"); + if (!SDL_GetStringBoolean(allow_steam_virtual_gamepad, false)) { + free(cur_dev); + return NULL; + } + } + } +#endif + cur_dev->usage_page = usage_page; cur_dev->usage = usage; @@ -649,7 +664,7 @@ static struct hid_device_info *create_device_info_with_usage(IOHIDDeviceRef dev, cur_dev->product_id = dev_pid; /* Release Number */ - cur_dev->release_number = get_int_property(dev, CFSTR(kIOHIDVersionNumberKey)); + cur_dev->release_number = dev_version; /* Interface Number. * We can only retrieve the interface number for USB HID devices. diff --git a/src/joystick/SDL_gamepad.c b/src/joystick/SDL_gamepad.c index 70dce263de..f4ba4bf1a7 100644 --- a/src/joystick/SDL_gamepad.c +++ b/src/joystick/SDL_gamepad.c @@ -3256,6 +3256,11 @@ bool SDL_ShouldIgnoreGamepad(Uint16 vendor_id, Uint16 product_id, Uint16 version } } +#ifdef SDL_PLATFORM_MACOS + // On macOS do nothing here since we detect Steam virtual gamepads + // in IOKit HID backends to ensure accuracy. + // See joystick/darwin/SDL_iokitjoystick.c and hidapi/mac/hid.c. +#else const char *hint = SDL_getenv_unsafe("SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD"); bool allow_steam_virtual_gamepad = SDL_GetStringBoolean(hint, false); #ifdef SDL_PLATFORM_WIN32 @@ -3271,6 +3276,7 @@ bool SDL_ShouldIgnoreGamepad(Uint16 vendor_id, Uint16 product_id, Uint16 version if (SDL_IsJoystickSteamVirtualGamepad(vendor_id, product_id, version)) { return !allow_steam_virtual_gamepad; } +#endif if (SDL_allowed_gamepads.num_included_entries > 0) { if (SDL_VIDPIDInList(vendor_id, product_id, &SDL_allowed_gamepads)) { diff --git a/src/joystick/darwin/SDL_iokitjoystick.c b/src/joystick/darwin/SDL_iokitjoystick.c index 75e7cc5201..7e36391f42 100644 --- a/src/joystick/darwin/SDL_iokitjoystick.c +++ b/src/joystick/darwin/SDL_iokitjoystick.c @@ -28,6 +28,7 @@ #include "../hidapi/SDL_hidapijoystick_c.h" #include "../../haptic/darwin/SDL_syshaptic_c.h" // For haptic hot plugging #include "../usb_ids.h" +#include "../../SDL_hints_c.h" #include #define SDL_JOYSTICK_RUNLOOP_MODE CFSTR("SDLJoystick") @@ -515,6 +516,16 @@ static bool GetDeviceInfo(IOHIDDeviceRef hidDevice, recDevice *pDevice) return false; } + if (IOHIDDeviceGetProperty(hidDevice, CFSTR(kIOHIDVirtualHIDevice)) == kCFBooleanTrue) { + // Steam virtual gamepads always have kIOHIDVirtualHIDevice property unlike real devices + if (SDL_IsJoystickSteamVirtualGamepad(vendor, product, version)) { + const char *allow_steam_virtual_gamepad = SDL_getenv_unsafe("SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD"); + if (!SDL_GetStringBoolean(allow_steam_virtual_gamepad, false)) { + return false; + } + } + } + // get device name refCF = IOHIDDeviceGetProperty(hidDevice, CFSTR(kIOHIDManufacturerKey)); if ((!refCF) || (!CFStringGetCString(refCF, manufacturer_string, sizeof(manufacturer_string), kCFStringEncodingUTF8))) {