Remove website, now in yukkurigames.com repository.
[enjoyable.git] / Classes / NJHIDManager.m
1 #import "NJHIDManager.h"
2
3 @implementation NJHIDManager {
4 NSArray *_criteria;
5 IOHIDManagerRef _manager;
6 }
7
8 - (id)initWithCriteria:(NSArray *)criteria
9 delegate:(id <NJHIDManagerDelegate>)delegate
10 {
11 if ((self = [super init])) {
12 self.criteria = criteria;
13 self.delegate = delegate;
14 }
15 return self;
16 }
17
18 - (void)dealloc {
19 [self stop];
20 }
21
22 static void _input(void *ctx, IOReturn inResult, void *inSender, IOHIDValueRef value) {
23 NJHIDManager *self = (__bridge NJHIDManager *)ctx;
24 [self.delegate HIDManager:self valueChanged:value];
25 }
26
27 static void _add(void *ctx, IOReturn inResult, void *inSender, IOHIDDeviceRef device) {
28 NJHIDManager *self = (__bridge NJHIDManager *)ctx;
29 [self.delegate HIDManager:self deviceAdded:device];
30 IOHIDDeviceRegisterInputValueCallback(device, _input, ctx);
31 }
32
33 static void _remove(void *ctx, IOReturn inResult, void *inSender, IOHIDDeviceRef device) {
34 NJHIDManager *self = (__bridge NJHIDManager *)ctx;
35 [self.delegate HIDManager:self deviceRemoved:device];
36 }
37
38 - (void)start {
39 if (self.running)
40 return;
41 IOHIDManagerRef manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
42 IOHIDManagerSetDeviceMatchingMultiple(manager, (__bridge CFArrayRef)self.criteria);
43 IOReturn ret = IOHIDManagerOpen(manager, kIOHIDOptionsTypeNone);
44 if (ret != kIOReturnSuccess) {
45 NSError *error = [NSError errorWithDomain:NSMachErrorDomain code:ret userInfo:nil];
46 IOHIDManagerClose(manager, kIOHIDOptionsTypeNone);
47 CFRelease(manager);
48 [self.delegate HIDManager:self didError:error];
49 NSLog(@"Error starting HID manager: %@.", error);
50 } else {
51 _manager = manager;
52 IOHIDManagerScheduleWithRunLoop(_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
53 IOHIDManagerRegisterDeviceMatchingCallback(_manager, _add, (__bridge void *)self);
54 IOHIDManagerRegisterDeviceRemovalCallback(_manager, _remove, (__bridge void *)self);
55 [self.delegate HIDManagerDidStart:self];
56 NSLog(@"Started HID manager.");
57 }
58 }
59
60 - (void)stop {
61 if (!self.running)
62 return;
63 IOHIDManagerUnscheduleFromRunLoop(_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
64 IOHIDManagerClose(_manager, kIOHIDOptionsTypeNone);
65 CFRelease(_manager);
66 _manager = NULL;
67 [self.delegate HIDManagerDidStop:self];
68 NSLog(@"Stopped HID manager.");
69 }
70
71 - (BOOL)running {
72 return !!_manager;
73 }
74
75 - (void)setRunning:(BOOL)running {
76 if (running)
77 [self start];
78 else
79 [self stop];
80 }
81
82 - (NSArray *)criteria {
83 return _criteria;
84 }
85
86 - (void)setCriteria:(NSArray *)criteria {
87 if (!criteria)
88 criteria = @[];
89 if (![criteria isEqualToArray:_criteria]) {
90 BOOL running = !!_manager;
91 [self stop];
92 _criteria = [criteria copy];
93 if (running)
94 [self start];
95 }
96 }
97
98 @end