// Created by Sam McCall on 4/05/09.
//
-@implementation Joystick
-
+@implementation Joystick {
+ NSMutableArray *children;
+}
-@synthesize vendorId, productId, productName, name, index, device, children;
+@synthesize vendorId, productId, productName, index, device, children;
--(id)initWithDevice: (IOHIDDeviceRef) newDevice {
- if(self=[super init]) {
- children = [[NSMutableArray alloc]init];
-
- device = newDevice;
- productName = (__bridge NSString*)IOHIDDeviceGetProperty( device, CFSTR(kIOHIDProductKey) );
- vendorId = [(__bridge NSNumber*)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVendorIDKey)) intValue];
- productId = [(__bridge NSNumber*)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVendorIDKey)) intValue];
+- (id)initWithDevice: (IOHIDDeviceRef) newDevice {
+ if ((self = [super init])) {
+ children = [[NSMutableArray alloc] init];
- name = productName;
+ 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;
}
--(void) setIndex: (int) newIndex {
- index = newIndex;
- name = [[NSString alloc] initWithFormat: @"%@ #%d", productName, (index+1)];
-}
--(int) index {
- return index;
-}
-
--(void) invalidate {
- IOHIDDeviceClose(device, kIOHIDOptionsTypeNone);
- NSLog(@"Removed a device: %@", [self name]);
+- (NSString *)name {
+ return [[NSString alloc] initWithFormat: @"%@ #%d", productName, index + 1];
}
-(id) base {
[outlineView expandItem: handler];
}
-BOOL objInArray(NSMutableArray *array, id object) {
- for (id o in array) {
- if (o == object)
- return true;
- }
- return false;
-}
-
-void timer_callback(CFRunLoopTimerRef timer, void *ctx) {
+static void timer_callback(CFRunLoopTimerRef timer, void *ctx) {
JoystickController *jc = (__bridge JoystickController *)ctx;
jc->mouseLoc = [NSEvent mouseLocation];
for (Target *target in [jc runningTargets]) {
}
}
-void input_callback(void* inContext, IOReturn inResult, void* inSender, IOHIDValueRef value) {
- JoystickController* self = (__bridge JoystickController*)inContext;
- IOHIDDeviceRef device = IOHIDQueueGetDevice((IOHIDQueueRef) inSender);
+static void input_callback(void *ctx, IOReturn inResult, void *inSender, IOHIDValueRef value) {
+ JoystickController *controller = (__bridge JoystickController *)ctx;
+ IOHIDDeviceRef device = IOHIDQueueGetDevice(inSender);
- Joystick* js = [self findJoystickByRef: device];
+ Joystick *js = [controller findJoystickByRef:device];
if([(ApplicationController *)[[NSApplication sharedApplication] delegate] active]) {
- // for reals
JSAction* mainAction = [js actionForEvent: value];
if(!mainAction)
return;
if(!subactions)
subactions = @[mainAction];
for(id subaction in subactions) {
- Target* target = [[self->configsController currentConfig] getTargetForAction:subaction];
+ Target* target = [[controller->configsController currentConfig] getTargetForAction:subaction];
if(!target)
continue;
/* target application? doesn't seem to be any need since we are only active when it's in front */
/* might be required for some strange actions */
if ([target running] != [subaction active]) {
if ([subaction active]) {
- [target trigger: self];
+ [target trigger: controller];
}
else {
- [target untrigger: self];
+ [target untrigger: controller];
}
[target setRunning: [subaction active]];
}
// Add to list of running targets
if ([target isContinuous] && [target running]) {
- if (!objInArray([self runningTargets], target)) {
- [[self runningTargets] addObject: target];
+ if (![controller.runningTargets containsObject:target]) {
+ [[controller runningTargets] addObject: target];
}
}
}
if(!handler)
return;
- [self expandRecursive: handler];
- self->programmaticallySelecting = YES;
- [self->outlineView selectRowIndexes: [NSIndexSet indexSetWithIndex: [self->outlineView rowForItem: handler]] byExtendingSelection: NO];
+ [controller expandRecursive: handler];
+ controller->programmaticallySelecting = YES;
+ [controller->outlineView selectRowIndexes: [NSIndexSet indexSetWithIndex: [controller->outlineView rowForItem: handler]] byExtendingSelection: NO];
}
}
-int findAvailableIndex(id list, Joystick* js) {
+static int findAvailableIndex(id list, Joystick* js) {
BOOL available;
Joystick* js2;
for(int index=0;;index++) {
}
}
-void add_callback(void* inContext, IOReturn inResult, void* inSender, IOHIDDeviceRef device) {
- JoystickController* self = (__bridge JoystickController*)inContext;
-
- IOHIDDeviceOpen(device, kIOHIDOptionsTypeNone);
- IOHIDDeviceRegisterInputValueCallback(device, input_callback, (void*) CFBridgingRetain(self));
-
- Joystick *js = [[Joystick alloc] initWithDevice: device];
- [js setIndex: findAvailableIndex([self joysticks], js)];
-
+static void add_callback(void *ctx, IOReturn inResult, void *inSender, IOHIDDeviceRef device) {
+ JoystickController *controller = (__bridge JoystickController *)ctx;
+ IOHIDDeviceRegisterInputValueCallback(device, input_callback, (__bridge void*)controller);
+ Joystick *js = [[Joystick alloc] initWithDevice:device];
+ js.index = findAvailableIndex(controller.joysticks, js);
[js populateActions];
-
- [[self joysticks] addObject: js];
- [self->outlineView reloadData];
+ [[controller joysticks] addObject:js];
+ [controller->outlineView reloadData];
}
--(Joystick*) findJoystickByRef: (IOHIDDeviceRef) device {
+- (Joystick *)findJoystickByRef:(IOHIDDeviceRef)device {
for (Joystick *js in joysticks)
if (js.device == device)
return js;
return nil;
}
-void remove_callback(void* inContext, IOReturn inResult, void* inSender, IOHIDDeviceRef device) {
- JoystickController* self = CFBridgingRelease(inContext);
-
- Joystick* match = [self findJoystickByRef: device];
- if(!match)
- return;
-
- [[self joysticks] removeObject: match];
-
- [match invalidate];
- [self->outlineView reloadData];
+static void remove_callback(void *ctx, IOReturn inResult, void *inSender, IOHIDDeviceRef device) {
+ JoystickController *controller = (__bridge JoystickController *)ctx;
+ Joystick *match = [controller findJoystickByRef:device];
+ IOHIDDeviceRegisterInputValueCallback(device, NULL, NULL);
+ if (match) {
+ [controller.joysticks removeObject:match];
+ [controller->outlineView reloadData];
+ }
}
--(void) setup {
+- (void)setup {
hidManager = IOHIDManagerCreate( kCFAllocatorDefault, kIOHIDOptionsTypeNone);
- NSArray *criteria = @[create_criterion(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick),
- create_criterion(kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad),
- create_criterion(kHIDPage_GenericDesktop, kHIDUsage_GD_MultiAxisController)];
+ NSArray *criteria = @[
+ create_criterion(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick),
+ create_criterion(kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad),
+ create_criterion(kHIDPage_GenericDesktop, kHIDUsage_GD_MultiAxisController)];
IOHIDManagerSetDeviceMatchingMultiple(hidManager, (CFArrayRef)CFBridgingRetain(criteria));
IOReturn tIOReturn = IOHIDManagerOpen( hidManager, kIOHIDOptionsTypeNone );
(void)tIOReturn;
- IOHIDManagerRegisterDeviceMatchingCallback( hidManager, add_callback, (__bridge void*)self );
- IOHIDManagerRegisterDeviceRemovalCallback(hidManager, remove_callback, (__bridge void*) self);
-// IOHIDManagerRegisterInputValueCallback(hidManager, input_callback, (void*)self);
-// register individually so we can find the device more easily
-
-
-
+ IOHIDManagerRegisterDeviceMatchingCallback(hidManager, add_callback, (__bridge void *)self );
+ IOHIDManagerRegisterDeviceRemovalCallback(hidManager, remove_callback, (__bridge void *)self);
+
// Setup timer for continuous targets
CFRunLoopTimerContext ctx = {
0, (__bridge void*)self, NULL, NULL, NULL