18 #include <IOKit/IOKitLib.h>
19 #include <IOKit/hid/IOHIDLib.h>
20 #include <IOKit/usb/USB.h>
27 "title" :
"VuoHidDevices",
29 "CoreFoundation.framework",
35 "VuoList_VuoHidControl",
36 "VuoList_VuoHidDevice",
52 CFNumberRef usagePageCF = (CFNumberRef)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDDeviceUsagePageKey));
54 CFNumberGetValue(usagePageCF, kCFNumberSInt32Type, usagePage);
57 usagePageCF = (CFNumberRef)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDPrimaryUsagePageKey));
59 CFNumberGetValue(usagePageCF, kCFNumberSInt32Type, usagePage);
62 CFNumberRef usageCF = (CFNumberRef)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDDeviceUsageKey));
64 CFNumberGetValue(usageCF, kCFNumberSInt32Type, usage);
67 usageCF = (CFNumberRef)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDPrimaryUsageKey));
69 CFNumberGetValue(usageCF, kCFNumberSInt32Type, usage);
78 CFNumberRef vendorIDCF = (CFNumberRef)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVendorIDKey));
81 uint32_t vendorID32 = 0;
82 CFNumberGetValue(vendorIDCF, kCFNumberSInt32Type, &vendorID32);
83 *vendorID = vendorID32;
86 CFStringRef manufacturerCF = (CFStringRef)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDManufacturerKey));
100 CFNumberRef productIDCF = (CFNumberRef)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductIDKey));
103 uint32_t productID32 = 0;
104 CFNumberGetValue(productIDCF, kCFNumberSInt32Type, &productID32);
105 *productID = productID32;
110 io_service_t service = IOHIDDeviceGetService(device);
111 io_registry_entry_t parent;
112 IORegistryEntryGetParentEntry(service, kIOServicePlane, &parent);
113 CFStringRef interfaceNameCF = (CFStringRef)IORegistryEntryCreateCFProperty(parent, CFSTR(
"USB Interface Name"), NULL, 0);
118 CFStringRef productCF = (CFStringRef)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
138 IOHIDDeviceRef device = (IOHIDDeviceRef)d;
140 CFNumberRef locationIDCF = (CFNumberRef)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDLocationIDKey));
141 uint32_t location = 0;
143 CFNumberGetValue(locationIDCF, kCFNumberSInt32Type, &location);
145 io_service_t service = IOHIDDeviceGetService(device);
146 io_registry_entry_t parent;
147 IORegistryEntryGetParentEntry(service, kIOServicePlane, &parent);
148 CFNumberRef interfaceNumberCF = (CFNumberRef)IORegistryEntryCreateCFProperty(parent, CFSTR(kUSBInterfaceNumber), NULL, 0);
149 uint32_t interfaceNumber = 0xff;
150 if (interfaceNumberCF)
152 CFNumberGetValue(interfaceNumberCF, kCFNumberSInt32Type, &interfaceNumber);
153 CFRelease(interfaceNumberCF);
156 return (location << 8) + interfaceNumber;
164 IOHIDElementRef element = (IOHIDElementRef)e;
167 uint32_t usage = IOHIDElementGetUsage(element);
180 IOHIDElementType elementType = IOHIDElementGetType(element);
181 if (elementType != kIOHIDElementTypeInput_Misc
182 && elementType != kIOHIDElementTypeInput_Button)
193 IOHIDElementRef element = (IOHIDElementRef)e;
195 uint32_t usagePage = IOHIDElementGetUsagePage(element);
196 uint32_t usage = IOHIDElementGetUsage(element);
199 VuoInteger min = IOHIDElementGetLogicalMin(element);
200 VuoInteger max = IOHIDElementGetLogicalMax(element);
219 IOHIDManagerRef manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
222 VUserLog(
"Error: Couldn't initialize IOHIDManager.");
226 IOHIDManagerSetDeviceMatching(manager, NULL);
228 IOHIDDeviceRef *devicesIO = NULL;
231 IOReturn ret = IOHIDManagerOpen(manager, kIOHIDOptionsTypeNone);
232 if (ret != kIOReturnSuccess)
234 if (ret == kIOReturnExclusiveAccess)
242 VUserLog(
"Error: Couldn't open IOHIDManager: %s", text);
249 CFSetRef deviceCF = IOHIDManagerCopyDevices(manager);
252 VUserLog(
"Error: Couldn't copy device list.");
257 deviceCount = CFSetGetCount(deviceCF);
258 devicesIO = (IOHIDDeviceRef *)malloc(
sizeof(IOHIDDeviceRef) * deviceCount);
259 CFSetGetValues(deviceCF, (
const void **)devicesIO);
264 for (CFIndex deviceIndex = 0; deviceIndex < deviceCount; ++deviceIndex)
266 uint32_t usagePage = 0;
279 if (vendorID == 0x05ac
280 && ( productID == 0x0262
281 || productID == 0x0259)
282 && ((usagePage == 0x0001 && usage == 0x0002)
283 || (usagePage == 0xff00 && usage == 0x0001))
286 && strcmp(manufacturer,
"Apple Inc.") == 0
287 && strcmp(product,
"Touchpad") == 0)
295 if (product && strcmp(product,
"Apple Internal Keyboard / Trackpad") == 0)
303 VuoHidDevice device = {VuoHidDevice_MatchLocation, NULL, 0, NULL, vendorID, productID, usagePage, usage};
304 if (manufacturer && product)
306 else if (manufacturer)
318 CFArrayRef elementsCF = IOHIDDeviceCopyMatchingElements(devicesIO[deviceIndex], NULL, kIOHIDOptionsTypeNone);
321 CFIndex elementCount = CFArrayGetCount(elementsCF);
323 for (CFIndex elementIndex = 0; elementIndex < elementCount; ++elementIndex)
325 IOHIDElementRef element = (IOHIDElementRef)CFArrayGetValueAtIndex(elementsCF, elementIndex);
335 CFRelease(elementsCF);
342 VDebugLog(
"\t\tSkipping this device since it doesn't have any valid elements.");
345 VDebugLog(
"\t\tSkipping this device since I can't get its elements (perhaps another process has it open for exclusive access).");
351 VuoListSort_VuoHidDevice(devices);
387 VuoHid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
390 VUserLog(
"Error: Couldn't initialize IOHIDManager.");
397 IOReturn ret = IOHIDManagerOpen(
VuoHid_manager, kIOHIDOptionsTypeNone);
398 if (ret != kIOReturnSuccess)
400 if (ret == kIOReturnExclusiveAccess)
408 VUserLog(
"Error: Couldn't open IOHIDManager: %s", text);
418 IOHIDManagerScheduleWithRunLoop(
VuoHid_manager, CFRunLoopGetMain(), kCFRunLoopDefaultMode);
425 usleep(USEC_PER_SEC / 10);
441 VUserLog(
"Error: Unbalanced VuoHid_use() / _disuse() calls.");