// Copyright 2009 University of Otago. All rights reserved.
//
-@class JoystickController;
+@class NJInputController;
@class TargetController;
@class ConfigsController;
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;
#import "Config.h"
#import "ConfigsController.h"
-#import "JoystickController.h"
+#import "NJInputController.h"
#import "TargetController.h"
#import "NJEvents.h"
//
@class Target;
-@class JSAction;
+@class NJInput;
@interface Config : NSObject
@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
#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];
}
}
<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>
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>"; };
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 */,
+++ /dev/null
-//
-// 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
+++ /dev/null
-//
-// 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
+++ /dev/null
-//
-// 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
+++ /dev/null
-//
-// 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
+++ /dev/null
-//
-// 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
+++ /dev/null
-//
-// 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
+++ /dev/null
-//
-// 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
+++ /dev/null
-//
-// 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
+++ /dev/null
-//
-// 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
+++ /dev/null
-//
-// 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
+++ /dev/null
-//
-// 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
+++ /dev/null
-//
-// 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
+++ /dev/null
-#import <Foundation/Foundation.h>
-
-@protocol NJActionPathElement <NSObject>
-
-- (NSArray *)children;
-- (id <NJActionPathElement>) base;
-- (NSString *)name;
-
-@end
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+//
+// 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
--- /dev/null
+#import <Foundation/Foundation.h>
+
+@protocol NJInputPathElement <NSObject>
+
+- (NSArray *)children;
+- (id <NJInputPathElement>) base;
+- (NSString *)name;
+
+@end
// Copyright 2009 University of Otago. All rights reserved.
//
-@class JoystickController;
+@class NJInputController;
@interface Target : NSObject
- (void)trigger;
- (void)untrigger;
-- (BOOL)update:(JoystickController *)jc;
+- (BOOL)update:(NJInputController *)jc;
- (NSDictionary *)serialize;
+ (Target *)targetDeserialize:(NSDictionary *)serialization
- (void)untrigger {
}
-- (BOOL)update:(JoystickController *)jc {
+- (BOOL)update:(NJInputController *)jc {
return NO;
}
#import "NJKeyInputField.h"
@class ConfigsController;
-@class JoystickController;
+@class NJInputController;
@class Target;
@class TargetMouseMove;
IBOutlet NSTextField *title;
IBOutlet NSPopUpButton *configPopup;
IBOutlet ConfigsController *configsController;
- IBOutlet JoystickController *joystickController;
+ IBOutlet NJInputController *joystickController;
}
@property (assign) BOOL enabled;
#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"
}
- (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 {
#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) {
}
}
-- (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) {
#import "TargetToggleMouseScope.h"
#import "ApplicationController.h"
-#import "JoystickController.h"
+#import "NJInputController.h"
@implementation TargetToggleMouseScope
// 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;
}