mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-05-25 22:19:10 +00:00
Fixed detecting Bluetooth Steam Controllers
This commit is contained in:
parent
6150b5b3cb
commit
6e7769cde1
8 changed files with 113 additions and 12 deletions
|
@ -531,8 +531,8 @@ static void HIDAPI_ShutdownDiscovery(void)
|
||||||
/* Platform HIDAPI Implementation */
|
/* Platform HIDAPI Implementation */
|
||||||
|
|
||||||
#define HIDAPI_USING_SDL_RUNTIME
|
#define HIDAPI_USING_SDL_RUNTIME
|
||||||
#define HIDAPI_IGNORE_DEVICE(VID, PID, USAGE_PAGE, USAGE) \
|
#define HIDAPI_IGNORE_DEVICE(BUS, VID, PID, USAGE_PAGE, USAGE) \
|
||||||
SDL_HIDAPI_ShouldIgnoreDevice(VID, PID, USAGE_PAGE, USAGE)
|
SDL_HIDAPI_ShouldIgnoreDevice(BUS, VID, PID, USAGE_PAGE, USAGE)
|
||||||
|
|
||||||
struct PLATFORM_hid_device_;
|
struct PLATFORM_hid_device_;
|
||||||
typedef struct PLATFORM_hid_device_ PLATFORM_hid_device;
|
typedef struct PLATFORM_hid_device_ PLATFORM_hid_device;
|
||||||
|
@ -1053,13 +1053,15 @@ static void SDLCALL IgnoredDevicesChanged(void *userdata, const char *name, cons
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_bool SDL_HIDAPI_ShouldIgnoreDevice(Uint16 vendor_id, Uint16 product_id, Uint16 usage_page, Uint16 usage)
|
SDL_bool SDL_HIDAPI_ShouldIgnoreDevice(int bus, Uint16 vendor_id, Uint16 product_id, Uint16 usage_page, Uint16 usage)
|
||||||
{
|
{
|
||||||
/* See if there are any devices we should skip in enumeration */
|
/* See if there are any devices we should skip in enumeration */
|
||||||
if (SDL_hidapi_only_controllers && usage_page) {
|
if (SDL_hidapi_only_controllers && usage_page) {
|
||||||
if (vendor_id == USB_VENDOR_VALVE) {
|
if (vendor_id == USB_VENDOR_VALVE) {
|
||||||
/* Ignore the mouse/keyboard interface on Steam Controllers */
|
/* Ignore the USB mouse/keyboard interface on Steam Controllers */
|
||||||
if (usage == USB_USAGE_GENERIC_KEYBOARD || usage == USB_USAGE_GENERIC_MOUSE) {
|
if (bus == HID_API_BUS_USB &&
|
||||||
|
usage_page == USB_USAGEPAGE_GENERIC_DESKTOP &&
|
||||||
|
(usage == USB_USAGE_GENERIC_KEYBOARD || usage == USB_USAGE_GENERIC_MOUSE)) {
|
||||||
return SDL_TRUE;
|
return SDL_TRUE;
|
||||||
}
|
}
|
||||||
} else if (usage_page == USB_USAGEPAGE_GENERIC_DESKTOP &&
|
} else if (usage_page == USB_USAGEPAGE_GENERIC_DESKTOP &&
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
|
|
||||||
/* Return true if the HIDAPI should ignore a device during enumeration */
|
/* Return true if the HIDAPI should ignore a device during enumeration */
|
||||||
extern SDL_bool SDL_HIDAPI_ShouldIgnoreDevice(Uint16 vendor_id, Uint16 product_id, Uint16 usage_page, Uint16 usage);
|
extern SDL_bool SDL_HIDAPI_ShouldIgnoreDevice(int bus_type, Uint16 vendor_id, Uint16 product_id, Uint16 usage_page, Uint16 usage);
|
||||||
|
|
||||||
#ifdef SDL_JOYSTICK_HIDAPI
|
#ifdef SDL_JOYSTICK_HIDAPI
|
||||||
#ifdef HAVE_LIBUSB
|
#ifdef HAVE_LIBUSB
|
||||||
|
|
|
@ -1074,7 +1074,7 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor
|
||||||
const hid_device_info *info = pDevice->GetDeviceInfo();
|
const hid_device_info *info = pDevice->GetDeviceInfo();
|
||||||
|
|
||||||
/* See if there are any devices we should skip in enumeration */
|
/* See if there are any devices we should skip in enumeration */
|
||||||
if (SDL_HIDAPI_ShouldIgnoreDevice(info->vendor_id, info->product_id, 0, 0)) {
|
if (SDL_HIDAPI_ShouldIgnoreDevice(HID_API_BUS_UNKNOWN, info->vendor_id, info->product_id, 0, 0)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -859,7 +859,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
|
||||||
struct hid_device_info *root = NULL;
|
struct hid_device_info *root = NULL;
|
||||||
|
|
||||||
/* See if there are any devices we should skip in enumeration */
|
/* See if there are any devices we should skip in enumeration */
|
||||||
if (SDL_HIDAPI_ShouldIgnoreDevice(VALVE_USB_VID, D0G_BLE2_PID, 0, 0)) {
|
if (SDL_HIDAPI_ShouldIgnoreDevice(HID_API_BUS_BLUETOOTH, VALVE_USB_VID, D0G_BLE2_PID, 0, 0)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -943,7 +943,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
|
||||||
|
|
||||||
#ifdef HIDAPI_IGNORE_DEVICE
|
#ifdef HIDAPI_IGNORE_DEVICE
|
||||||
/* See if there are any devices we should skip in enumeration */
|
/* See if there are any devices we should skip in enumeration */
|
||||||
if (HIDAPI_IGNORE_DEVICE(dev_vid, dev_pid, 0, 0)) {
|
if (HIDAPI_IGNORE_DEVICE(HID_API_BUS_USB, dev_vid, dev_pid, 0, 0)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -984,7 +984,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
|
||||||
if (get_hid_report_descriptor_from_sysfs(sysfs_path, &report_desc) >= 0) {
|
if (get_hid_report_descriptor_from_sysfs(sysfs_path, &report_desc) >= 0) {
|
||||||
get_next_hid_usage(report_desc.value, report_desc.size, &pos, &page, &usage);
|
get_next_hid_usage(report_desc.value, report_desc.size, &pos, &page, &usage);
|
||||||
}
|
}
|
||||||
if (HIDAPI_IGNORE_DEVICE(dev_vid, dev_pid, page, usage)) {
|
if (HIDAPI_IGNORE_DEVICE(bus_type, dev_vid, dev_pid, page, usage)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -548,6 +548,28 @@ static int read_usb_interface_from_hid_service_parent(io_service_t hid_service)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HIDAPI_IGNORE_DEVICE
|
||||||
|
static hid_bus_type get_bus_type(IOHIDDeviceRef dev)
|
||||||
|
{
|
||||||
|
hid_bus_type bus_type = HID_API_BUS_UNKNOWN;
|
||||||
|
|
||||||
|
CFTypeRef transport_prop = IOHIDDeviceGetProperty(dev, CFSTR(kIOHIDTransportKey));
|
||||||
|
|
||||||
|
if (transport_prop != NULL && CFGetTypeID(transport_prop) == CFStringGetTypeID()) {
|
||||||
|
if (CFStringCompare((CFStringRef)transport_prop, CFSTR(kIOHIDTransportUSBValue), 0) == kCFCompareEqualTo) {
|
||||||
|
bus_type = HID_API_BUS_USB;
|
||||||
|
} else if (CFStringHasPrefix((CFStringRef)transport_prop, CFSTR(kIOHIDTransportBluetoothValue))) {
|
||||||
|
bus_type = HID_API_BUS_BLUETOOTH;
|
||||||
|
} else if (CFStringCompare((CFStringRef)transport_prop, CFSTR(kIOHIDTransportI2CValue), 0) == kCFCompareEqualTo) {
|
||||||
|
bus_type = HID_API_BUS_I2C;
|
||||||
|
} else if (CFStringCompare((CFStringRef)transport_prop, CFSTR(kIOHIDTransportSPIValue), 0) == kCFCompareEqualTo) {
|
||||||
|
bus_type = HID_API_BUS_SPI;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bus_type;
|
||||||
|
}
|
||||||
|
#endif /* HIDAPI_IGNORE_DEVICE */
|
||||||
|
|
||||||
static struct hid_device_info *create_device_info_with_usage(IOHIDDeviceRef dev, int32_t usage_page, int32_t usage)
|
static struct hid_device_info *create_device_info_with_usage(IOHIDDeviceRef dev, int32_t usage_page, int32_t usage)
|
||||||
{
|
{
|
||||||
unsigned short dev_vid;
|
unsigned short dev_vid;
|
||||||
|
@ -769,11 +791,12 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
|
||||||
|
|
||||||
#ifdef HIDAPI_IGNORE_DEVICE
|
#ifdef HIDAPI_IGNORE_DEVICE
|
||||||
/* See if there are any devices we should skip in enumeration */
|
/* See if there are any devices we should skip in enumeration */
|
||||||
|
hid_bus_type bus_type = get_bus_type(dev);
|
||||||
unsigned short dev_vid = get_vendor_id(dev);
|
unsigned short dev_vid = get_vendor_id(dev);
|
||||||
unsigned short dev_pid = get_product_id(dev);
|
unsigned short dev_pid = get_product_id(dev);
|
||||||
unsigned short usage_page = get_int_property(dev, CFSTR(kIOHIDPrimaryUsagePageKey));
|
unsigned short usage_page = get_int_property(dev, CFSTR(kIOHIDPrimaryUsagePageKey));
|
||||||
unsigned short usage = get_int_property(dev, CFSTR(kIOHIDPrimaryUsageKey));
|
unsigned short usage = get_int_property(dev, CFSTR(kIOHIDPrimaryUsageKey));
|
||||||
if (HIDAPI_IGNORE_DEVICE(dev_vid, dev_pid, usage_page, usage)) {
|
if (HIDAPI_IGNORE_DEVICE(bus_type, dev_vid, dev_pid, usage_page, usage)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -644,6 +644,81 @@ static void hid_internal_get_ble_info(struct hid_device_info* dev, DEVINST dev_n
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HIDAPI_IGNORE_DEVICE
|
||||||
|
static hid_bus_type get_bus_type(const wchar_t* interface_path)
|
||||||
|
{
|
||||||
|
wchar_t *device_id = NULL, *compatible_ids = NULL;
|
||||||
|
CONFIGRET cr;
|
||||||
|
DEVINST dev_node;
|
||||||
|
hid_bus_type bus_type = HID_API_BUS_UNKNOWN;
|
||||||
|
|
||||||
|
/* Get the device id from interface path */
|
||||||
|
device_id = hid_internal_get_device_interface_property(interface_path, &DEVPKEY_Device_InstanceId, DEVPROP_TYPE_STRING);
|
||||||
|
if (!device_id)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
/* Open devnode from device id */
|
||||||
|
cr = CM_Locate_DevNodeW(&dev_node, (DEVINSTID_W)device_id, CM_LOCATE_DEVNODE_NORMAL);
|
||||||
|
if (cr != CR_SUCCESS)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
/* Get devnode parent */
|
||||||
|
cr = CM_Get_Parent(&dev_node, dev_node, 0);
|
||||||
|
if (cr != CR_SUCCESS)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
/* Get the compatible ids from parent devnode */
|
||||||
|
compatible_ids = hid_internal_get_devnode_property(dev_node, &DEVPKEY_Device_CompatibleIds, DEVPROP_TYPE_STRING_LIST);
|
||||||
|
if (!compatible_ids)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
/* Now we can parse parent's compatible IDs to find out the device bus type */
|
||||||
|
for (wchar_t* compatible_id = compatible_ids; *compatible_id; compatible_id += wcslen(compatible_id) + 1) {
|
||||||
|
/* Normalize to upper case */
|
||||||
|
hid_internal_towupper(compatible_id);
|
||||||
|
|
||||||
|
/* USB devices
|
||||||
|
https://docs.microsoft.com/windows-hardware/drivers/hid/plug-and-play-support
|
||||||
|
https://docs.microsoft.com/windows-hardware/drivers/install/standard-usb-identifiers */
|
||||||
|
if (wcsstr(compatible_id, L"USB") != NULL) {
|
||||||
|
bus_type = HID_API_BUS_USB;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bluetooth devices
|
||||||
|
https://docs.microsoft.com/windows-hardware/drivers/bluetooth/installing-a-bluetooth-device */
|
||||||
|
if (wcsstr(compatible_id, L"BTHENUM") != NULL) {
|
||||||
|
bus_type = HID_API_BUS_BLUETOOTH;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bluetooth LE devices */
|
||||||
|
if (wcsstr(compatible_id, L"BTHLEDEVICE") != NULL) {
|
||||||
|
bus_type = HID_API_BUS_BLUETOOTH;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* I2C devices
|
||||||
|
https://docs.microsoft.com/windows-hardware/drivers/hid/plug-and-play-support-and-power-management */
|
||||||
|
if (wcsstr(compatible_id, L"PNP0C50") != NULL) {
|
||||||
|
bus_type = HID_API_BUS_I2C;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SPI devices
|
||||||
|
https://docs.microsoft.com/windows-hardware/drivers/hid/plug-and-play-for-spi */
|
||||||
|
if (wcsstr(compatible_id, L"PNP0C51") != NULL) {
|
||||||
|
bus_type = HID_API_BUS_SPI;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end:
|
||||||
|
free(device_id);
|
||||||
|
free(compatible_ids);
|
||||||
|
return bus_type;
|
||||||
|
}
|
||||||
|
#endif /* HIDAPI_IGNORE_DEVICE */
|
||||||
|
|
||||||
static void hid_internal_get_info(const wchar_t* interface_path, struct hid_device_info* dev)
|
static void hid_internal_get_info(const wchar_t* interface_path, struct hid_device_info* dev)
|
||||||
{
|
{
|
||||||
wchar_t *device_id = NULL, *compatible_ids = NULL;
|
wchar_t *device_id = NULL, *compatible_ids = NULL;
|
||||||
|
@ -906,13 +981,14 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor
|
||||||
|
|
||||||
#ifdef HIDAPI_IGNORE_DEVICE
|
#ifdef HIDAPI_IGNORE_DEVICE
|
||||||
/* See if there are any devices we should skip in enumeration */
|
/* See if there are any devices we should skip in enumeration */
|
||||||
|
hid_bus_type bus_type = get_bus_type(device_interface);
|
||||||
PHIDP_PREPARSED_DATA pp_data = NULL;
|
PHIDP_PREPARSED_DATA pp_data = NULL;
|
||||||
HIDP_CAPS caps = { 0 };
|
HIDP_CAPS caps = { 0 };
|
||||||
if (HidD_GetPreparsedData(device_handle, &pp_data)) {
|
if (HidD_GetPreparsedData(device_handle, &pp_data)) {
|
||||||
HidP_GetCaps(pp_data, &caps);
|
HidP_GetCaps(pp_data, &caps);
|
||||||
HidD_FreePreparsedData(pp_data);
|
HidD_FreePreparsedData(pp_data);
|
||||||
}
|
}
|
||||||
if (HIDAPI_IGNORE_DEVICE(attrib.VendorID, attrib.ProductID, caps.UsagePage, caps.Usage)) {
|
if (HIDAPI_IGNORE_DEVICE(bus_type, attrib.VendorID, attrib.ProductID, caps.UsagePage, caps.Usage)) {
|
||||||
goto cont_close;
|
goto cont_close;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue