Forked Enjoy, mouse movement
[enjoyable.git] / Joystick.m
1 //
2 // Joystick.m
3 // Enjoy
4 //
5 // Created by Sam McCall on 4/05/09.
6 //
7
8 @implementation Joystick
9
10
11 @synthesize vendorId, productId, productName, name, index, device, children;
12
13 -(id)initWithDevice: (IOHIDDeviceRef) newDevice {
14 if(self=[super init]) {
15 children = [[NSMutableArray alloc]init];
16
17 device = newDevice;
18 productName = (NSString*)IOHIDDeviceGetProperty( device, CFSTR(kIOHIDProductKey) );
19 vendorId = [(NSNumber*)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVendorIDKey)) intValue];
20 productId = [(NSNumber*)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVendorIDKey)) intValue];
21
22 name = productName;
23 }
24 return self;
25 }
26
27 -(void) setIndex: (int) newIndex {
28 index = newIndex;
29 name = [[NSString alloc] initWithFormat: @"%@ #%d", productName, (index+1)];
30 }
31 -(int) index {
32 return index;
33 }
34
35 -(void) invalidate {
36 IOHIDDeviceClose(device, kIOHIDOptionsTypeNone);
37 NSLog(@"Removed a device: %@", [self name]);
38 }
39
40 -(id) base {
41 return NULL;
42 }
43
44 -(void) populateActions {
45 NSArray* elements = (NSArray*)IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone);
46
47 int buttons = 0;
48 int axes = 0;
49
50 for(int i=0; i<[elements count]; i++) {
51 IOHIDElementRef element = (IOHIDElementRef)[elements objectAtIndex: i];
52 int type = IOHIDElementGetType(element);
53 int usage = IOHIDElementGetUsage(element);
54 int usagePage = IOHIDElementGetUsagePage(element);
55 int max = IOHIDElementGetPhysicalMax(element);
56 int min = IOHIDElementGetPhysicalMin(element);
57 CFStringRef elName = IOHIDElementGetName(element);
58
59 // if(usagePage != 1 || usagePage == 9) {
60 // NSLog(@"Skipping usage page %x usage %x", usagePage, usage);
61 // continue;
62 // }
63
64 JSAction* action = NULL;
65
66 if(!(type == kIOHIDElementTypeInput_Misc || type == kIOHIDElementTypeInput_Axis ||
67 type == kIOHIDElementTypeInput_Button)) {
68
69 continue;
70 }
71
72 if((max - min == 1) || usagePage == kHIDPage_Button || type == kIOHIDElementTypeInput_Button) {
73 action = [[JSActionButton alloc] initWithIndex: buttons++ andName: (NSString *)elName];
74 [(JSActionButton*)action setMax: max];
75 } else if(usage == 0x39)
76 action = [[JSActionHat alloc] init];
77 else {
78 if(usage >= 0x30 && usage < 0x36) {
79 action = [[JSActionAnalog alloc] initWithIndex: axes++];
80 [(JSActionAnalog*)action setOffset: (double)-1.0];
81 [(JSActionAnalog*)action setScale: (double)2.0/(max - min)];
82 } else
83 continue;
84 }
85
86 [action setBase: self];
87 [action setUsage: usage];
88 [action setCookie: IOHIDElementGetCookie(element)];
89 [children addObject:action];
90 }
91 }
92
93 -(NSString*) stringify {
94 return [[NSString alloc] initWithFormat: @"%d~%d~%d", vendorId, productId, index];
95 }
96
97 - (JSAction*) findActionByCookie: (void*) cookie {
98 for(int i=0; i<[children count]; i++)
99 if([[children objectAtIndex:i]cookie] == cookie)
100 return (JSAction*)[children objectAtIndex:i];
101 return NULL;
102 }
103
104 -(id) handlerForEvent: (IOHIDValueRef) value {
105 JSAction* mainAction = [self actionForEvent: value];
106 if(!mainAction)
107 return NULL;
108 return [mainAction findSubActionForValue: value];
109 }
110 -(JSAction*) actionForEvent: (IOHIDValueRef) value {
111 IOHIDElementRef elt = IOHIDValueGetElement(value);
112 void* cookie = IOHIDElementGetCookie(elt);
113 return [self findActionByCookie: cookie];
114 }
115
116 @end