Skip to content

Commit 6033f24

Browse files
dylanmckayz3ntu
authored andcommitted
mac: Set a valid interface number on hid_device_info for USB HID devices
Previously the interface would never be set on Mac. This presents a big pain because retrieving interface numbers can be the only way to distinguish between the interfaces returned by HIDAPI. This change makes it possible to retrieve interface number from an hid_device_info on Mac for USB HID devices only. It is unclear if the macOS IOKit library returns valid interface numbers for non-HID USB devices. Because of this, I have opted to simply skip that case - leave it initialised to `-1`. In the future, we can easily relax this restriction if it turns out IOKit correctly returns interface number with non-HID USB devices. For now, this commit brings 90% of the value at 5% of the risk.
1 parent a6a622f commit 6033f24

File tree

2 files changed

+20
-5
lines changed

2 files changed

+20
-5
lines changed

hidapi/hidapi.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,13 @@ extern "C" {
6969
(Windows/Mac only).*/
7070
unsigned short usage;
7171
/** The USB interface which this logical device
72-
represents. Valid on both Linux implementations
73-
in all cases, and valid on the Windows implementation
74-
only if the device contains more than one interface. */
72+
represents.
73+
74+
* Valid on both Linux implementations in all cases
75+
* Valid on the Windows implementation only if the device
76+
contains more than one interface
77+
* Valid on the Mac implementation if and only if the device
78+
* is a USB HID device. */
7579
int interface_number;
7680

7781
/** Pointer to the next device */

mac/hid.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <IOKit/hid/IOHIDManager.h>
2626
#include <IOKit/hid/IOHIDKeys.h>
2727
#include <IOKit/IOKitLib.h>
28+
#include <IOKit/usb/USBSpec.h>
2829
#include <CoreFoundation/CoreFoundation.h>
2930
#include <wchar.h>
3031
#include <locale.h>
@@ -432,6 +433,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
432433
if ((vendor_id == 0x0 || vendor_id == dev_vid) &&
433434
(product_id == 0x0 || product_id == dev_pid)) {
434435
struct hid_device_info *tmp;
436+
bool is_usb_hid; /* Is this an actual HID usb device */
435437
io_object_t iokit_dev;
436438
kern_return_t res;
437439
io_string_t path;
@@ -446,6 +448,8 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
446448
}
447449
cur_dev = tmp;
448450

451+
is_usb_hid = get_int_property(dev, CFSTR(kUSBInterfaceClass)) == kUSBHIDClass;
452+
449453
/* Get the Usage Page and Usage for this device. */
450454
cur_dev->usage_page = get_int_property(dev, CFSTR(kIOHIDPrimaryUsagePageKey));
451455
cur_dev->usage = get_int_property(dev, CFSTR(kIOHIDPrimaryUsageKey));
@@ -478,8 +482,15 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
478482
/* Release Number */
479483
cur_dev->release_number = get_int_property(dev, CFSTR(kIOHIDVersionNumberKey));
480484

481-
/* Interface Number (Unsupported on Mac)*/
482-
cur_dev->interface_number = -1;
485+
/* We can only retrieve the interface number for USB HID devices.
486+
* IOKit always seems to return 0 when querying a standard USB device
487+
* for its interface. */
488+
if (is_usb_hid) {
489+
/* Get the interface number */
490+
cur_dev->interface_number = get_int_property(dev, CFSTR(kUSBInterfaceNumber));
491+
} else {
492+
cur_dev->interface_number = -1;
493+
}
483494
}
484495
}
485496

0 commit comments

Comments
 (0)