2828#include <IOKit/usb/USBSpec.h>
2929#include <CoreFoundation/CoreFoundation.h>
3030#include <mach/mach_error.h>
31+ #include <stdbool.h>
3132#include <wchar.h>
3233#include <locale.h>
3334#include <pthread.h>
@@ -302,7 +303,7 @@ static CFArrayRef get_array_property(IOHIDDeviceRef device, CFStringRef key)
302303static int32_t get_int_property (IOHIDDeviceRef device , CFStringRef key )
303304{
304305 CFTypeRef ref ;
305- int32_t value ;
306+ int32_t value = 0 ;
306307
307308 ref = IOHIDDeviceGetProperty (device , key );
308309 if (ref ) {
@@ -314,6 +315,20 @@ static int32_t get_int_property(IOHIDDeviceRef device, CFStringRef key)
314315 return 0 ;
315316}
316317
318+ static bool try_get_int_property (IOHIDDeviceRef device , CFStringRef key , int32_t * out_val )
319+ {
320+ bool result = false;
321+ CFTypeRef ref ;
322+
323+ ref = IOHIDDeviceGetProperty (device , key );
324+ if (ref ) {
325+ if (CFGetTypeID (ref ) == CFNumberGetTypeID ()) {
326+ result = CFNumberGetValue ((CFNumberRef ) ref , kCFNumberSInt32Type , out_val );
327+ }
328+ }
329+ return result ;
330+ }
331+
317332static CFArrayRef get_usage_pairs (IOHIDDeviceRef device )
318333{
319334 return get_array_property (device , CFSTR (kIOHIDDeviceUsagePairsKey ));
@@ -540,24 +555,25 @@ static struct hid_device_info *create_device_info_with_usage(IOHIDDeviceRef dev,
540555 /* Release Number */
541556 cur_dev -> release_number = get_int_property (dev , CFSTR (kIOHIDVersionNumberKey ));
542557
543- /* Interface Number */
544- /* We can only retrieve the interface number for USB HID devices.
545- * IOKit always seems to return 0 when querying a standard USB device
546- * for its interface. */
547- int is_usb_hid = get_int_property (dev , CFSTR (kUSBInterfaceClass )) == kUSBHIDClass ;
548- if (is_usb_hid ) {
549- /* Get the interface number */
550- cur_dev -> interface_number = get_int_property (dev , CFSTR (kUSBInterfaceNumber ));
551- } else {
552- cur_dev -> interface_number = -1 ;
553- }
558+ /* Interface Number.
559+ * We can only retrieve the interface number for USB HID devices.
560+ * See below */
561+ cur_dev -> interface_number = -1 ;
554562
555563 /* Bus Type */
556564 transport_prop = IOHIDDeviceGetProperty (dev , CFSTR (kIOHIDTransportKey ));
557565
558566 if (transport_prop != NULL && CFGetTypeID (transport_prop ) == CFStringGetTypeID ()) {
559567 if (CFStringCompare ((CFStringRef )transport_prop , CFSTR (kIOHIDTransportUSBValue ), 0 ) == kCFCompareEqualTo ) {
568+ int32_t interface_number = -1 ;
560569 cur_dev -> bus_type = HID_API_BUS_USB ;
570+ if (try_get_int_property (dev , CFSTR (kUSBInterfaceNumber ), & interface_number )) {
571+ cur_dev -> interface_number = interface_number ;
572+ }
573+ else {
574+ // TODO: use a different approach - this is a USB device after all
575+ }
576+
561577 /* Match "Bluetooth", "BluetoothLowEnergy" and "Bluetooth Low Energy" strings */
562578 } else if (CFStringHasPrefix ((CFStringRef )transport_prop , CFSTR (kIOHIDTransportBluetoothValue ))) {
563579 cur_dev -> bus_type = HID_API_BUS_BLUETOOTH ;
0 commit comments