Big rename part 1: 'action' to 'input'.
authorJoe Wreschnig <joe.wreschnig@gmail.com>
Sun, 3 Mar 2013 20:42:59 +0000 (21:42 +0100)
committerJoe Wreschnig <joe.wreschnig@gmail.com>
Sun, 3 Mar 2013 20:42:59 +0000 (21:42 +0100)
39 files changed:
ApplicationController.h
ApplicationController.m
Config.h
Config.m
English.lproj/MainMenu.xib
Enjoyable.xcodeproj/project.pbxproj
JSAction.h [deleted file]
JSAction.m [deleted file]
JSActionAnalog.h [deleted file]
JSActionAnalog.m [deleted file]
JSActionButton.h [deleted file]
JSActionButton.m [deleted file]
JSActionHat.h [deleted file]
JSActionHat.m [deleted file]
Joystick.h [deleted file]
Joystick.m [deleted file]
JoystickController.h [deleted file]
JoystickController.m [deleted file]
NJActionPathElement.h [deleted file]
NJDevice.h [new file with mode: 0644]
NJDevice.m [new file with mode: 0644]
NJInput.h [new file with mode: 0644]
NJInput.m [new file with mode: 0644]
NJInputAnalog.h [new file with mode: 0644]
NJInputAnalog.m [new file with mode: 0644]
NJInputButton.h [new file with mode: 0644]
NJInputButton.m [new file with mode: 0644]
NJInputController.h [new file with mode: 0644]
NJInputController.m [new file with mode: 0644]
NJInputHat.h [new file with mode: 0644]
NJInputHat.m [new file with mode: 0644]
NJInputPathElement.h [new file with mode: 0644]
Target.h
Target.m
TargetController.h
TargetController.m
TargetMouseMove.m
TargetMouseScroll.m
TargetToggleMouseScope.m

index dc513aee13fcf9ec5e02179bc16afeee0d2b0146..5dae0cc04a525b0d295aba4ec8bc3d36c90b8f23 100644 (file)
@@ -6,7 +6,7 @@
 //  Copyright 2009 University of Otago. All rights reserved.
 //
 
-@class JoystickController;
+@class NJInputController;
 @class TargetController;
 @class ConfigsController;
 
@@ -18,7 +18,7 @@
     IBOutlet NSMenu *dockMenuBase;
 }
 
-@property (nonatomic, strong) IBOutlet JoystickController *jsController;
+@property (nonatomic, strong) IBOutlet NJInputController *jsController;
 @property (nonatomic, strong) IBOutlet TargetController *targetController;
 @property (nonatomic, strong) IBOutlet ConfigsController *configsController;
 
index 1acc692151d78f548dda0c36cfbb872952338145..bc7c4689c3fb75d6eb942123a58f17f723400a7c 100644 (file)
@@ -9,7 +9,7 @@
 
 #import "Config.h"
 #import "ConfigsController.h"
-#import "JoystickController.h"
+#import "NJInputController.h"
 #import "TargetController.h"
 #import "NJEvents.h"
 
index 606529dc46d2c95d9580b54d11d435bb8be3eff6..a2ba55b6f3deb16c0ad324e344d673d7fc034f5f 100644 (file)
--- a/Config.h
+++ b/Config.h
@@ -7,7 +7,7 @@
 //
 
 @class Target;
-@class JSAction;
+@class NJInput;
 
 @interface Config : NSObject
 
@@ -15,8 +15,8 @@
 @property (nonatomic, readonly) NSMutableDictionary *entries;
 
 - (id)initWithName:(NSString *)name;
-- (Target *)objectForKeyedSubscript:(JSAction *)action;
-- (void)setObject:(Target *)target forKeyedSubscript:(JSAction *)action;
+- (Target *)objectForKeyedSubscript:(NJInput *)input;
+- (void)setObject:(Target *)target forKeyedSubscript:(NJInput *)input;
 - (NSDictionary *)serialize;
 
 @end
index 046ccc2c6fa22980952d76ab84f0b59c76bea1a6..189773436a41c7af148000a5834d65aafffa7d6a 100644 (file)
--- a/Config.m
+++ b/Config.m
@@ -7,7 +7,7 @@
 
 #import "Config.h"
 
-#import "JSAction.h"
+#import "NJInput.h"
 
 @implementation Config
 
     return self;
 }
 
-- (Target *)objectForKeyedSubscript:(JSAction *)action {
-    return action ? _entries[action.uid] : nil;
+- (Target *)objectForKeyedSubscript:(NJInput *)input {
+    return input ? _entries[input.uid] : nil;
 }
 
-- (void)setObject:(Target *)target forKeyedSubscript:(JSAction *)action {
-    if (action) {
+- (void)setObject:(Target *)target forKeyedSubscript:(NJInput *)input {
+    if (input) {
         if (target)
-            _entries[action.uid] = target;
+            _entries[input.uid] = target;
         else
-            [_entries removeObjectForKey:action.uid];
+            [_entries removeObjectForKey:input.uid];
     }
 }
 
index 6e87fb02440bdad0d36971862161b6b324042b33..e1e7aa1304c737843d042be4e8430f6444383959 100644 (file)
                                <nil key="NSUserInterfaceItemIdentifier"/>
                                <string key="NSWindowContentMinSize">{640, 300}</string>
                                <object class="NSView" key="NSWindowView" id="177223957">
-                                       <reference key="NSNextResponder"/>
+                                       <nil key="NSNextResponder"/>
                                        <int key="NSvFlags">256</int>
                                        <array class="NSMutableArray" key="NSSubviews">
                                                <object class="NSSplitView" id="206489479">
                                                                                                                        <int key="NSvFlags">256</int>
                                                                                                                        <string key="NSFrameSize">{200, 298}</string>
                                                                                                                        <reference key="NSSuperview" ref="698362889"/>
-                                                                                                                       <reference key="NSWindow"/>
-                                                                                                                       <reference key="NSNextKeyView" ref="1036252745"/>
+                                                                                                                       <reference key="NSNextKeyView" ref="892486973"/>
                                                                                                                        <bool key="NSEnabled">YES</bool>
                                                                                                                        <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
                                                                                                                        <bool key="NSControlAllowsExpansionToolTips">YES</bool>
                                                                                                        </array>
                                                                                                        <string key="NSFrame">{{1, 1}, {200, 298}}</string>
                                                                                                        <reference key="NSSuperview" ref="364857164"/>
-                                                                                                       <reference key="NSWindow"/>
                                                                                                        <reference key="NSNextKeyView" ref="365506042"/>
                                                                                                        <reference key="NSDocView" ref="365506042"/>
                                                                                                        <reference key="NSBGColor" ref="834857663"/>
                                                                                                        <int key="NSvFlags">-2147483392</int>
                                                                                                        <string key="NSFrame">{{1, 1}, {8, 298}}</string>
                                                                                                        <reference key="NSSuperview" ref="364857164"/>
-                                                                                                       <reference key="NSWindow"/>
                                                                                                        <reference key="NSNextKeyView" ref="606740242"/>
                                                                                                        <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
                                                                                                        <reference key="NSTarget" ref="364857164"/>
                                                                                                        <int key="NSvFlags">-2147483392</int>
                                                                                                        <string key="NSFrame">{{-100, -100}, {473, 15}}</string>
                                                                                                        <reference key="NSSuperview" ref="364857164"/>
-                                                                                                       <reference key="NSWindow"/>
                                                                                                        <reference key="NSNextKeyView" ref="698362889"/>
                                                                                                        <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
                                                                                                        <int key="NSsFlags">1</int>
                                                                                        </array>
                                                                                        <string key="NSFrameSize">{202, 300}</string>
                                                                                        <reference key="NSSuperview" ref="977242492"/>
-                                                                                       <reference key="NSWindow"/>
-                                                                                       <reference key="NSNextKeyView" ref="892486973"/>
+                                                                                       <reference key="NSNextKeyView" ref="698362889"/>
                                                                                        <int key="NSsFlags">150034</int>
                                                                                        <reference key="NSVScroller" ref="1036252745"/>
                                                                                        <reference key="NSHScroller" ref="892486973"/>
                                                                        </array>
                                                                        <string key="NSFrameSize">{202, 300}</string>
                                                                        <reference key="NSSuperview" ref="206489479"/>
-                                                                       <reference key="NSWindow"/>
                                                                        <reference key="NSNextKeyView" ref="364857164"/>
                                                                        <string key="NSClassName">NSView</string>
                                                                </object>
                                                                                        <int key="NSvFlags">265</int>
                                                                                        <string key="NSFrame">{{227, 123}, {180, 24}}</string>
                                                                                        <reference key="NSSuperview" ref="606740242"/>
-                                                                                       <reference key="NSWindow"/>
                                                                                        <reference key="NSNextKeyView" ref="125828224"/>
                                                                                        <string key="NSReuseIdentifierKey">_NS:9</string>
                                                                                        <bool key="NSEnabled">YES</bool>
                                                                                        <int key="NSvFlags">265</int>
                                                                                        <string key="NSFrame">{{227, 55}, {180, 24}}</string>
                                                                                        <reference key="NSSuperview" ref="606740242"/>
-                                                                                       <reference key="NSWindow"/>
                                                                                        <string key="NSReuseIdentifierKey">_NS:9</string>
                                                                                        <bool key="NSEnabled">YES</bool>
                                                                                        <object class="NSSegmentedCell" key="NSCell" id="301345285">
                                                                                        <int key="NSvFlags">265</int>
                                                                                        <string key="NSFrame">{{227, 89}, {180, 24}}</string>
                                                                                        <reference key="NSSuperview" ref="606740242"/>
-                                                                                       <reference key="NSWindow"/>
                                                                                        <reference key="NSNextKeyView" ref="921829691"/>
                                                                                        <string key="NSReuseIdentifierKey">_NS:9</string>
                                                                                        <bool key="NSEnabled">YES</bool>
                                                                                        <int key="NSvFlags">265</int>
                                                                                        <string key="NSFrame">{{229, 190}, {176, 24}}</string>
                                                                                        <reference key="NSSuperview" ref="606740242"/>
-                                                                                       <reference key="NSWindow"/>
                                                                                        <reference key="NSNextKeyView" ref="194275224"/>
                                                                                        <string key="NSReuseIdentifierKey">_NS:9</string>
                                                                                        <string key="NSClassName">NJKeyInputField</string>
                                                                                        <int key="NSvFlags">265</int>
                                                                                        <string key="NSFrame">{{226, 156}, {182, 26}}</string>
                                                                                        <reference key="NSSuperview" ref="606740242"/>
-                                                                                       <reference key="NSWindow"/>
                                                                                        <reference key="NSNextKeyView" ref="875916470"/>
                                                                                        <bool key="NSEnabled">YES</bool>
                                                                                        <object class="NSPopUpButtonCell" key="NSCell" id="74311158">
                                                                                        <int key="NSvFlags">268</int>
                                                                                        <string key="NSFrame">{{20, 16}, {201, 236}}</string>
                                                                                        <reference key="NSSuperview" ref="606740242"/>
-                                                                                       <reference key="NSWindow"/>
                                                                                        <reference key="NSNextKeyView" ref="57697638"/>
                                                                                        <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
                                                                                        <int key="NSNumRows">7</int>
                                                                                        <int key="NSvFlags">266</int>
                                                                                        <string key="NSFrame">{{0, 269}, {429, 17}}</string>
                                                                                        <reference key="NSSuperview" ref="606740242"/>
-                                                                                       <reference key="NSWindow"/>
                                                                                        <reference key="NSNextKeyView" ref="497528019"/>
                                                                                        <bool key="NSEnabled">YES</bool>
                                                                                        <object class="NSTextFieldCell" key="NSCell" id="853503577">
                                                                                        <int key="NSvFlags">10</int>
                                                                                        <string key="NSFrame">{{12, 258}, {405, 5}}</string>
                                                                                        <reference key="NSSuperview" ref="606740242"/>
-                                                                                       <reference key="NSWindow"/>
                                                                                        <reference key="NSNextKeyView" ref="120408205"/>
                                                                                        <string key="NSOffsets">{0, 0}</string>
                                                                                        <object class="NSTextFieldCell" key="NSTitleCell">
                                                                        </array>
                                                                        <string key="NSFrame">{{211, 0}, {429, 300}}</string>
                                                                        <reference key="NSSuperview" ref="206489479"/>
-                                                                       <reference key="NSWindow"/>
                                                                        <reference key="NSNextKeyView" ref="1016088174"/>
                                                                        <string key="NSClassName">NSView</string>
                                                                </object>
                                                        </array>
                                                        <string key="NSFrameSize">{640, 300}</string>
                                                        <reference key="NSSuperview" ref="177223957"/>
-                                                       <reference key="NSWindow"/>
                                                        <reference key="NSNextKeyView" ref="977242492"/>
                                                        <bool key="NSIsVertical">YES</bool>
                                                </object>
                                        </array>
                                        <string key="NSFrameSize">{640, 300}</string>
-                                       <reference key="NSSuperview"/>
-                                       <reference key="NSWindow"/>
                                        <reference key="NSNextKeyView" ref="206489479"/>
                                </object>
                                <string key="NSScreenRect">{{0, 0}, {1440, 878}}</string>
                                <bool key="NSWindowIsRestorable">YES</bool>
                        </object>
                        <object class="NSCustomView" id="671181514">
-                               <reference key="NSNextResponder"/>
+                               <nil key="NSNextResponder"/>
                                <int key="NSvFlags">256</int>
                                <array class="NSMutableArray" key="NSSubviews">
                                        <object class="NSScrollView" id="443618264">
                                                                                <int key="NSvFlags">256</int>
                                                                                <string key="NSFrameSize">{320, 418}</string>
                                                                                <reference key="NSSuperview" ref="947403733"/>
-                                                                               <reference key="NSWindow"/>
                                                                                <reference key="NSNextKeyView" ref="968378655"/>
                                                                                <bool key="NSEnabled">YES</bool>
                                                                                <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
                                                                </array>
                                                                <string key="NSFrame">{{1, 1}, {320, 418}}</string>
                                                                <reference key="NSSuperview" ref="443618264"/>
-                                                               <reference key="NSWindow"/>
                                                                <reference key="NSNextKeyView" ref="762432499"/>
                                                                <reference key="NSDocView" ref="762432499"/>
                                                                <reference key="NSBGColor" ref="834857663"/>
                                                                <int key="NSvFlags">-2147483392</int>
                                                                <string key="NSFrame">{{306, 1}, {15, 403}}</string>
                                                                <reference key="NSSuperview" ref="443618264"/>
-                                                               <reference key="NSWindow"/>
                                                                <reference key="NSNextKeyView" ref="553414014"/>
                                                                <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
                                                                <reference key="NSTarget" ref="443618264"/>
                                                                <int key="NSvFlags">-2147483392</int>
                                                                <string key="NSFrame">{{1, 404}, {305, 15}}</string>
                                                                <reference key="NSSuperview" ref="443618264"/>
-                                                               <reference key="NSWindow"/>
                                                                <reference key="NSNextKeyView" ref="861276216"/>
                                                                <bool key="NSAllowsLogicalLayoutDirection">NO</bool>
                                                                <int key="NSsFlags">1</int>
                                                </array>
                                                <string key="NSFrame">{{0, 34}, {322, 420}}</string>
                                                <reference key="NSSuperview" ref="671181514"/>
-                                               <reference key="NSWindow"/>
                                                <reference key="NSNextKeyView" ref="947403733"/>
                                                <int key="NSsFlags">133682</int>
                                                <reference key="NSVScroller" ref="968378655"/>
                                                <int key="NSvFlags">260</int>
                                                <string key="NSFrame">{{10, 4}, {39, 28}}</string>
                                                <reference key="NSSuperview" ref="671181514"/>
-                                               <reference key="NSWindow"/>
                                                <reference key="NSNextKeyView" ref="456935010"/>
                                                <bool key="NSEnabled">YES</bool>
                                                <object class="NSButtonCell" key="NSCell" id="867532725">
                                                <int key="NSvFlags">260</int>
                                                <string key="NSFrame">{{57, 4}, {39, 28}}</string>
                                                <reference key="NSSuperview" ref="671181514"/>
-                                               <reference key="NSWindow"/>
                                                <bool key="NSEnabled">YES</bool>
                                                <object class="NSButtonCell" key="NSCell" id="1008023024">
                                                        <int key="NSCellFlags">603979776</int>
                                        </object>
                                </array>
                                <string key="NSFrameSize">{322, 454}</string>
-                               <reference key="NSSuperview"/>
-                               <reference key="NSWindow"/>
                                <reference key="NSNextKeyView" ref="443618264"/>
                                <string key="NSClassName">NSView</string>
                        </object>
                                <string key="NSClassName">ConfigsController</string>
                        </object>
                        <object class="NSCustomObject" id="1007832501">
-                               <string key="NSClassName">JoystickController</string>
+                               <string key="NSClassName">NJInputController</string>
                        </object>
                        <object class="NSCustomObject" id="801536542">
                                <string key="NSClassName">TargetController</string>
index e75f56c850d0a495f444b2ee148b2225f51db246..5b21e9922e9dd1f02cc6b2496f341a7b497e0c69 100644 (file)
                D549CA4C0FBB441B00BC8203 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = D549CA4B0FBB441B00BC8203 /* Credits.rtf */; };
                D5617A360FAEB74000928B3A /* ConfigsController.m in Sources */ = {isa = PBXBuildFile; fileRef = D5617A350FAEB74000928B3A /* ConfigsController.m */; };
                D5617A390FAEBA1800928B3A /* Config.m in Sources */ = {isa = PBXBuildFile; fileRef = D5617A380FAEBA1800928B3A /* Config.m */; };
-               D5617D1A0FAF568100928B3A /* JSActionButton.m in Sources */ = {isa = PBXBuildFile; fileRef = D5617D190FAF568100928B3A /* JSActionButton.m */; };
-               D5617D260FAF579300928B3A /* JSActionHat.m in Sources */ = {isa = PBXBuildFile; fileRef = D5617D250FAF579300928B3A /* JSActionHat.m */; };
-               D5617D2B0FAF579A00928B3A /* JSActionAnalog.m in Sources */ = {isa = PBXBuildFile; fileRef = D5617D2A0FAF579A00928B3A /* JSActionAnalog.m */; };
+               D5617D1A0FAF568100928B3A /* NJInputButton.m in Sources */ = {isa = PBXBuildFile; fileRef = D5617D190FAF568100928B3A /* NJInputButton.m */; };
+               D5617D260FAF579300928B3A /* NJInputHat.m in Sources */ = {isa = PBXBuildFile; fileRef = D5617D250FAF579300928B3A /* NJInputHat.m */; };
+               D5617D2B0FAF579A00928B3A /* NJInputAnalog.m in Sources */ = {isa = PBXBuildFile; fileRef = D5617D2A0FAF579A00928B3A /* NJInputAnalog.m */; };
                D5617FD60FAFD06000928B3A /* Target.m in Sources */ = {isa = PBXBuildFile; fileRef = D5617FD50FAFD06000928B3A /* Target.m */; };
                D5617FD90FAFD1E600928B3A /* TargetKeyboard.m in Sources */ = {isa = PBXBuildFile; fileRef = D5617FD80FAFD1E600928B3A /* TargetKeyboard.m */; };
                D5617FE40FAFD7B000928B3A /* TargetController.m in Sources */ = {isa = PBXBuildFile; fileRef = D5617FE30FAFD7B000928B3A /* TargetController.m */; };
                D5617FE70FAFDB5800928B3A /* NJKeyInputField.m in Sources */ = {isa = PBXBuildFile; fileRef = D5617FE60FAFDB5800928B3A /* NJKeyInputField.m */; };
-               D594BE860FAE6219007A85F2 /* Joystick.m in Sources */ = {isa = PBXBuildFile; fileRef = D594BE850FAE6219007A85F2 /* Joystick.m */; };
-               D594BE8A0FAE64AD007A85F2 /* JSAction.m in Sources */ = {isa = PBXBuildFile; fileRef = D594BE890FAE64AD007A85F2 /* JSAction.m */; };
-               D594BEF90FAE6FF2007A85F2 /* JoystickController.m in Sources */ = {isa = PBXBuildFile; fileRef = D594BEF80FAE6FF2007A85F2 /* JoystickController.m */; };
+               D594BE860FAE6219007A85F2 /* NJDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = D594BE850FAE6219007A85F2 /* NJDevice.m */; };
+               D594BE8A0FAE64AD007A85F2 /* NJInput.m in Sources */ = {isa = PBXBuildFile; fileRef = D594BE890FAE64AD007A85F2 /* NJInput.m */; };
+               D594BEF90FAE6FF2007A85F2 /* NJInputController.m in Sources */ = {isa = PBXBuildFile; fileRef = D594BEF80FAE6FF2007A85F2 /* NJInputController.m */; };
                D594BF000FAE7397007A85F2 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D594BEFF0FAE7397007A85F2 /* IOKit.framework */; };
                D594BF830FAE9661007A85F2 /* ApplicationController.m in Sources */ = {isa = PBXBuildFile; fileRef = D594BF820FAE9661007A85F2 /* ApplicationController.m */; };
                D5F809710FB093400006A4DE /* TargetConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = D5F809700FB093400006A4DE /* TargetConfig.m */; };
                D5617A350FAEB74000928B3A /* ConfigsController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ConfigsController.m; sourceTree = "<group>"; };
                D5617A370FAEBA1800928B3A /* Config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Config.h; sourceTree = "<group>"; };
                D5617A380FAEBA1800928B3A /* Config.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Config.m; sourceTree = "<group>"; };
-               D5617D180FAF568100928B3A /* JSActionButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSActionButton.h; sourceTree = "<group>"; };
-               D5617D190FAF568100928B3A /* JSActionButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JSActionButton.m; sourceTree = "<group>"; };
-               D5617D240FAF579300928B3A /* JSActionHat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSActionHat.h; sourceTree = "<group>"; };
-               D5617D250FAF579300928B3A /* JSActionHat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JSActionHat.m; sourceTree = "<group>"; };
-               D5617D290FAF579A00928B3A /* JSActionAnalog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSActionAnalog.h; sourceTree = "<group>"; };
-               D5617D2A0FAF579A00928B3A /* JSActionAnalog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JSActionAnalog.m; sourceTree = "<group>"; };
+               D5617D180FAF568100928B3A /* NJInputButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NJInputButton.h; sourceTree = "<group>"; };
+               D5617D190FAF568100928B3A /* NJInputButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NJInputButton.m; sourceTree = "<group>"; };
+               D5617D240FAF579300928B3A /* NJInputHat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NJInputHat.h; sourceTree = "<group>"; };
+               D5617D250FAF579300928B3A /* NJInputHat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NJInputHat.m; sourceTree = "<group>"; };
+               D5617D290FAF579A00928B3A /* NJInputAnalog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NJInputAnalog.h; sourceTree = "<group>"; };
+               D5617D2A0FAF579A00928B3A /* NJInputAnalog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NJInputAnalog.m; sourceTree = "<group>"; };
                D5617FD40FAFD06000928B3A /* Target.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Target.h; sourceTree = "<group>"; };
                D5617FD50FAFD06000928B3A /* Target.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Target.m; sourceTree = "<group>"; };
                D5617FD70FAFD1E600928B3A /* TargetKeyboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TargetKeyboard.h; sourceTree = "<group>"; };
                D5617FE30FAFD7B000928B3A /* TargetController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TargetController.m; sourceTree = "<group>"; };
                D5617FE50FAFDB5800928B3A /* NJKeyInputField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NJKeyInputField.h; sourceTree = "<group>"; };
                D5617FE60FAFDB5800928B3A /* NJKeyInputField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NJKeyInputField.m; sourceTree = "<group>"; };
-               D594BE840FAE6219007A85F2 /* Joystick.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Joystick.h; sourceTree = "<group>"; };
-               D594BE850FAE6219007A85F2 /* Joystick.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Joystick.m; sourceTree = "<group>"; };
-               D594BE880FAE64AD007A85F2 /* JSAction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSAction.h; sourceTree = "<group>"; };
-               D594BE890FAE64AD007A85F2 /* JSAction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JSAction.m; sourceTree = "<group>"; };
-               D594BEF70FAE6FF2007A85F2 /* JoystickController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JoystickController.h; sourceTree = "<group>"; };
-               D594BEF80FAE6FF2007A85F2 /* JoystickController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JoystickController.m; sourceTree = "<group>"; };
+               D594BE840FAE6219007A85F2 /* NJDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NJDevice.h; sourceTree = "<group>"; };
+               D594BE850FAE6219007A85F2 /* NJDevice.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NJDevice.m; sourceTree = "<group>"; };
+               D594BE880FAE64AD007A85F2 /* NJInput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NJInput.h; sourceTree = "<group>"; };
+               D594BE890FAE64AD007A85F2 /* NJInput.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NJInput.m; sourceTree = "<group>"; };
+               D594BEF70FAE6FF2007A85F2 /* NJInputController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NJInputController.h; sourceTree = "<group>"; };
+               D594BEF80FAE6FF2007A85F2 /* NJInputController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NJInputController.m; sourceTree = "<group>"; };
                D594BEFF0FAE7397007A85F2 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = "<absolute>"; };
                D594BF810FAE9661007A85F2 /* ApplicationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ApplicationController.h; sourceTree = "<group>"; };
                D594BF820FAE9661007A85F2 /* ApplicationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ApplicationController.m; sourceTree = "<group>"; };
@@ -89,7 +89,7 @@
                EE1D7C9116E01E7000B000EB /* NSView+FirstResponder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSView+FirstResponder.m"; sourceTree = "<group>"; };
                EE1D7C9416E0ECCF00B000EB /* NSError+Description.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSError+Description.h"; sourceTree = "<group>"; };
                EE1D7C9516E0ECCF00B000EB /* NSError+Description.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSError+Description.m"; sourceTree = "<group>"; };
-               EEF86B7316E2241000674B87 /* NJActionPathElement.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NJActionPathElement.h; sourceTree = "<group>"; };
+               EEF86B7316E2241000674B87 /* NJInputPathElement.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NJInputPathElement.h; sourceTree = "<group>"; };
                EEF86B7416E298CD00674B87 /* NJEvents.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NJEvents.h; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
                080E96DDFE201D6D7F000001 /* Classes */ = {
                        isa = PBXGroup;
                        children = (
-                               D5617D290FAF579A00928B3A /* JSActionAnalog.h */,
-                               D5617D2A0FAF579A00928B3A /* JSActionAnalog.m */,
-                               D594BE840FAE6219007A85F2 /* Joystick.h */,
-                               D594BE850FAE6219007A85F2 /* Joystick.m */,
-                               D594BE880FAE64AD007A85F2 /* JSAction.h */,
-                               D594BE890FAE64AD007A85F2 /* JSAction.m */,
-                               D5617D240FAF579300928B3A /* JSActionHat.h */,
-                               D5617D250FAF579300928B3A /* JSActionHat.m */,
-                               D5617D180FAF568100928B3A /* JSActionButton.h */,
-                               D5617D190FAF568100928B3A /* JSActionButton.m */,
-                               D594BEF70FAE6FF2007A85F2 /* JoystickController.h */,
-                               D594BEF80FAE6FF2007A85F2 /* JoystickController.m */,
+                               D5617D290FAF579A00928B3A /* NJInputAnalog.h */,
+                               D5617D2A0FAF579A00928B3A /* NJInputAnalog.m */,
+                               D594BE840FAE6219007A85F2 /* NJDevice.h */,
+                               D594BE850FAE6219007A85F2 /* NJDevice.m */,
+                               D594BE880FAE64AD007A85F2 /* NJInput.h */,
+                               D594BE890FAE64AD007A85F2 /* NJInput.m */,
+                               D5617D240FAF579300928B3A /* NJInputHat.h */,
+                               D5617D250FAF579300928B3A /* NJInputHat.m */,
+                               D5617D180FAF568100928B3A /* NJInputButton.h */,
+                               D5617D190FAF568100928B3A /* NJInputButton.m */,
+                               D594BEF70FAE6FF2007A85F2 /* NJInputController.h */,
+                               D594BEF80FAE6FF2007A85F2 /* NJInputController.m */,
                                D594BF810FAE9661007A85F2 /* ApplicationController.h */,
                                D594BF820FAE9661007A85F2 /* ApplicationController.m */,
                                D5617A340FAEB74000928B3A /* ConfigsController.h */,
                                8BEFAD9B15C46BFF00823AEC /* TargetMouseScroll.m */,
                                8BEFAD9E15C476DC00823AEC /* TargetToggleMouseScope.h */,
                                8BEFAD9F15C476DC00823AEC /* TargetToggleMouseScope.m */,
-                               EEF86B7316E2241000674B87 /* NJActionPathElement.h */,
+                               EEF86B7316E2241000674B87 /* NJInputPathElement.h */,
                                EEF86B7416E298CD00674B87 /* NJEvents.h */,
                        );
                        name = Classes;
                        buildActionMask = 2147483647;
                        files = (
                                8D11072D0486CEB800E47090 /* main.m in Sources */,
-                               D594BE860FAE6219007A85F2 /* Joystick.m in Sources */,
-                               D594BE8A0FAE64AD007A85F2 /* JSAction.m in Sources */,
-                               D594BEF90FAE6FF2007A85F2 /* JoystickController.m in Sources */,
+                               D594BE860FAE6219007A85F2 /* NJDevice.m in Sources */,
+                               D594BE8A0FAE64AD007A85F2 /* NJInput.m in Sources */,
+                               D594BEF90FAE6FF2007A85F2 /* NJInputController.m in Sources */,
                                D594BF830FAE9661007A85F2 /* ApplicationController.m in Sources */,
                                D5617A360FAEB74000928B3A /* ConfigsController.m in Sources */,
                                D5617A390FAEBA1800928B3A /* Config.m in Sources */,
-                               D5617D1A0FAF568100928B3A /* JSActionButton.m in Sources */,
-                               D5617D260FAF579300928B3A /* JSActionHat.m in Sources */,
-                               D5617D2B0FAF579A00928B3A /* JSActionAnalog.m in Sources */,
+                               D5617D1A0FAF568100928B3A /* NJInputButton.m in Sources */,
+                               D5617D260FAF579300928B3A /* NJInputHat.m in Sources */,
+                               D5617D2B0FAF579A00928B3A /* NJInputAnalog.m in Sources */,
                                D5617FD60FAFD06000928B3A /* Target.m in Sources */,
                                D5617FD90FAFD1E600928B3A /* TargetKeyboard.m in Sources */,
                                D5617FE40FAFD7B000928B3A /* TargetController.m in Sources */,
diff --git a/JSAction.h b/JSAction.h
deleted file mode 100644 (file)
index dc00a8d..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-//
-//  JSAction.h
-//  Enjoy
-//
-//  Created by Sam McCall on 4/05/09.
-//  Copyright 2009 University of Otago. All rights reserved.
-//
-
-#import "NJActionPathElement.h"
-
-@interface JSAction : NSObject <NJActionPathElement>
-
-@property (nonatomic, assign) IOHIDElementCookie cookie;
-@property (nonatomic, copy) NSArray *children;
-@property (nonatomic, weak) id base;
-@property (nonatomic, copy) NSString *name;
-@property (nonatomic, assign) BOOL active;
-@property (nonatomic, readonly) float magnitude;
-@property (readonly) NSString *uid;
-
-- (id)initWithName:(NSString *)newName base:(id <NJActionPathElement>)newBase;
-
-- (void)notifyEvent:(IOHIDValueRef)value;
-- (id)findSubActionForValue:(IOHIDValueRef)value;
-
-@end
diff --git a/JSAction.m b/JSAction.m
deleted file mode 100644 (file)
index 1cdbeb2..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-//
-//  JSAction.m
-//  Enjoy
-//
-//  Created by Sam McCall on 4/05/09.
-//
-
-#import "JSAction.h"
-
-@implementation JSAction
-
-- (id)initWithName:(NSString *)newName base:(id <NJActionPathElement>)newBase {
-    if ((self = [super init])) {
-        self.name = newName;
-        self.base = newBase;
-    }
-    return self;
-}
-
-- (id)findSubActionForValue:(IOHIDValueRef)value {
-    return NULL;
-}
-
-- (NSString *)uid {
-    return [NSString stringWithFormat:@"%@~%@", [_base uid], _name];
-}
-
-- (void)notifyEvent:(IOHIDValueRef)value {
-    [self doesNotRecognizeSelector:_cmd];
-}
-
-- (float)magnitude {
-    return 0.f;
-}
-
-@end
diff --git a/JSActionAnalog.h b/JSActionAnalog.h
deleted file mode 100644 (file)
index deaf3a5..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-//
-//  JSActionAnalog.h
-//  Enjoy
-//
-//  Created by Sam McCall on 5/05/09.
-//  Copyright 2009 University of Otago. All rights reserved.
-//
-
-#import <Cocoa/Cocoa.h>
-
-#import "JSAction.h"
-
-@interface JSActionAnalog : JSAction
-
-- (id)initWithIndex:(int)index rawMin:(long)rawMin rawMax:(long)rawMax;
-
-@end
diff --git a/JSActionAnalog.m b/JSActionAnalog.m
deleted file mode 100644 (file)
index 9c98f21..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-//
-//  JSActionAnalog.m
-//  Enjoy
-//
-//  Created by Sam McCall on 5/05/09.
-//
-
-#define DEAD_ZONE 0.3
-
-#import "JSActionAnalog.h"
-
-static float normalize(long p, long min, long max) {
-    return 2 * (p - min) / (float)(max - min) - 1;
-}
-
-@implementation JSActionAnalog {
-    float magnitude;
-    long rawMin;
-    long rawMax;
-}
-
-- (id)initWithIndex:(int)index rawMin:(long)rawMin_ rawMax:(long)rawMax_ {
-    if ((self = [super init])) {
-        self.name = [[NSString alloc] initWithFormat: @"Axis %d", index];
-        self.children = @[[[JSAction alloc] initWithName:@"Low" base:self],
-                          [[JSAction alloc] initWithName:@"High" base:self]];
-        rawMax = rawMax_;
-        rawMin = rawMin_;
-    }
-    return self;
-}
-
-- (id)findSubActionForValue:(IOHIDValueRef)value {
-    float mag = normalize(IOHIDValueGetIntegerValue(value), rawMin, rawMax);
-    if (mag < -DEAD_ZONE)
-        return self.children[0];
-    else if (mag > DEAD_ZONE)
-        return self.children[1];
-    else
-        return nil;
-}
-
-- (void)notifyEvent:(IOHIDValueRef)value {
-    magnitude = normalize(IOHIDValueGetIntegerValue(value), rawMin, rawMax);
-    [self.children[0] setActive:magnitude < -DEAD_ZONE];
-    [self.children[1] setActive:magnitude > DEAD_ZONE];
-}
-
-- (float)magnitude {
-    return magnitude;
-}
-
-@end
diff --git a/JSActionButton.h b/JSActionButton.h
deleted file mode 100644 (file)
index 8a4bdc6..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-//
-//  JSActionButton.h
-//  Enjoy
-//
-//  Created by Sam McCall on 5/05/09.
-//  Copyright 2009 University of Otago. All rights reserved.
-//
-
-#import "JSAction.h"
-
-@interface JSActionButton : JSAction
-
-- (id)initWithName:(NSString *)name idx:(int)idx max:(long)max;
-
-@end
diff --git a/JSActionButton.m b/JSActionButton.m
deleted file mode 100644 (file)
index 7d2572a..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-//
-//  JSActionButton.m
-//  Enjoy
-//
-//  Created by Sam McCall on 5/05/09.
-//
-
-#import "JSActionButton.h"
-
-@implementation JSActionButton {
-    long _max;
-}
-
-- (id)initWithName:(NSString *)name idx:(int)idx max:(long)max {
-    if ((self = [super init])) {
-        _max = max;
-        if (name.length)
-            self.name = [NSString stringWithFormat:@"Button %d - %@", idx, name];
-        else
-            self.name = [NSString stringWithFormat:@"Button %d", idx];
-    }
-    return self;
-}
-
-- (id)findSubActionForValue:(IOHIDValueRef)val {
-    return (IOHIDValueGetIntegerValue(val) == _max) ? self : nil;
-}
-
-- (void)notifyEvent:(IOHIDValueRef)value {
-    self.active = IOHIDValueGetIntegerValue(value) == _max;
-}
-
-@end
diff --git a/JSActionHat.h b/JSActionHat.h
deleted file mode 100644 (file)
index 7c9ffce..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-//
-//  JSActionHat.h
-//  Enjoy
-//
-//  Created by Sam McCall on 5/05/09.
-//  Copyright 2009 University of Otago. All rights reserved.
-//
-
-#import "JSAction.h"
-
-@interface JSActionHat : JSAction
-
-- (id)initWithIndex:(int)index;
-
-@end
diff --git a/JSActionHat.m b/JSActionHat.m
deleted file mode 100644 (file)
index 2cac39c..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-//
-//  JSActionHat.m
-//  Enjoy
-//
-//  Created by Sam McCall on 5/05/09.
-//
-
-#import "JSActionHat.h"
-
-static BOOL active_eightway[36] = {
-    NO,  NO,  NO,  NO , // center
-    YES, NO,  NO,  NO , // N
-    YES, NO,  NO,  YES, // NE
-    NO,  NO,  NO,  YES, // E
-    NO,  YES, NO,  YES, // SE
-    NO,  YES, NO,  NO , // S
-    NO,  YES, YES, NO , // SW
-    NO,  NO,  YES, NO , // W
-    YES, NO,  YES, NO , // NW
-};
-
-static BOOL active_fourway[20] = {
-    NO,  NO,  NO,  NO , // center
-    YES, NO,  NO,  NO , // N
-    NO,  NO,  NO,  YES, // E
-    NO,  YES, NO,  NO , // S
-    NO,  NO,  YES, NO , // W
-};
-
-@implementation JSActionHat
-
-- (id)initWithIndex:(int)index {
-    if ((self = [super init])) {
-        self.children = @[[[JSAction alloc] initWithName:@"Up" base:self],
-                          [[JSAction alloc] initWithName:@"Down" base:self],
-                          [[JSAction alloc] initWithName:@"Left" base:self],
-                          [[JSAction alloc] initWithName:@"Right" base:self]];
-        self.name = [NSString stringWithFormat:@"Hat Switch %d", index];
-    }
-    return self;
-}
-
-- (id)findSubActionForValue:(IOHIDValueRef)value {
-    long parsed = IOHIDValueGetIntegerValue(value);
-    switch (IOHIDElementGetLogicalMax(IOHIDValueGetElement(value))) {
-        case 7: // 8-way switch, 0-7.
-            switch (parsed) {
-                case 0: return self.children[0];
-                case 4: return self.children[1];
-                case 6: return self.children[2];
-                case 2: return self.children[3];
-                default: return nil;
-            }
-        case 8: // 8-way switch, 1-8 (neutral 0).
-            switch (parsed) {
-                case 1: return self.children[0];
-                case 5: return self.children[1];
-                case 7: return self.children[2];
-                case 3: return self.children[3];
-                default: return nil;
-            }
-        case 3: // 4-way switch, 0-3.
-            switch (parsed) {
-                case 0: return self.children[0];
-                case 2: return self.children[1];
-                case 3: return self.children[2];
-                case 1: return self.children[3];
-                default: return nil;
-            }
-        case 4: // 4-way switch, 1-4 (neutral 0).
-            switch (parsed) {
-                case 1: return self.children[0];
-                case 3: return self.children[1];
-                case 4: return self.children[2];
-                case 2: return self.children[3];
-                default: return nil;
-            }
-        default:
-            return nil;
-    }
-}
-
-- (void)notifyEvent:(IOHIDValueRef)value {
-    long parsed = IOHIDValueGetIntegerValue(value);
-    long size = IOHIDElementGetLogicalMax(IOHIDValueGetElement(value));
-    // Skip first row in table if 0 is not neutral.
-    if (size & 1) {
-        parsed++;
-        size++;
-    }
-    BOOL *activechildren = (size == 8) ? active_eightway : active_fourway;
-    for (int i = 0; i < 4; i++)
-        [self.children[i] setActive:activechildren[parsed * 4 + i]];
-}
-
-@end
diff --git a/Joystick.h b/Joystick.h
deleted file mode 100644 (file)
index e5566f1..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-//
-//  Joystick.h
-//  Enjoy
-//
-//  Created by Sam McCall on 4/05/09.
-//  Copyright 2009 University of Otago. All rights reserved.
-//
-
-#import "NJActionPathElement.h"
-
-@class JSAction;
-
-@interface Joystick : NSObject <NJActionPathElement>
-
-@property (nonatomic, assign) int index;
-@property (nonatomic, copy) NSString *productName;
-@property (nonatomic, assign) IOHIDDeviceRef device;
-@property (nonatomic, copy) NSArray *children;
-@property (nonatomic, readonly) NSString *name;
-@property (readonly) NSString *uid;
-
-- (id)initWithDevice:(IOHIDDeviceRef)device;
-- (JSAction *)handlerForEvent:(IOHIDValueRef)value;
-- (JSAction *)actionForEvent:(IOHIDValueRef)value;
-
-@end
diff --git a/Joystick.m b/Joystick.m
deleted file mode 100644 (file)
index 4753caf..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-//
-//  Joystick.m
-//  Enjoy
-//
-//  Created by Sam McCall on 4/05/09.
-//
-
-#import "Joystick.h"
-
-#import "JSAction.h"
-#import "JSActionAnalog.h"
-#import "JSActionButton.h"
-#import "JSActionHat.h"
-
-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];
-    }
-
-    CFRelease(elements);
-    return children;
-}
-
-@implementation Joystick {
-    int vendorId;
-    int productId;
-}
-
-- (id)initWithDevice:(IOHIDDeviceRef)dev {
-    if ((self = [super init])) {
-        self.device = dev;
-        self.productName = (__bridge NSString *)IOHIDDeviceGetProperty(dev, CFSTR(kIOHIDProductKey));
-        vendorId = [(__bridge NSNumber *)IOHIDDeviceGetProperty(dev, CFSTR(kIOHIDVendorIDKey)) intValue];
-        productId = [(__bridge NSNumber *)IOHIDDeviceGetProperty(dev, CFSTR(kIOHIDProductIDKey)) intValue];
-        self.children = ActionsForElement(dev, self);
-    }
-    return self;
-}
-
-- (NSString *)name {
-    return [NSString stringWithFormat:@"%@ #%d", _productName, _index];
-}
-
-- (id)base {
-    return nil;
-}
-
-- (NSString *)uid {
-    return [NSString stringWithFormat: @"%d:%d:%d", vendorId, productId, _index];
-}
-
-- (JSAction *)findActionByCookie:(IOHIDElementCookie)cookie {
-    for (JSAction *child in _children)
-        if (child.cookie == cookie)
-            return child;
-    return nil;
-}
-
-- (JSAction *)handlerForEvent:(IOHIDValueRef)value {
-    JSAction *mainAction = [self actionForEvent:value];
-    return [mainAction findSubActionForValue:value];
-}
-
-- (JSAction *)actionForEvent:(IOHIDValueRef)value {
-    IOHIDElementRef elt = IOHIDValueGetElement(value);
-    IOHIDElementCookie cookie = IOHIDElementGetCookie(elt);
-    return [self findActionByCookie:cookie];
-}
-
-@end
diff --git a/JoystickController.h b/JoystickController.h
deleted file mode 100644 (file)
index d56f932..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-//
-//  JoystickController.h
-//  Enjoy
-//
-//  Created by Sam McCall on 4/05/09.
-//  Copyright 2009 University of Otago. All rights reserved.
-//
-
-@class Joystick;
-@class JSAction;
-@class ConfigsController;
-@class TargetController;
-
-@interface JoystickController : NSObject <NSOutlineViewDataSource, NSOutlineViewDelegate> {
-       IBOutlet NSOutlineView *outlineView;
-       IBOutlet TargetController *targetController;
-       IBOutlet ConfigsController *configsController;
-}
-
-- (void)setup;
-- (Joystick *)findJoystickByRef:(IOHIDDeviceRef)device;
-
-@property (nonatomic, readonly) JSAction *selectedAction;
-@property (nonatomic, assign) NSPoint mouseLoc;
-@property (nonatomic, assign) BOOL frontWindowOnly;
-@property (nonatomic, assign) BOOL translatingEvents;
-
-@end
diff --git a/JoystickController.m b/JoystickController.m
deleted file mode 100644 (file)
index 2efd68f..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-//
-//  JoystickController.m
-//  Enjoy
-//
-//  Created by Sam McCall on 4/05/09.
-//
-
-#import "JoystickController.h"
-
-#import "Config.h"
-#import "ConfigsController.h"
-#import "Joystick.h"
-#import "JSAction.h"
-#import "Target.h"
-#import "TargetController.h"
-#import "NJEvents.h"
-
-@implementation JoystickController {
-    IOHIDManagerRef hidManager;
-    NSTimer *continuousTimer;
-    NSMutableArray *runningTargets;
-    NSMutableArray *_joysticks;
-}
-
-- (id)init {
-    if ((self = [super init])) {
-        _joysticks = [[NSMutableArray alloc] initWithCapacity:16];
-        runningTargets = [[NSMutableArray alloc] initWithCapacity:32];
-    }
-    return self;
-}
-
-- (void)dealloc {
-    [continuousTimer invalidate];
-    IOHIDManagerClose(hidManager, kIOHIDOptionsTypeNone);
-    CFRelease(hidManager);
-}
-
-- (void)expandRecursive:(id <NJActionPathElement>)pathElement {
-    if (pathElement) {
-        [self expandRecursive:pathElement.base];
-        [outlineView expandItem:pathElement];
-    }
-}
-
-- (void)addRunningTarget:(Target *)target {
-    if (![runningTargets containsObject:target]) {
-        [runningTargets addObject:target];
-    }
-    if (!continuousTimer) {
-        continuousTimer = [NSTimer scheduledTimerWithTimeInterval:1.f/60.f
-                                                           target:self
-                                                         selector:@selector(updateContinuousActions:)
-                                                         userInfo:nil
-                                                          repeats:YES];
-        NSLog(@"Scheduled continuous target timer.");
-    }
-}
-
-- (void)runTargetForDevice:(IOHIDDeviceRef)device value:(IOHIDValueRef)value {
-    Joystick *js = [self findJoystickByRef:device];
-    JSAction *mainAction = [js actionForEvent:value];
-    [mainAction notifyEvent:value];
-    NSArray *children = mainAction.children ? mainAction.children : mainAction ? @[mainAction] : @[];
-    for (JSAction *subaction in children) {
-        Target *target = configsController.currentConfig[subaction];
-        target.magnitude = mainAction.magnitude;
-        target.running = subaction.active;
-        if (target.running && target.isContinuous)
-            [self addRunningTarget:target];
-    }
-}
-
-- (void)showTargetForDevice:(IOHIDDeviceRef)device value:(IOHIDValueRef)value {
-    Joystick *js = [self findJoystickByRef:device];
-    JSAction *handler = [js handlerForEvent:value];
-    if (!handler)
-        return;
-    
-    [self expandRecursive:handler];
-    [outlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:[outlineView rowForItem:handler]] byExtendingSelection: NO];
-    [targetController focusKey];
-}
-
-static void input_callback(void *ctx, IOReturn inResult, void *inSender, IOHIDValueRef value) {
-    JoystickController *controller = (__bridge JoystickController *)ctx;
-    IOHIDDeviceRef device = IOHIDQueueGetDevice(inSender);
-    
-    if (controller.translatingEvents) {
-        [controller runTargetForDevice:device value:value];
-    } else if ([NSApplication sharedApplication].mainWindow.isVisible) {
-        [controller showTargetForDevice:device value:value];
-    }
-}
-
-static int findAvailableIndex(NSArray *list, Joystick *js) {
-    for (int index = 1; ; index++) {
-        BOOL available = YES;
-        for (Joystick *used in list) {
-            if ([used.productName isEqualToString:js.productName] && used.index == index) {
-                available = NO;
-                break;
-            }
-        }
-        if (available)
-            return index;
-    }
-}
-
-- (void)addJoystickForDevice:(IOHIDDeviceRef)device {
-    IOHIDDeviceRegisterInputValueCallback(device, input_callback, (__bridge void*)self);
-    Joystick *js = [[Joystick alloc] initWithDevice:device];
-    js.index = findAvailableIndex(_joysticks, js);
-    [_joysticks addObject:js];
-    [outlineView reloadData];
-}
-
-static void add_callback(void *ctx, IOReturn inResult, void *inSender, IOHIDDeviceRef device) {
-    JoystickController *controller = (__bridge JoystickController *)ctx;
-    [controller addJoystickForDevice:device];
-}
-
-- (Joystick *)findJoystickByRef:(IOHIDDeviceRef)device {
-    for (Joystick *js in _joysticks)
-        if (js.device == device)
-            return js;
-    return nil;
-}
-
-static void remove_callback(void *ctx, IOReturn inResult, void *inSender, IOHIDDeviceRef device) {
-    JoystickController *controller = (__bridge JoystickController *)ctx;
-    [controller removeJoystickForDevice:device];
-}
-
-- (void)removeJoystickForDevice:(IOHIDDeviceRef)device {
-    Joystick *match = [self findJoystickByRef:device];
-    IOHIDDeviceRegisterInputValueCallback(device, NULL, NULL);
-    if (match) {
-        [_joysticks removeObject:match];
-        [outlineView reloadData];
-    }
-    
-}
-
-- (void)updateContinuousActions:(NSTimer *)timer {
-    self.mouseLoc = [NSEvent mouseLocation];
-    for (Target *target in [runningTargets copy]) {
-        if (![target update:self]) {
-            [runningTargets removeObject:target];
-        }
-    }
-    if (!runningTargets.count) {
-        [continuousTimer invalidate];
-        continuousTimer = nil;
-        NSLog(@"Unscheduled continuous target timer.");
-    }
-}
-
-#define NSSTR(e) ((NSString *)CFSTR(e))
-
-- (void)setup {
-    hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
-    NSArray *criteria = @[ @{ NSSTR(kIOHIDDeviceUsagePageKey) : @(kHIDPage_GenericDesktop),
-                              NSSTR(kIOHIDDeviceUsageKey) : @(kHIDUsage_GD_Joystick) },
-                           @{ NSSTR(kIOHIDDeviceUsagePageKey) : @(kHIDPage_GenericDesktop),
-                              NSSTR(kIOHIDDeviceUsageKey) : @(kHIDUsage_GD_GamePad) },
-                           @{ NSSTR(kIOHIDDeviceUsagePageKey) : @(kHIDPage_GenericDesktop),
-                              NSSTR(kIOHIDDeviceUsageKey) : @(kHIDUsage_GD_MultiAxisController) }
-                           ];
-    IOHIDManagerSetDeviceMatchingMultiple(hidManager, (__bridge CFArrayRef)criteria);
-    
-    IOHIDManagerScheduleWithRunLoop(hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
-    IOReturn ret = IOHIDManagerOpen(hidManager, kIOHIDOptionsTypeNone);
-    if (ret != kIOReturnSuccess) {
-        [[NSAlert alertWithMessageText:@"Input devices are unavailable"
-                         defaultButton:nil
-                       alternateButton:nil
-                           otherButton:nil
-             informativeTextWithFormat:@"Error 0x%08x occured trying to access your devices. "
-                                       @"Input may not be correctly detected or mapped.",
-                                       ret]
-         beginSheetModalForWindow:outlineView.window
-                    modalDelegate:nil
-                   didEndSelector:nil
-                      contextInfo:nil];
-    }
-    
-    IOHIDManagerRegisterDeviceMatchingCallback(hidManager, add_callback, (__bridge void *)self);
-    IOHIDManagerRegisterDeviceRemovalCallback(hidManager, remove_callback, (__bridge void *)self);
-}
-
-- (JSAction *)selectedAction {
-    id <NJActionPathElement> item = [outlineView itemAtRow:outlineView.selectedRow];
-    return (!item.children && item.base) ? item : nil;
-}
-
-- (NSInteger)outlineView:(NSOutlineView *)outlineView
-  numberOfChildrenOfItem:(id <NJActionPathElement>)item {
-    return item ? item.children.count : _joysticks.count;
-}
-
-- (BOOL)outlineView:(NSOutlineView *)outlineView
-   isItemExpandable:(id <NJActionPathElement>)item {
-    return item ? [[item children] count] > 0: YES;
-}
-
-- (id)outlineView:(NSOutlineView *)outlineView
-            child:(NSInteger)index
-           ofItem:(id <NJActionPathElement>)item {
-    return item ? item.children[index] : _joysticks[index];
-}
-
-- (id)outlineView:(NSOutlineView *)outlineView
-objectValueForTableColumn:(NSTableColumn *)tableColumn
-           byItem:(id <NJActionPathElement>)item  {
-    return item ? item.name : @"root";
-}
-
-- (void)outlineViewSelectionDidChange:(NSNotification *)notification {
-    
-    [targetController loadCurrent];
-}
-
-- (void)setTranslatingEvents:(BOOL)translatingEvents {
-    if (translatingEvents != _translatingEvents) {
-        _translatingEvents = translatingEvents;
-        NSString *name = translatingEvents
-            ? NJEventTranslationActivated
-            : NJEventTranslationDeactivated;
-        [NSNotificationCenter.defaultCenter postNotificationName:name
-                                                          object:self];
-    }
-}
-
-@end
diff --git a/NJActionPathElement.h b/NJActionPathElement.h
deleted file mode 100644 (file)
index f5eb0ca..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#import <Foundation/Foundation.h>
-
-@protocol NJActionPathElement <NSObject>
-
-- (NSArray *)children;
-- (id <NJActionPathElement>) base;
-- (NSString *)name;
-
-@end
diff --git a/NJDevice.h b/NJDevice.h
new file mode 100644 (file)
index 0000000..ec607ac
--- /dev/null
@@ -0,0 +1,26 @@
+//
+//  NJDevice.h
+//  Enjoy
+//
+//  Created by Sam McCall on 4/05/09.
+//  Copyright 2009 University of Otago. All rights reserved.
+//
+
+#import "NJInputPathElement.h"
+
+@class NJInput;
+
+@interface NJDevice : NSObject <NJInputPathElement>
+
+@property (nonatomic, assign) int index;
+@property (nonatomic, copy) NSString *productName;
+@property (nonatomic, assign) IOHIDDeviceRef device;
+@property (nonatomic, copy) NSArray *children;
+@property (nonatomic, readonly) NSString *name;
+@property (readonly) NSString *uid;
+
+- (id)initWithDevice:(IOHIDDeviceRef)device;
+- (NJInput *)handlerForEvent:(IOHIDValueRef)value;
+- (NJInput *)inputForEvent:(IOHIDValueRef)value;
+
+@end
diff --git a/NJDevice.m b/NJDevice.m
new file mode 100644 (file)
index 0000000..69775d8
--- /dev/null
@@ -0,0 +1,109 @@
+//
+//  NJDevice.m
+//  Enjoy
+//
+//  Created by Sam McCall on 4/05/09.
+//
+
+#import "NJDevice.h"
+
+#import "NJInput.h"
+#import "NJInputAnalog.h"
+#import "NJInputHat.h"
+#import "NJInputButton.h"
+
+static NSArray *InputsForElement(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);
+        
+        NJInput *input = nil;
+        
+        if (!(type == kIOHIDElementTypeInput_Misc
+              || type == kIOHIDElementTypeInput_Axis
+              || type == kIOHIDElementTypeInput_Button))
+             continue;
+        
+        if (max - min == 1 || usagePage == kHIDPage_Button || type == kIOHIDElementTypeInput_Button) {
+            input = [[NJInputButton alloc] initWithName:(__bridge NSString *)elName
+                                                    idx:++buttons
+                                                    max:max];
+        } else if (usage == kHIDUsage_GD_Hatswitch) {
+            input = [[NJInputHat alloc] initWithIndex:++hats];
+        } else if (usage >= kHIDUsage_GD_X && usage <= kHIDUsage_GD_Rz) {
+            input = [[NJInputAnalog alloc] initWithIndex:++axes
+                                                  rawMin:min
+                                                  rawMax:max];
+        } else {
+            continue;
+        }
+        
+        // TODO(jfw): Should be moved into better constructors.
+        input.base = base;
+        input.cookie = IOHIDElementGetCookie(element);
+        [children addObject:input];
+    }
+
+    CFRelease(elements);
+    return children;
+}
+
+@implementation NJDevice {
+    int vendorId;
+    int productId;
+}
+
+- (id)initWithDevice:(IOHIDDeviceRef)dev {
+    if ((self = [super init])) {
+        self.device = dev;
+        self.productName = (__bridge NSString *)IOHIDDeviceGetProperty(dev, CFSTR(kIOHIDProductKey));
+        vendorId = [(__bridge NSNumber *)IOHIDDeviceGetProperty(dev, CFSTR(kIOHIDVendorIDKey)) intValue];
+        productId = [(__bridge NSNumber *)IOHIDDeviceGetProperty(dev, CFSTR(kIOHIDProductIDKey)) intValue];
+        self.children = InputsForElement(dev, self);
+    }
+    return self;
+}
+
+- (NSString *)name {
+    return [NSString stringWithFormat:@"%@ #%d", _productName, _index];
+}
+
+- (id)base {
+    return nil;
+}
+
+- (NSString *)uid {
+    return [NSString stringWithFormat: @"%d:%d:%d", vendorId, productId, _index];
+}
+
+- (NJInput *)findInputByCookie:(IOHIDElementCookie)cookie {
+    for (NJInput *child in _children)
+        if (child.cookie == cookie)
+            return child;
+    return nil;
+}
+
+- (NJInput *)handlerForEvent:(IOHIDValueRef)value {
+    NJInput *mainInput = [self inputForEvent:value];
+    return [mainInput findSubInputForValue:value];
+}
+
+- (NJInput *)inputForEvent:(IOHIDValueRef)value {
+    IOHIDElementRef elt = IOHIDValueGetElement(value);
+    IOHIDElementCookie cookie = IOHIDElementGetCookie(elt);
+    return [self findInputByCookie:cookie];
+}
+
+@end
diff --git a/NJInput.h b/NJInput.h
new file mode 100644 (file)
index 0000000..e2c8404
--- /dev/null
+++ b/NJInput.h
@@ -0,0 +1,26 @@
+//
+//  NJInput.h
+//  Enjoy
+//
+//  Created by Sam McCall on 4/05/09.
+//  Copyright 2009 University of Otago. All rights reserved.
+//
+
+#import "NJInputPathElement.h"
+
+@interface NJInput : NSObject <NJInputPathElement>
+
+@property (nonatomic, assign) IOHIDElementCookie cookie;
+@property (nonatomic, copy) NSArray *children;
+@property (nonatomic, weak) id base;
+@property (nonatomic, copy) NSString *name;
+@property (nonatomic, assign) BOOL active;
+@property (nonatomic, readonly) float magnitude;
+@property (readonly) NSString *uid;
+
+- (id)initWithName:(NSString *)newName base:(id <NJInputPathElement>)newBase;
+
+- (void)notifyEvent:(IOHIDValueRef)value;
+- (id)findSubInputForValue:(IOHIDValueRef)value;
+
+@end
diff --git a/NJInput.m b/NJInput.m
new file mode 100644 (file)
index 0000000..cccda29
--- /dev/null
+++ b/NJInput.m
@@ -0,0 +1,36 @@
+//
+//  NJInput.m
+//  Enjoy
+//
+//  Created by Sam McCall on 4/05/09.
+//
+
+#import "NJInput.h"
+
+@implementation NJInput
+
+- (id)initWithName:(NSString *)newName base:(id <NJInputPathElement>)newBase {
+    if ((self = [super init])) {
+        self.name = newName;
+        self.base = newBase;
+    }
+    return self;
+}
+
+- (id)findSubInputForValue:(IOHIDValueRef)value {
+    return NULL;
+}
+
+- (NSString *)uid {
+    return [NSString stringWithFormat:@"%@~%@", [_base uid], _name];
+}
+
+- (void)notifyEvent:(IOHIDValueRef)value {
+    [self doesNotRecognizeSelector:_cmd];
+}
+
+- (float)magnitude {
+    return 0.f;
+}
+
+@end
diff --git a/NJInputAnalog.h b/NJInputAnalog.h
new file mode 100644 (file)
index 0000000..e79ed89
--- /dev/null
@@ -0,0 +1,17 @@
+//
+//  NJInputAnalog.h
+//  Enjoy
+//
+//  Created by Sam McCall on 5/05/09.
+//  Copyright 2009 University of Otago. All rights reserved.
+//
+
+#import <Cocoa/Cocoa.h>
+
+#import "NJInput.h"
+
+@interface NJInputAnalog : NJInput
+
+- (id)initWithIndex:(int)index rawMin:(long)rawMin rawMax:(long)rawMax;
+
+@end
diff --git a/NJInputAnalog.m b/NJInputAnalog.m
new file mode 100644 (file)
index 0000000..98ed018
--- /dev/null
@@ -0,0 +1,53 @@
+//
+//  NJInputAnalog.m
+//  Enjoy
+//
+//  Created by Sam McCall on 5/05/09.
+//
+
+#define DEAD_ZONE 0.3
+
+#import "NJInputAnalog.h"
+
+static float normalize(long p, long min, long max) {
+    return 2 * (p - min) / (float)(max - min) - 1;
+}
+
+@implementation NJInputAnalog {
+    float magnitude;
+    long rawMin;
+    long rawMax;
+}
+
+- (id)initWithIndex:(int)index rawMin:(long)rawMin_ rawMax:(long)rawMax_ {
+    if ((self = [super init])) {
+        self.name = [[NSString alloc] initWithFormat: @"Axis %d", index];
+        self.children = @[[[NJInput alloc] initWithName:@"Low" base:self],
+                          [[NJInput alloc] initWithName:@"High" base:self]];
+        rawMax = rawMax_;
+        rawMin = rawMin_;
+    }
+    return self;
+}
+
+- (id)findSubInputForValue:(IOHIDValueRef)value {
+    float mag = normalize(IOHIDValueGetIntegerValue(value), rawMin, rawMax);
+    if (mag < -DEAD_ZONE)
+        return self.children[0];
+    else if (mag > DEAD_ZONE)
+        return self.children[1];
+    else
+        return nil;
+}
+
+- (void)notifyEvent:(IOHIDValueRef)value {
+    magnitude = normalize(IOHIDValueGetIntegerValue(value), rawMin, rawMax);
+    [self.children[0] setActive:magnitude < -DEAD_ZONE];
+    [self.children[1] setActive:magnitude > DEAD_ZONE];
+}
+
+- (float)magnitude {
+    return magnitude;
+}
+
+@end
diff --git a/NJInputButton.h b/NJInputButton.h
new file mode 100644 (file)
index 0000000..31cba73
--- /dev/null
@@ -0,0 +1,15 @@
+//
+//  NJInputButton.h
+//  Enjoy
+//
+//  Created by Sam McCall on 5/05/09.
+//  Copyright 2009 University of Otago. All rights reserved.
+//
+
+#import "NJInput.h"
+
+@interface NJInputButton : NJInput
+
+- (id)initWithName:(NSString *)name idx:(int)idx max:(long)max;
+
+@end
diff --git a/NJInputButton.m b/NJInputButton.m
new file mode 100644 (file)
index 0000000..c500276
--- /dev/null
@@ -0,0 +1,33 @@
+//
+//  NJInputButton.m
+//  Enjoy
+//
+//  Created by Sam McCall on 5/05/09.
+//
+
+#import "NJInputButton.h"
+
+@implementation NJInputButton {
+    long _max;
+}
+
+- (id)initWithName:(NSString *)name idx:(int)idx max:(long)max {
+    if ((self = [super init])) {
+        _max = max;
+        if (name.length)
+            self.name = [NSString stringWithFormat:@"Button %d - %@", idx, name];
+        else
+            self.name = [NSString stringWithFormat:@"Button %d", idx];
+    }
+    return self;
+}
+
+- (id)findSubInputForValue:(IOHIDValueRef)val {
+    return (IOHIDValueGetIntegerValue(val) == _max) ? self : nil;
+}
+
+- (void)notifyEvent:(IOHIDValueRef)value {
+    self.active = IOHIDValueGetIntegerValue(value) == _max;
+}
+
+@end
diff --git a/NJInputController.h b/NJInputController.h
new file mode 100644 (file)
index 0000000..1c4853c
--- /dev/null
@@ -0,0 +1,28 @@
+//
+//  NJInputController.h
+//  Enjoy
+//
+//  Created by Sam McCall on 4/05/09.
+//  Copyright 2009 University of Otago. All rights reserved.
+//
+
+@class NJDevice;
+@class NJInput;
+@class ConfigsController;
+@class TargetController;
+
+@interface NJInputController : NSObject <NSOutlineViewDataSource, NSOutlineViewDelegate> {
+       IBOutlet NSOutlineView *outlineView;
+       IBOutlet TargetController *targetController;
+       IBOutlet ConfigsController *configsController;
+}
+
+- (void)setup;
+- (NJDevice *)findJoystickByRef:(IOHIDDeviceRef)device;
+
+@property (nonatomic, readonly) NJInput *selectedInput;
+@property (nonatomic, assign) NSPoint mouseLoc;
+@property (nonatomic, assign) BOOL frontWindowOnly;
+@property (nonatomic, assign) BOOL translatingEvents;
+
+@end
diff --git a/NJInputController.m b/NJInputController.m
new file mode 100644 (file)
index 0000000..9ee6d04
--- /dev/null
@@ -0,0 +1,235 @@
+//
+//  NJInputController.h
+//  Enjoy
+//
+//  Created by Sam McCall on 4/05/09.
+//
+
+#import "NJInputController.h"
+
+#import "Config.h"
+#import "ConfigsController.h"
+#import "NJDevice.h"
+#import "NJInput.h"
+#import "Target.h"
+#import "TargetController.h"
+#import "NJEvents.h"
+
+@implementation NJInputController {
+    IOHIDManagerRef hidManager;
+    NSTimer *continuousTimer;
+    NSMutableArray *runningTargets;
+    NSMutableArray *_joysticks;
+}
+
+- (id)init {
+    if ((self = [super init])) {
+        _joysticks = [[NSMutableArray alloc] initWithCapacity:16];
+        runningTargets = [[NSMutableArray alloc] initWithCapacity:32];
+    }
+    return self;
+}
+
+- (void)dealloc {
+    [continuousTimer invalidate];
+    IOHIDManagerClose(hidManager, kIOHIDOptionsTypeNone);
+    CFRelease(hidManager);
+}
+
+- (void)expandRecursive:(id <NJInputPathElement>)pathElement {
+    if (pathElement) {
+        [self expandRecursive:pathElement.base];
+        [outlineView expandItem:pathElement];
+    }
+}
+
+- (void)addRunningTarget:(Target *)target {
+    if (![runningTargets containsObject:target]) {
+        [runningTargets addObject:target];
+    }
+    if (!continuousTimer) {
+        continuousTimer = [NSTimer scheduledTimerWithTimeInterval:1.f/60.f
+                                                           target:self
+                                                         selector:@selector(updateContinuousInputs:)
+                                                         userInfo:nil
+                                                          repeats:YES];
+        NSLog(@"Scheduled continuous target timer.");
+    }
+}
+
+- (void)runTargetForDevice:(IOHIDDeviceRef)device value:(IOHIDValueRef)value {
+    NJDevice *js = [self findJoystickByRef:device];
+    NJInput *mainInput = [js inputForEvent:value];
+    [mainInput notifyEvent:value];
+    NSArray *children = mainInput.children ? mainInput.children : mainInput ? @[mainInput] : @[];
+    for (NJInput *subInput in children) {
+        Target *target = configsController.currentConfig[subInput];
+        target.magnitude = mainInput.magnitude;
+        target.running = subInput.active;
+        if (target.running && target.isContinuous)
+            [self addRunningTarget:target];
+    }
+}
+
+- (void)showTargetForDevice:(IOHIDDeviceRef)device value:(IOHIDValueRef)value {
+    NJDevice *js = [self findJoystickByRef:device];
+    NJInput *handler = [js handlerForEvent:value];
+    if (!handler)
+        return;
+    
+    [self expandRecursive:handler];
+    [outlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:[outlineView rowForItem:handler]] byExtendingSelection: NO];
+    [targetController focusKey];
+}
+
+static void input_callback(void *ctx, IOReturn inResult, void *inSender, IOHIDValueRef value) {
+    NJInputController *controller = (__bridge NJInputController *)ctx;
+    IOHIDDeviceRef device = IOHIDQueueGetDevice(inSender);
+    
+    if (controller.translatingEvents) {
+        [controller runTargetForDevice:device value:value];
+    } else if ([NSApplication sharedApplication].mainWindow.isVisible) {
+        [controller showTargetForDevice:device value:value];
+    }
+}
+
+static int findAvailableIndex(NSArray *list, NJDevice *js) {
+    for (int index = 1; ; index++) {
+        BOOL available = YES;
+        for (NJDevice *used in list) {
+            if ([used.productName isEqualToString:js.productName] && used.index == index) {
+                available = NO;
+                break;
+            }
+        }
+        if (available)
+            return index;
+    }
+}
+
+- (void)addJoystickForDevice:(IOHIDDeviceRef)device {
+    IOHIDDeviceRegisterInputValueCallback(device, input_callback, (__bridge void*)self);
+    NJDevice *js = [[NJDevice alloc] initWithDevice:device];
+    js.index = findAvailableIndex(_joysticks, js);
+    [_joysticks addObject:js];
+    [outlineView reloadData];
+}
+
+static void add_callback(void *ctx, IOReturn inResult, void *inSender, IOHIDDeviceRef device) {
+    NJInputController *controller = (__bridge NJInputController *)ctx;
+    [controller addJoystickForDevice:device];
+}
+
+- (NJDevice *)findJoystickByRef:(IOHIDDeviceRef)device {
+    for (NJDevice *js in _joysticks)
+        if (js.device == device)
+            return js;
+    return nil;
+}
+
+static void remove_callback(void *ctx, IOReturn inResult, void *inSender, IOHIDDeviceRef device) {
+    NJInputController *controller = (__bridge NJInputController *)ctx;
+    [controller removeJoystickForDevice:device];
+}
+
+- (void)removeJoystickForDevice:(IOHIDDeviceRef)device {
+    NJDevice *match = [self findJoystickByRef:device];
+    IOHIDDeviceRegisterInputValueCallback(device, NULL, NULL);
+    if (match) {
+        [_joysticks removeObject:match];
+        [outlineView reloadData];
+    }
+    
+}
+
+- (void)updateContinuousInputs:(NSTimer *)timer {
+    self.mouseLoc = [NSEvent mouseLocation];
+    for (Target *target in [runningTargets copy]) {
+        if (![target update:self]) {
+            [runningTargets removeObject:target];
+        }
+    }
+    if (!runningTargets.count) {
+        [continuousTimer invalidate];
+        continuousTimer = nil;
+        NSLog(@"Unscheduled continuous target timer.");
+    }
+}
+
+#define NSSTR(e) ((NSString *)CFSTR(e))
+
+- (void)setup {
+    hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
+    NSArray *criteria = @[ @{ NSSTR(kIOHIDDeviceUsagePageKey) : @(kHIDPage_GenericDesktop),
+                              NSSTR(kIOHIDDeviceUsageKey) : @(kHIDUsage_GD_Joystick) },
+                           @{ NSSTR(kIOHIDDeviceUsagePageKey) : @(kHIDPage_GenericDesktop),
+                              NSSTR(kIOHIDDeviceUsageKey) : @(kHIDUsage_GD_GamePad) },
+                           @{ NSSTR(kIOHIDDeviceUsagePageKey) : @(kHIDPage_GenericDesktop),
+                              NSSTR(kIOHIDDeviceUsageKey) : @(kHIDUsage_GD_MultiAxisController) }
+                           ];
+    IOHIDManagerSetDeviceMatchingMultiple(hidManager, (__bridge CFArrayRef)criteria);
+    
+    IOHIDManagerScheduleWithRunLoop(hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
+    IOReturn ret = IOHIDManagerOpen(hidManager, kIOHIDOptionsTypeNone);
+    if (ret != kIOReturnSuccess) {
+        [[NSAlert alertWithMessageText:@"Input devices are unavailable"
+                         defaultButton:nil
+                       alternateButton:nil
+                           otherButton:nil
+             informativeTextWithFormat:@"Error 0x%08x occured trying to access your devices. "
+                                       @"Input may not be correctly detected or mapped.",
+                                       ret]
+         beginSheetModalForWindow:outlineView.window
+                    modalDelegate:nil
+                   didEndSelector:nil
+                      contextInfo:nil];
+    }
+    
+    IOHIDManagerRegisterDeviceMatchingCallback(hidManager, add_callback, (__bridge void *)self);
+    IOHIDManagerRegisterDeviceRemovalCallback(hidManager, remove_callback, (__bridge void *)self);
+}
+
+- (NJInput *)selectedInput {
+    id <NJInputPathElement> item = [outlineView itemAtRow:outlineView.selectedRow];
+    return (!item.children && item.base) ? item : nil;
+}
+
+- (NSInteger)outlineView:(NSOutlineView *)outlineView
+  numberOfChildrenOfItem:(id <NJInputPathElement>)item {
+    return item ? item.children.count : _joysticks.count;
+}
+
+- (BOOL)outlineView:(NSOutlineView *)outlineView
+   isItemExpandable:(id <NJInputPathElement>)item {
+    return item ? [[item children] count] > 0: YES;
+}
+
+- (id)outlineView:(NSOutlineView *)outlineView
+            child:(NSInteger)index
+           ofItem:(id <NJInputPathElement>)item {
+    return item ? item.children[index] : _joysticks[index];
+}
+
+- (id)outlineView:(NSOutlineView *)outlineView
+objectValueForTableColumn:(NSTableColumn *)tableColumn
+           byItem:(id <NJInputPathElement>)item  {
+    return item ? item.name : @"root";
+}
+
+- (void)outlineViewSelectionDidChange:(NSNotification *)notification {
+    
+    [targetController loadCurrent];
+}
+
+- (void)setTranslatingEvents:(BOOL)translatingEvents {
+    if (translatingEvents != _translatingEvents) {
+        _translatingEvents = translatingEvents;
+        NSString *name = translatingEvents
+            ? NJEventTranslationActivated
+            : NJEventTranslationDeactivated;
+        [NSNotificationCenter.defaultCenter postNotificationName:name
+                                                          object:self];
+    }
+}
+
+@end
diff --git a/NJInputHat.h b/NJInputHat.h
new file mode 100644 (file)
index 0000000..5290d71
--- /dev/null
@@ -0,0 +1,15 @@
+//
+//  NJInputHat.h
+//  Enjoy
+//
+//  Created by Sam McCall on 5/05/09.
+//  Copyright 2009 University of Otago. All rights reserved.
+//
+
+#import "NJInput.h"
+
+@interface NJInputHat : NJInput
+
+- (id)initWithIndex:(int)index;
+
+@end
diff --git a/NJInputHat.m b/NJInputHat.m
new file mode 100644 (file)
index 0000000..b7d0161
--- /dev/null
@@ -0,0 +1,96 @@
+//
+//  NJInputHat.m
+//  Enjoy
+//
+//  Created by Sam McCall on 5/05/09.
+//
+
+#import "NJInputHat.h"
+
+static BOOL active_eightway[36] = {
+    NO,  NO,  NO,  NO , // center
+    YES, NO,  NO,  NO , // N
+    YES, NO,  NO,  YES, // NE
+    NO,  NO,  NO,  YES, // E
+    NO,  YES, NO,  YES, // SE
+    NO,  YES, NO,  NO , // S
+    NO,  YES, YES, NO , // SW
+    NO,  NO,  YES, NO , // W
+    YES, NO,  YES, NO , // NW
+};
+
+static BOOL active_fourway[20] = {
+    NO,  NO,  NO,  NO , // center
+    YES, NO,  NO,  NO , // N
+    NO,  NO,  NO,  YES, // E
+    NO,  YES, NO,  NO , // S
+    NO,  NO,  YES, NO , // W
+};
+
+@implementation NJInputHat
+
+- (id)initWithIndex:(int)index {
+    if ((self = [super init])) {
+        self.children = @[[[NJInput alloc] initWithName:@"Up" base:self],
+                          [[NJInput alloc] initWithName:@"Down" base:self],
+                          [[NJInput alloc] initWithName:@"Left" base:self],
+                          [[NJInput alloc] initWithName:@"Right" base:self]];
+        self.name = [NSString stringWithFormat:@"Hat Switch %d", index];
+    }
+    return self;
+}
+
+- (id)findSubInputForValue:(IOHIDValueRef)value {
+    long parsed = IOHIDValueGetIntegerValue(value);
+    switch (IOHIDElementGetLogicalMax(IOHIDValueGetElement(value))) {
+        case 7: // 8-way switch, 0-7.
+            switch (parsed) {
+                case 0: return self.children[0];
+                case 4: return self.children[1];
+                case 6: return self.children[2];
+                case 2: return self.children[3];
+                default: return nil;
+            }
+        case 8: // 8-way switch, 1-8 (neutral 0).
+            switch (parsed) {
+                case 1: return self.children[0];
+                case 5: return self.children[1];
+                case 7: return self.children[2];
+                case 3: return self.children[3];
+                default: return nil;
+            }
+        case 3: // 4-way switch, 0-3.
+            switch (parsed) {
+                case 0: return self.children[0];
+                case 2: return self.children[1];
+                case 3: return self.children[2];
+                case 1: return self.children[3];
+                default: return nil;
+            }
+        case 4: // 4-way switch, 1-4 (neutral 0).
+            switch (parsed) {
+                case 1: return self.children[0];
+                case 3: return self.children[1];
+                case 4: return self.children[2];
+                case 2: return self.children[3];
+                default: return nil;
+            }
+        default:
+            return nil;
+    }
+}
+
+- (void)notifyEvent:(IOHIDValueRef)value {
+    long parsed = IOHIDValueGetIntegerValue(value);
+    long size = IOHIDElementGetLogicalMax(IOHIDValueGetElement(value));
+    // Skip first row in table if 0 is not neutral.
+    if (size & 1) {
+        parsed++;
+        size++;
+    }
+    BOOL *activechildren = (size == 8) ? active_eightway : active_fourway;
+    for (int i = 0; i < 4; i++)
+        [self.children[i] setActive:activechildren[parsed * 4 + i]];
+}
+
+@end
diff --git a/NJInputPathElement.h b/NJInputPathElement.h
new file mode 100644 (file)
index 0000000..8fe5c65
--- /dev/null
@@ -0,0 +1,9 @@
+#import <Foundation/Foundation.h>
+
+@protocol NJInputPathElement <NSObject>
+
+- (NSArray *)children;
+- (id <NJInputPathElement>) base;
+- (NSString *)name;
+
+@end
index df3535b7176b8c35973f008b5e6d07a4e536268f..d2341621aaef39a2d0ad1210123ab97d961c8e7f 100644 (file)
--- a/Target.h
+++ b/Target.h
@@ -6,7 +6,7 @@
 //  Copyright 2009 University of Otago. All rights reserved.
 //
 
-@class JoystickController;
+@class NJInputController;
 
 @interface Target : NSObject
 
@@ -16,7 +16,7 @@
 
 - (void)trigger;
 - (void)untrigger;
-- (BOOL)update:(JoystickController *)jc;
+- (BOOL)update:(NJInputController *)jc;
 
 - (NSDictionary *)serialize;
 + (Target *)targetDeserialize:(NSDictionary *)serialization
index 493f94afbbaf6005958fbbe81a2547f20411b11f..42d004c6cd94e2ca67f26eff49896e71d4e0f2db 100644 (file)
--- a/Target.m
+++ b/Target.m
@@ -63,7 +63,7 @@
 - (void)untrigger {
 }
 
-- (BOOL)update:(JoystickController *)jc {
+- (BOOL)update:(NJInputController *)jc {
     return NO;
 }
 
index 9c03c081095cc05750afd7377deb9e8fe05a19ee..7f9e1590c88259cacac70a9603c997c2a8cb983e 100644 (file)
@@ -9,7 +9,7 @@
 #import "NJKeyInputField.h"
 
 @class ConfigsController;
-@class JoystickController;
+@class NJInputController;
 @class Target;
 @class TargetMouseMove;
 
@@ -22,7 +22,7 @@
     IBOutlet NSTextField *title;
     IBOutlet NSPopUpButton *configPopup;
     IBOutlet ConfigsController *configsController;
-    IBOutlet JoystickController *joystickController;
+    IBOutlet NJInputController *joystickController;
 }
 
 @property (assign) BOOL enabled;
index 48119c20e45e28dea3b812590fdeb1b2d37c5bdb..2e539179dbe3ac5149f9955984959017967dc941 100644 (file)
@@ -9,8 +9,8 @@
 
 #import "ConfigsController.h"
 #import "Config.h"
-#import "JSAction.h"
-#import "JoystickController.h"
+#import "NJInput.h"
+#import "NJInputController.h"
 #import "NJKeyInputField.h"
 #import "TargetConfig.h"
 #import "TargetController.h"
@@ -98,7 +98,7 @@
 }
 
 - (Target *)currentTarget {
-    return configsController.currentConfig[joystickController.selectedAction];
+    return configsController.currentConfig[joystickController.selectedInput];
 }
 
 - (Target *)makeTarget {
 
 - (void)commit {
     [self cleanUpInterface];
-    configsController.currentConfig[joystickController.selectedAction] = [self makeTarget];
+    configsController.currentConfig[joystickController.selectedInput] = [self makeTarget];
     [configsController save];
 }
 
     [scrollDirSelect setEnabled:enabled];
 }
 
-- (void)loadTarget:(Target *)target forAction:(JSAction *)action {
-    if (!action) {
+- (void)loadTarget:(Target *)target forInput:(NJInput *)input {
+    if (!input) {
         self.enabled = NO;
         title.stringValue = @"";
     } else {
         self.enabled = YES;
-        NSString *actFullName = action.name;
-        for (id <NJActionPathElement> cur = action.base; cur; cur = cur.base) {
-            actFullName = [[NSString alloc] initWithFormat:@"%@ > %@", cur.name, actFullName];
+        NSString *inpFullName = input.name;
+        for (id <NJInputPathElement> cur = input.base; cur; cur = cur.base) {
+            inpFullName = [[NSString alloc] initWithFormat:@"%@ > %@", cur.name, inpFullName];
         }
-        title.stringValue = [[NSString alloc] initWithFormat:@"%@ > %@", configsController.currentConfig.name, actFullName];
+        title.stringValue = [[NSString alloc] initWithFormat:@"%@ > %@", configsController.currentConfig.name, inpFullName];
     }
 
     if ([target isKindOfClass:TargetKeyboard.class]) {
 }
 
 - (void)loadCurrent {
-    [self loadTarget:self.currentTarget forAction:joystickController.selectedAction];
+    [self loadTarget:self.currentTarget forInput:joystickController.selectedInput];
 }
 
 - (void)focusKey {
index 3ec8f38ff440d68b300d3742ad186cd3327ca391..2806827588daaa6c330888722dbf0aacdac7d1ad 100644 (file)
@@ -7,7 +7,7 @@
 
 #import "TargetMouseMove.h"
 
-#import "JoystickController.h"
+#import "NJInputController.h"
 
 @implementation TargetMouseMove {
     int sign;
        return target;
 }
 
-- (BOOL)update:(JoystickController *)jc {
+- (BOOL)update:(NJInputController *)jc {
     if (fabsf(self.magnitude) < 0.01) {
         sign = 0;
         return NO; // dead zone
     }
 
-    // If the action crossed over High/Low, this target is done.
+    // If the input crossed over High/Low, this target is done.
     if (!sign)
         sign = self.magnitude < 0 ? -1 : 1;
     else if (sign / self.magnitude < 0) {
index 6595628002913477619858d8264a941826ab34ad..ac3b852511d37a92f7ae744518e7b62bfadee5e9 100644 (file)
     }
 }
 
-- (BOOL)update:(JoystickController *)jc {
+- (BOOL)update:(NJInputController *)jc {
     if (fabsf(self.magnitude) < 0.01f) {
         sign = 0;
         return NO; // dead zone
     }
     
-    // If the action crossed over High/Low, this target is done.
+    // If the input crossed over High/Low, this target is done.
     if (!sign)
         sign = self.magnitude < 0 ? -1 : 1;
     else if (sign / self.magnitude < 0) {
index 863a35fda7d1df27182ff543ff8fec040ddbe59a..499e9c9a3e768d51441deb99fa93d576fe2aadea 100644 (file)
@@ -8,7 +8,7 @@
 #import "TargetToggleMouseScope.h"
 
 #import "ApplicationController.h"
-#import "JoystickController.h"
+#import "NJInputController.h"
 
 @implementation TargetToggleMouseScope
 
@@ -29,7 +29,7 @@
     // FIXME: It's hacky to get at the controller this way, but it's
     // also hacky to pass it. Shouldn't need to do either.
     ApplicationController *ac = NSApplication.sharedApplication.delegate;
-    JoystickController *jc = ac.jsController;
+    NJInputController *jc = ac.jsController;
     jc.frontWindowOnly = !jc.frontWindowOnly;
 }