5 // Created by Joe Wreschnig on 3/13/13.
9 #import "NJHIDManager.h"
11 @implementation NJHIDManager {
13 IOHIDManagerRef _manager;
16 - (id)initWithCriteria:(NSArray *)criteria
17 delegate:(id <NJHIDManagerDelegate>)delegate
19 if ((self = [super init])) {
20 self.criteria = criteria;
21 self.delegate = delegate;
30 static void input_callback(void *ctx, IOReturn inResult, void *inSender, IOHIDValueRef value) {
31 NJHIDManager *self = (__bridge NJHIDManager *)ctx;
32 IOHIDDeviceRef device = IOHIDQueueGetDevice(inSender);
33 [self.delegate hidManager:self valueChanged:value fromDevice:device];
36 static void add_callback(void *ctx, IOReturn inResult, void *inSender, IOHIDDeviceRef device) {
37 NJHIDManager *self = (__bridge NJHIDManager *)ctx;
38 [self.delegate hidManager:self deviceAdded:device];
39 IOHIDDeviceRegisterInputValueCallback(device, input_callback, ctx);
42 static void remove_callback(void *ctx, IOReturn inResult, void *inSender, IOHIDDeviceRef device) {
43 NJHIDManager *self = (__bridge NJHIDManager *)ctx;
44 [self.delegate hidManager:self deviceRemoved:device];
50 IOHIDManagerRef manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
51 IOHIDManagerSetDeviceMatchingMultiple(manager, (__bridge CFArrayRef)self.criteria);
52 IOReturn ret = IOHIDManagerOpen(manager, kIOHIDOptionsTypeNone);
53 if (ret != kIOReturnSuccess) {
54 NSError *error = [NSError errorWithDomain:NSMachErrorDomain code:ret userInfo:nil];
55 IOHIDManagerClose(manager, kIOHIDOptionsTypeNone);
57 [self.delegate hidManager:self didError:error];
58 NSLog(@"Error starting HID manager: %@.", error);
61 IOHIDManagerScheduleWithRunLoop(_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
62 IOHIDManagerRegisterDeviceMatchingCallback(_manager, add_callback, (__bridge void *)self);
63 IOHIDManagerRegisterDeviceRemovalCallback(_manager, remove_callback, (__bridge void *)self);
64 [self.delegate hidManagerDidStart:self];
65 NSLog(@"Started HID manager.");
72 IOHIDManagerUnscheduleFromRunLoop(_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
73 IOHIDManagerClose(_manager, kIOHIDOptionsTypeNone);
76 [self.delegate hidManagerDidStop:self];
77 NSLog(@"Stopped HID manager.");
84 - (NSArray *)criteria {
88 - (void)setCriteria:(NSArray *)criteria {
91 if (![criteria isEqualToArray:_criteria]) {
92 BOOL running = !!_manager;
94 _criteria = [criteria copy];