-- (id)initWithDevice: (IOHIDDeviceRef) newDevice {
- if ((self = [super init])) {
- children = [[NSMutableArray alloc] init];
-
- self.device = newDevice;
- self.productName = (__bridge NSString *)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
- self.vendorId = [(__bridge NSNumber *)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVendorIDKey)) intValue];
- self.productId = [(__bridge NSNumber *)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVendorIDKey)) intValue];
- }
- return self;
-}
+static NSArray *ActionsForElement(IOHIDDeviceRef device, id base) {
+ CFArrayRef elements = IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone);
+ NSMutableArray *children = [NSMutableArray arrayWithCapacity:CFArrayGetCount(elements)];
+
+ int buttons = 0;
+ int axes = 0;
+ int hats = 0;
+
+ for (int i = 0; i < CFArrayGetCount(elements); i++) {
+ IOHIDElementRef element = (IOHIDElementRef)CFArrayGetValueAtIndex(elements, i);
+ int type = IOHIDElementGetType(element);
+ unsigned usage = IOHIDElementGetUsage(element);
+ unsigned usagePage = IOHIDElementGetUsagePage(element);
+ long max = IOHIDElementGetPhysicalMax(element);
+ long min = IOHIDElementGetPhysicalMin(element);
+ CFStringRef elName = IOHIDElementGetName(element);
+
+ JSAction *action = nil;
+
+ if (!(type == kIOHIDElementTypeInput_Misc
+ || type == kIOHIDElementTypeInput_Axis
+ || type == kIOHIDElementTypeInput_Button))
+ continue;
+
+ if (max - min == 1 || usagePage == kHIDPage_Button || type == kIOHIDElementTypeInput_Button) {
+ action = [[JSActionButton alloc] initWithName:(__bridge NSString *)elName
+ idx:++buttons
+ max:max];
+ } else if (usage == kHIDUsage_GD_Hatswitch) {
+ action = [[JSActionHat alloc] initWithIndex:++hats];
+ } else if (usage >= kHIDUsage_GD_X && usage <= kHIDUsage_GD_Rz) {
+ action = [[JSActionAnalog alloc] initWithIndex:++axes
+ rawMin:min
+ rawMax:max];
+ } else {
+ continue;
+ }
+
+ // TODO(jfw): Should be moved into better constructors.
+ action.base = base;
+ action.cookie = IOHIDElementGetCookie(element);
+ [children addObject:action];
+ }