aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDominik Pich2013-03-17 13:33:20 +0100
committerDominik Pich2013-03-17 13:33:20 +0100
commitd4ffd217288cfc0d2798b3df67ab20bc867a7f7e (patch)
treeab40c6fb784fbe578713381ea5cf1159934a9c34
parent77d2a9f99a289d247c5a8561879489c8f8162055 (diff)
downloadDDHidLib-d4ffd217288cfc0d2798b3df67ab20bc867a7f7e.tar.bz2
DDHIDLib 1.1.1
-rw-r--r--DDHidLib-Info.plist22
-rw-r--r--DDHidLib.xcodeproj/project.pbxproj1118
-rw-r--r--LICENSE.html181
-rw-r--r--README.md10
-rw-r--r--browser/English.lproj/EventWatcher.nib/classes.nib13
-rw-r--r--browser/English.lproj/EventWatcher.nib/info.nib16
-rw-r--r--browser/English.lproj/EventWatcher.nib/keyedobjects.nibbin0 -> 9260 bytes
-rw-r--r--browser/English.lproj/InfoPlist.stringsbin0 -> 190 bytes
-rw-r--r--browser/English.lproj/MainMenu.nib/classes.nib19
-rw-r--r--browser/English.lproj/MainMenu.nib/info.nib22
-rw-r--r--browser/English.lproj/MainMenu.nib/keyedobjects.nibbin0 -> 31311 bytes
-rw-r--r--browser/HIDBrowser_Prefix.pch7
-rw-r--r--browser/HexFormatter.h34
-rw-r--r--browser/HexFormatter.m49
-rw-r--r--browser/HidBrowserController.h42
-rw-r--r--browser/HidBrowserController.m144
-rw-r--r--browser/Info.plist30
-rw-r--r--browser/WatcherWindowController.h57
-rw-r--r--browser/WatcherWindowController.m269
-rw-r--r--browser/main.m30
-rw-r--r--changelog.yml24
-rw-r--r--device_test/AppleMikeyPaneController.h62
-rw-r--r--device_test/AppleMikeyPaneController.m160
-rw-r--r--device_test/AppleRemote.tiffbin0 -> 90050 bytes
-rw-r--r--device_test/AppleRemotePaneController.h51
-rw-r--r--device_test/AppleRemotePaneController.m145
-rw-r--r--device_test/BoolFormatter.h35
-rw-r--r--device_test/BoolFormatter.m82
-rw-r--r--device_test/ButtonState.h38
-rw-r--r--device_test/ButtonState.m77
-rw-r--r--device_test/DeviceTestController.h35
-rw-r--r--device_test/DeviceTestController.m49
-rw-r--r--device_test/English.lproj/InfoPlist.stringsbin0 -> 190 bytes
-rw-r--r--device_test/English.lproj/MainMenu.nib/designable.nib5311
-rw-r--r--device_test/English.lproj/MainMenu.nib/keyedobjects.nibbin0 -> 46512 bytes
-rw-r--r--device_test/Info.plist26
-rw-r--r--device_test/JoystickPaneController.h72
-rw-r--r--device_test/JoystickPaneController.m174
-rw-r--r--device_test/KeyboardPaneController.h64
-rw-r--r--device_test/KeyboardPaneController.m179
-rw-r--r--device_test/MousePaneController.h68
-rw-r--r--device_test/MousePaneController.m211
-rw-r--r--device_test/RemoteFeedbackView.h42
-rw-r--r--device_test/RemoteFeedbackView.m162
-rw-r--r--device_test/main.m30
-rw-r--r--header.c23
-rw-r--r--lib/DDHidAppleMikey.h66
-rw-r--r--lib/DDHidAppleMikey.m164
-rw-r--r--lib/DDHidAppleRemote.h84
-rw-r--r--lib/DDHidAppleRemote.m236
-rw-r--r--lib/DDHidDevice.h131
-rw-r--r--lib/DDHidDevice.m585
-rw-r--r--lib/DDHidElement.h65
-rw-r--r--lib/DDHidElement.m185
-rw-r--r--lib/DDHidEvent.h45
-rw-r--r--lib/DDHidEvent.m81
-rw-r--r--lib/DDHidJoystick.h132
-rw-r--r--lib/DDHidJoystick.m654
-rw-r--r--lib/DDHidKeyboard.h68
-rw-r--r--lib/DDHidKeyboard.m173
-rw-r--r--lib/DDHidKeyboardBarcodeScanner.h74
-rw-r--r--lib/DDHidKeyboardBarcodeScanner.m222
-rw-r--r--lib/DDHidLib.h36
-rw-r--r--lib/DDHidMouse.h78
-rw-r--r--lib/DDHidMouse.m279
-rw-r--r--lib/DDHidQueue.h70
-rw-r--r--lib/DDHidQueue.m172
-rw-r--r--lib/DDHidStandardUsages.plist2327
-rw-r--r--lib/DDHidUsage.h52
-rw-r--r--lib/DDHidUsage.m84
-rw-r--r--lib/DDHidUsageTables.h40
-rw-r--r--lib/DDHidUsageTables.m85
-rw-r--r--lib/NSDictionary+DDHidExtras.h46
-rw-r--r--lib/NSDictionary+DDHidExtras.m81
-rw-r--r--usb_hid_usages.txt1086
-rwxr-xr-xusb_hid_usages2plist46
-rw-r--r--vendor/NSXReturnThrowError/NSXReturnThrowError.h103
-rw-r--r--vendor/NSXReturnThrowError/NSXReturnThrowError.m106
-rw-r--r--versions.xcconfig2
79 files changed, 16839 insertions, 2 deletions
diff --git a/DDHidLib-Info.plist b/DDHidLib-Info.plist
new file mode 100644
index 0000000..b77aa20
--- /dev/null
+++ b/DDHidLib-Info.plist
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>org.dribin.dave.DDHidLib</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>FMWK</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>${CURRENT_PROJECT_VERSION}</string>
+ <key>CFBundleShortVersionString</key>
+ <string>${CURRENT_MARKETING_VERSION}</string>
+</dict>
+</plist>
diff --git a/DDHidLib.xcodeproj/project.pbxproj b/DDHidLib.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..9f72bee
--- /dev/null
+++ b/DDHidLib.xcodeproj/project.pbxproj
@@ -0,0 +1,1118 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 42;
+ objects = {
+
+/* Begin PBXAggregateTarget section */
+ 551711110B8F41EB00C82155 /* All */ = {
+ isa = PBXAggregateTarget;
+ buildConfigurationList = 551711280B8F420E00C82155 /* Build configuration list for PBXAggregateTarget "All" */;
+ buildPhases = (
+ );
+ dependencies = (
+ 551711130B8F41F500C82155 /* PBXTargetDependency */,
+ 551711150B8F41F500C82155 /* PBXTargetDependency */,
+ 55D5935D0BAE3B1E00364849 /* PBXTargetDependency */,
+ );
+ name = All;
+ productName = All;
+ };
+/* End PBXAggregateTarget section */
+
+/* Begin PBXBuildFile section */
+ 55170D360B8EC2CE00C82155 /* DDHidAppleRemote.h in Headers */ = {isa = PBXBuildFile; fileRef = 55170D340B8EC2CE00C82155 /* DDHidAppleRemote.h */; };
+ 55170D370B8EC2CE00C82155 /* DDHidAppleRemote.m in Sources */ = {isa = PBXBuildFile; fileRef = 55170D350B8EC2CE00C82155 /* DDHidAppleRemote.m */; };
+ 55170E0D0B8ECCAC00C82155 /* AppleRemotePaneController.m in Sources */ = {isa = PBXBuildFile; fileRef = 55170E0C0B8ECCAC00C82155 /* AppleRemotePaneController.m */; };
+ 55170E650B8ECEF600C82155 /* RemoteFeedbackView.m in Sources */ = {isa = PBXBuildFile; fileRef = 55170E640B8ECEF600C82155 /* RemoteFeedbackView.m */; };
+ 55170E670B8ECF0000C82155 /* AppleRemote.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 55170E660B8ECF0000C82155 /* AppleRemote.tiff */; };
+ 55193E580B93F31D004C0C98 /* DDHidDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 55917B4F0B533C82005308AC /* DDHidDevice.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 55193E590B93F31D004C0C98 /* DDHidDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = 55917B500B533C82005308AC /* DDHidDevice.m */; };
+ 55193E5A0B93F31D004C0C98 /* DDHidElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 55917E6F0B5413E7005308AC /* DDHidElement.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 55193E5B0B93F31D004C0C98 /* DDHidElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 55917E700B5413E7005308AC /* DDHidElement.m */; };
+ 55193E5C0B93F31D004C0C98 /* DDHidUsage.h in Headers */ = {isa = PBXBuildFile; fileRef = 559CB82B0B595B2F00C8FD74 /* DDHidUsage.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 55193E5D0B93F31D004C0C98 /* DDHidUsage.m in Sources */ = {isa = PBXBuildFile; fileRef = 559CB82C0B595B2F00C8FD74 /* DDHidUsage.m */; };
+ 55193E5E0B93F31D004C0C98 /* DDHidQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 559180CA0B575698005308AC /* DDHidQueue.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 55193E5F0B93F31D004C0C98 /* DDHidQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 559180CB0B575698005308AC /* DDHidQueue.m */; };
+ 55193E600B93F31D004C0C98 /* DDHidEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 559181A40B576149005308AC /* DDHidEvent.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 55193E610B93F31D004C0C98 /* DDHidEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 559181A50B576149005308AC /* DDHidEvent.m */; };
+ 55193E620B93F31D004C0C98 /* DDHidUsageTables.h in Headers */ = {isa = PBXBuildFile; fileRef = 55917F610B545104005308AC /* DDHidUsageTables.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 55193E630B93F31D004C0C98 /* DDHidUsageTables.m in Sources */ = {isa = PBXBuildFile; fileRef = 55917F620B545104005308AC /* DDHidUsageTables.m */; };
+ 55193E640B93F31D004C0C98 /* NSDictionary+DDHidExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = 55917E720B541541005308AC /* NSDictionary+DDHidExtras.h */; settings = {ATTRIBUTES = (); }; };
+ 55193E650B93F31D004C0C98 /* NSDictionary+DDHidExtras.m in Sources */ = {isa = PBXBuildFile; fileRef = 55917E730B541541005308AC /* NSDictionary+DDHidExtras.m */; };
+ 55193E660B93F31D004C0C98 /* DDHidMouse.h in Headers */ = {isa = PBXBuildFile; fileRef = 559CBC2A0B5B34C300C8FD74 /* DDHidMouse.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 55193E670B93F31D004C0C98 /* DDHidMouse.m in Sources */ = {isa = PBXBuildFile; fileRef = 559CBC2B0B5B34C300C8FD74 /* DDHidMouse.m */; };
+ 55193E680B93F31D004C0C98 /* DDHidJoystick.h in Headers */ = {isa = PBXBuildFile; fileRef = 55FD66D30B5DDC3F00325FEF /* DDHidJoystick.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 55193E690B93F31D004C0C98 /* DDHidJoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = 55FD66D40B5DDC3F00325FEF /* DDHidJoystick.m */; };
+ 55193E6A0B93F31D004C0C98 /* DDHidAppleRemote.h in Headers */ = {isa = PBXBuildFile; fileRef = 55170D340B8EC2CE00C82155 /* DDHidAppleRemote.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 55193E6B0B93F31D004C0C98 /* DDHidAppleRemote.m in Sources */ = {isa = PBXBuildFile; fileRef = 55170D350B8EC2CE00C82155 /* DDHidAppleRemote.m */; };
+ 55193E6C0B93F31D004C0C98 /* DDHidLib.h in Headers */ = {isa = PBXBuildFile; fileRef = 55FD67CB0B5DE18600325FEF /* DDHidLib.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 55193E700B93F35A004C0C98 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 556E1E680B5359F9002F709C /* IOKit.framework */; };
+ 55193F110B93F36F004C0C98 /* NSXReturnThrowError.h in Headers */ = {isa = PBXBuildFile; fileRef = 55BE6DCB0B8033010085514D /* NSXReturnThrowError.h */; settings = {ATTRIBUTES = (); }; };
+ 55193F120B93F371004C0C98 /* NSXReturnThrowError.m in Sources */ = {isa = PBXBuildFile; fileRef = 55BE6DCC0B8033010085514D /* NSXReturnThrowError.m */; };
+ 556E1E690B5359F9002F709C /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 556E1E680B5359F9002F709C /* IOKit.framework */; };
+ 55917B640B53408C005308AC /* HidBrowserController.m in Sources */ = {isa = PBXBuildFile; fileRef = 55917B630B53408C005308AC /* HidBrowserController.m */; };
+ 55917E1C0B53E454005308AC /* HexFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 55917E1B0B53E454005308AC /* HexFormatter.m */; };
+ 559CBAEB0B5B31AB00C8FD74 /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 559CBAE90B5B31AB00C8FD74 /* Info.plist */; };
+ 559CBAEC0B5B31AB00C8FD74 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 559CBAEA0B5B31AB00C8FD74 /* main.m */; };
+ 559CBB930B5B31E300C8FD74 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+ 559CBB940B5B31EA00C8FD74 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 556E1E680B5359F9002F709C /* IOKit.framework */; };
+ 559CBBD10B5B337600C8FD74 /* DDHidDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 55917B4F0B533C82005308AC /* DDHidDevice.h */; };
+ 559CBBD20B5B337600C8FD74 /* DDHidDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = 55917B500B533C82005308AC /* DDHidDevice.m */; };
+ 559CBBD30B5B337600C8FD74 /* DDHidElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 55917E6F0B5413E7005308AC /* DDHidElement.h */; };
+ 559CBBD40B5B337600C8FD74 /* DDHidElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 55917E700B5413E7005308AC /* DDHidElement.m */; };
+ 559CBBD50B5B337600C8FD74 /* DDHidUsage.h in Headers */ = {isa = PBXBuildFile; fileRef = 559CB82B0B595B2F00C8FD74 /* DDHidUsage.h */; };
+ 559CBBD60B5B337600C8FD74 /* DDHidUsage.m in Sources */ = {isa = PBXBuildFile; fileRef = 559CB82C0B595B2F00C8FD74 /* DDHidUsage.m */; };
+ 559CBBD70B5B337600C8FD74 /* DDHidQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 559180CA0B575698005308AC /* DDHidQueue.h */; };
+ 559CBBD80B5B337600C8FD74 /* DDHidQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 559180CB0B575698005308AC /* DDHidQueue.m */; };
+ 559CBBD90B5B337600C8FD74 /* DDHidEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 559181A40B576149005308AC /* DDHidEvent.h */; };
+ 559CBBDA0B5B337600C8FD74 /* DDHidEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 559181A50B576149005308AC /* DDHidEvent.m */; };
+ 559CBBDB0B5B337600C8FD74 /* DDHidUsageTables.h in Headers */ = {isa = PBXBuildFile; fileRef = 55917F610B545104005308AC /* DDHidUsageTables.h */; };
+ 559CBBDC0B5B337600C8FD74 /* DDHidUsageTables.m in Sources */ = {isa = PBXBuildFile; fileRef = 55917F620B545104005308AC /* DDHidUsageTables.m */; };
+ 559CBBDD0B5B337600C8FD74 /* NSDictionary+DDHidExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = 55917E720B541541005308AC /* NSDictionary+DDHidExtras.h */; };
+ 559CBC260B5B349100C8FD74 /* NSDictionary+DDHidExtras.m in Sources */ = {isa = PBXBuildFile; fileRef = 55917E730B541541005308AC /* NSDictionary+DDHidExtras.m */; };
+ 559CBC2C0B5B34C300C8FD74 /* DDHidMouse.h in Headers */ = {isa = PBXBuildFile; fileRef = 559CBC2A0B5B34C300C8FD74 /* DDHidMouse.h */; };
+ 559CBC2D0B5B34C300C8FD74 /* DDHidMouse.m in Sources */ = {isa = PBXBuildFile; fileRef = 559CBC2B0B5B34C300C8FD74 /* DDHidMouse.m */; };
+ 559CBCA90B5B3BCE00C8FD74 /* MousePaneController.m in Sources */ = {isa = PBXBuildFile; fileRef = 559CBCA80B5B3BCE00C8FD74 /* MousePaneController.m */; };
+ 55A000520B5D7C06001B47E5 /* BoolFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 55A000500B5D7C06001B47E5 /* BoolFormatter.m */; };
+ 55BE6DCD0B8033010085514D /* NSXReturnThrowError.h in Headers */ = {isa = PBXBuildFile; fileRef = 55BE6DCB0B8033010085514D /* NSXReturnThrowError.h */; };
+ 55BE6DCE0B8033010085514D /* NSXReturnThrowError.m in Sources */ = {isa = PBXBuildFile; fileRef = 55BE6DCC0B8033010085514D /* NSXReturnThrowError.m */; };
+ 55CA60E50BA0F2530012CF7B /* DDHidKeyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = 55CA60E30BA0F2530012CF7B /* DDHidKeyboard.h */; };
+ 55CA60E60BA0F2530012CF7B /* DDHidKeyboard.m in Sources */ = {isa = PBXBuildFile; fileRef = 55CA60E40BA0F2530012CF7B /* DDHidKeyboard.m */; };
+ 55CA668B0BA38AEF0012CF7B /* KeyboardPaneController.m in Sources */ = {isa = PBXBuildFile; fileRef = 55CA668A0BA38AEF0012CF7B /* KeyboardPaneController.m */; };
+ 55D5927D0BAE306E00364849 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 55D5927B0BAE306E00364849 /* InfoPlist.strings */; };
+ 55D592940BAE30B600364849 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 55D592920BAE30B600364849 /* MainMenu.nib */; };
+ 55D593290BAE3ABD00364849 /* DDHidLib.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55193E500B93F2EE004C0C98 /* DDHidLib.framework */; };
+ 55D593390BAE3ADF00364849 /* DDHidLib.framework in Copy Files to Frameworks */ = {isa = PBXBuildFile; fileRef = 55193E500B93F2EE004C0C98 /* DDHidLib.framework */; };
+ 55D593660BAE3B5D00364849 /* DDHidLib.framework in Copy Files to Frameworks */ = {isa = PBXBuildFile; fileRef = 55193E500B93F2EE004C0C98 /* DDHidLib.framework */; };
+ 55D593750BAE3B7500364849 /* DDHidLib.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55193E500B93F2EE004C0C98 /* DDHidLib.framework */; };
+ 55D5937B0BAE3B8800364849 /* DDHidKeyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = 55CA60E30BA0F2530012CF7B /* DDHidKeyboard.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 55D5937C0BAE3B8800364849 /* DDHidKeyboard.m in Sources */ = {isa = PBXBuildFile; fileRef = 55CA60E40BA0F2530012CF7B /* DDHidKeyboard.m */; };
+ 55D593870BAE3BB700364849 /* DDHidStandardUsages.plist in Resources */ = {isa = PBXBuildFile; fileRef = 55917F760B54535B005308AC /* DDHidStandardUsages.plist */; };
+ 55DCD9C60B55D35D000648E5 /* WatcherWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 55DCD9C50B55D35D000648E5 /* WatcherWindowController.m */; };
+ 55DCD9E00B55D503000648E5 /* EventWatcher.nib in Resources */ = {isa = PBXBuildFile; fileRef = 55DCD9DE0B55D503000648E5 /* EventWatcher.nib */; };
+ 55FC9FDB0BB76D8D0095FC7B /* DDHidKeyboardBarcodeScanner.h in Headers */ = {isa = PBXBuildFile; fileRef = 55FC9FD90BB76D8D0095FC7B /* DDHidKeyboardBarcodeScanner.h */; };
+ 55FC9FDC0BB76D8D0095FC7B /* DDHidKeyboardBarcodeScanner.m in Sources */ = {isa = PBXBuildFile; fileRef = 55FC9FDA0BB76D8D0095FC7B /* DDHidKeyboardBarcodeScanner.m */; };
+ 55FC9FDD0BB76D8D0095FC7B /* DDHidKeyboardBarcodeScanner.h in Headers */ = {isa = PBXBuildFile; fileRef = 55FC9FD90BB76D8D0095FC7B /* DDHidKeyboardBarcodeScanner.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 55FC9FDE0BB76D8D0095FC7B /* DDHidKeyboardBarcodeScanner.m in Sources */ = {isa = PBXBuildFile; fileRef = 55FC9FDA0BB76D8D0095FC7B /* DDHidKeyboardBarcodeScanner.m */; };
+ 55FD65CB0B5DD57200325FEF /* DeviceTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = 55FD65CA0B5DD57200325FEF /* DeviceTestController.m */; };
+ 55FD66D50B5DDC3F00325FEF /* DDHidJoystick.h in Headers */ = {isa = PBXBuildFile; fileRef = 55FD66D30B5DDC3F00325FEF /* DDHidJoystick.h */; };
+ 55FD66D60B5DDC3F00325FEF /* DDHidJoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = 55FD66D40B5DDC3F00325FEF /* DDHidJoystick.m */; };
+ 55FD66FD0B5DDD2100325FEF /* JoystickPaneController.m in Sources */ = {isa = PBXBuildFile; fileRef = 55FD66FC0B5DDD2100325FEF /* JoystickPaneController.m */; };
+ 55FD67750B5DDF8200325FEF /* ButtonState.m in Sources */ = {isa = PBXBuildFile; fileRef = 55FD67740B5DDF8200325FEF /* ButtonState.m */; };
+ 55FD67CC0B5DE18600325FEF /* DDHidLib.h in Headers */ = {isa = PBXBuildFile; fileRef = 55FD67CB0B5DE18600325FEF /* DDHidLib.h */; };
+ 8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 29B97318FDCFA39411CA2CEA /* MainMenu.nib */; };
+ 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
+ 8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
+ 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+ B366F1B016F5DE9800C0BA49 /* DDHidAppleMikey.h in Headers */ = {isa = PBXBuildFile; fileRef = B366F1AE16F5DE9800C0BA49 /* DDHidAppleMikey.h */; };
+ B366F1B116F5DE9800C0BA49 /* DDHidAppleMikey.m in Sources */ = {isa = PBXBuildFile; fileRef = B366F1AF16F5DE9800C0BA49 /* DDHidAppleMikey.m */; };
+ B366F1B316F5E20800C0BA49 /* DDHidAppleMikey.m in Sources */ = {isa = PBXBuildFile; fileRef = B366F1AF16F5DE9800C0BA49 /* DDHidAppleMikey.m */; };
+ B366F1B616F5E64B00C0BA49 /* AppleMikeyPaneController.m in Sources */ = {isa = PBXBuildFile; fileRef = B366F1B516F5E64B00C0BA49 /* AppleMikeyPaneController.m */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 551711120B8F41F500C82155 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 8D1107260486CEB800E47090;
+ remoteInfo = HIDBrowser;
+ };
+ 551711140B8F41F500C82155 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 559CBAE00B5B313000C8FD74;
+ remoteInfo = HIDDeviceTest;
+ };
+ 55D593250BAE3AA800364849 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 55193E4F0B93F2EE004C0C98;
+ remoteInfo = DDHidLib;
+ };
+ 55D5935C0BAE3B1E00364849 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 55193E4F0B93F2EE004C0C98;
+ remoteInfo = DDHidLib;
+ };
+ 55D593600BAE3B3300364849 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 55193E4F0B93F2EE004C0C98;
+ remoteInfo = DDHidLib;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 55D593350BAE3AC800364849 /* Copy Files to Frameworks */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ 55D593390BAE3ADF00364849 /* DDHidLib.framework in Copy Files to Frameworks */,
+ );
+ name = "Copy Files to Frameworks";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 55D593620BAE3B4B00364849 /* Copy Files to Frameworks */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ 55D593660BAE3B5D00364849 /* DDHidLib.framework in Copy Files to Frameworks */,
+ );
+ name = "Copy Files to Frameworks";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+ 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
+ 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
+ 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+ 29B97319FDCFA39411CA2CEA /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/MainMenu.nib; sourceTree = "<group>"; };
+ 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
+ 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
+ 32CA4F630368D1EE00C91783 /* HIDBrowser_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HIDBrowser_Prefix.pch; sourceTree = "<group>"; };
+ 55170D340B8EC2CE00C82155 /* DDHidAppleRemote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDHidAppleRemote.h; sourceTree = "<group>"; };
+ 55170D350B8EC2CE00C82155 /* DDHidAppleRemote.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDHidAppleRemote.m; sourceTree = "<group>"; };
+ 55170E0B0B8ECCAC00C82155 /* AppleRemotePaneController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppleRemotePaneController.h; sourceTree = "<group>"; };
+ 55170E0C0B8ECCAC00C82155 /* AppleRemotePaneController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppleRemotePaneController.m; sourceTree = "<group>"; };
+ 55170E630B8ECEF600C82155 /* RemoteFeedbackView.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = RemoteFeedbackView.h; sourceTree = "<group>"; };
+ 55170E640B8ECEF600C82155 /* RemoteFeedbackView.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = RemoteFeedbackView.m; sourceTree = "<group>"; };
+ 55170E660B8ECF0000C82155 /* AppleRemote.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = AppleRemote.tiff; sourceTree = "<group>"; };
+ 55193E500B93F2EE004C0C98 /* DDHidLib.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DDHidLib.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 55193E510B93F2EE004C0C98 /* DDHidLib-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "DDHidLib-Info.plist"; sourceTree = "<group>"; };
+ 556E1E680B5359F9002F709C /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = "<absolute>"; };
+ 55917B4F0B533C82005308AC /* DDHidDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDHidDevice.h; sourceTree = "<group>"; };
+ 55917B500B533C82005308AC /* DDHidDevice.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDHidDevice.m; sourceTree = "<group>"; };
+ 55917B620B53408C005308AC /* HidBrowserController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HidBrowserController.h; sourceTree = "<group>"; };
+ 55917B630B53408C005308AC /* HidBrowserController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HidBrowserController.m; sourceTree = "<group>"; };
+ 55917E1A0B53E454005308AC /* HexFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HexFormatter.h; sourceTree = "<group>"; };
+ 55917E1B0B53E454005308AC /* HexFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HexFormatter.m; sourceTree = "<group>"; };
+ 55917E6F0B5413E7005308AC /* DDHidElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDHidElement.h; sourceTree = "<group>"; };
+ 55917E700B5413E7005308AC /* DDHidElement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDHidElement.m; sourceTree = "<group>"; };
+ 55917E720B541541005308AC /* NSDictionary+DDHidExtras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+DDHidExtras.h"; sourceTree = "<group>"; };
+ 55917E730B541541005308AC /* NSDictionary+DDHidExtras.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+DDHidExtras.m"; sourceTree = "<group>"; };
+ 55917F610B545104005308AC /* DDHidUsageTables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDHidUsageTables.h; sourceTree = "<group>"; };
+ 55917F620B545104005308AC /* DDHidUsageTables.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDHidUsageTables.m; sourceTree = "<group>"; };
+ 55917F760B54535B005308AC /* DDHidStandardUsages.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; name = DDHidStandardUsages.plist; path = ../lib/DDHidStandardUsages.plist; sourceTree = "<group>"; };
+ 559180CA0B575698005308AC /* DDHidQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDHidQueue.h; sourceTree = "<group>"; };
+ 559180CB0B575698005308AC /* DDHidQueue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDHidQueue.m; sourceTree = "<group>"; };
+ 559181A40B576149005308AC /* DDHidEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDHidEvent.h; sourceTree = "<group>"; };
+ 559181A50B576149005308AC /* DDHidEvent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDHidEvent.m; sourceTree = "<group>"; };
+ 559CB82B0B595B2F00C8FD74 /* DDHidUsage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDHidUsage.h; sourceTree = "<group>"; };
+ 559CB82C0B595B2F00C8FD74 /* DDHidUsage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDHidUsage.m; sourceTree = "<group>"; };
+ 559CBAE10B5B313000C8FD74 /* HIDDeviceTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HIDDeviceTest.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 559CBAE90B5B31AB00C8FD74 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ 559CBAEA0B5B31AB00C8FD74 /* main.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+ 559CBBCC0B5B336600C8FD74 /* libddhid.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libddhid.a; sourceTree = BUILT_PRODUCTS_DIR; };
+ 559CBC2A0B5B34C300C8FD74 /* DDHidMouse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDHidMouse.h; sourceTree = "<group>"; };
+ 559CBC2B0B5B34C300C8FD74 /* DDHidMouse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDHidMouse.m; sourceTree = "<group>"; };
+ 559CBCA70B5B3BCE00C8FD74 /* MousePaneController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MousePaneController.h; sourceTree = "<group>"; };
+ 559CBCA80B5B3BCE00C8FD74 /* MousePaneController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MousePaneController.m; sourceTree = "<group>"; };
+ 55A000500B5D7C06001B47E5 /* BoolFormatter.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = BoolFormatter.m; sourceTree = "<group>"; };
+ 55A000510B5D7C06001B47E5 /* BoolFormatter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = BoolFormatter.h; sourceTree = "<group>"; };
+ 55BE6DCB0B8033010085514D /* NSXReturnThrowError.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = NSXReturnThrowError.h; sourceTree = "<group>"; };
+ 55BE6DCC0B8033010085514D /* NSXReturnThrowError.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = NSXReturnThrowError.m; sourceTree = "<group>"; };
+ 55CA60E30BA0F2530012CF7B /* DDHidKeyboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDHidKeyboard.h; sourceTree = "<group>"; };
+ 55CA60E40BA0F2530012CF7B /* DDHidKeyboard.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDHidKeyboard.m; sourceTree = "<group>"; };
+ 55CA66890BA38AEF0012CF7B /* KeyboardPaneController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeyboardPaneController.h; sourceTree = "<group>"; };
+ 55CA668A0BA38AEF0012CF7B /* KeyboardPaneController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KeyboardPaneController.m; sourceTree = "<group>"; };
+ 55D592200BAE2E4500364849 /* versions.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = versions.xcconfig; sourceTree = "<group>"; };
+ 55D5927C0BAE306E00364849 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+ 55D592930BAE30B600364849 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/MainMenu.nib; sourceTree = "<group>"; };
+ 55DCD9C40B55D35D000648E5 /* WatcherWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WatcherWindowController.h; sourceTree = "<group>"; };
+ 55DCD9C50B55D35D000648E5 /* WatcherWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WatcherWindowController.m; sourceTree = "<group>"; };
+ 55DCD9DF0B55D503000648E5 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/EventWatcher.nib; sourceTree = "<group>"; };
+ 55FC9FD90BB76D8D0095FC7B /* DDHidKeyboardBarcodeScanner.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DDHidKeyboardBarcodeScanner.h; sourceTree = "<group>"; };
+ 55FC9FDA0BB76D8D0095FC7B /* DDHidKeyboardBarcodeScanner.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = DDHidKeyboardBarcodeScanner.m; sourceTree = "<group>"; };
+ 55FD65C90B5DD57200325FEF /* DeviceTestController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeviceTestController.h; sourceTree = "<group>"; };
+ 55FD65CA0B5DD57200325FEF /* DeviceTestController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DeviceTestController.m; sourceTree = "<group>"; };
+ 55FD66D30B5DDC3F00325FEF /* DDHidJoystick.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDHidJoystick.h; sourceTree = "<group>"; };
+ 55FD66D40B5DDC3F00325FEF /* DDHidJoystick.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDHidJoystick.m; sourceTree = "<group>"; };
+ 55FD66FB0B5DDD2100325FEF /* JoystickPaneController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JoystickPaneController.h; sourceTree = "<group>"; };
+ 55FD66FC0B5DDD2100325FEF /* JoystickPaneController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JoystickPaneController.m; sourceTree = "<group>"; };
+ 55FD67730B5DDF8200325FEF /* ButtonState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ButtonState.h; sourceTree = "<group>"; };
+ 55FD67740B5DDF8200325FEF /* ButtonState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ButtonState.m; sourceTree = "<group>"; };
+ 55FD67CB0B5DE18600325FEF /* DDHidLib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDHidLib.h; sourceTree = "<group>"; };
+ 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
+ 8D1107320486CEB800E47090 /* HIDBrowser.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HIDBrowser.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ B366F1AE16F5DE9800C0BA49 /* DDHidAppleMikey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DDHidAppleMikey.h; sourceTree = "<group>"; };
+ B366F1AF16F5DE9800C0BA49 /* DDHidAppleMikey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DDHidAppleMikey.m; sourceTree = "<group>"; };
+ B366F1B416F5E64A00C0BA49 /* AppleMikeyPaneController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppleMikeyPaneController.h; sourceTree = "<group>"; };
+ B366F1B516F5E64B00C0BA49 /* AppleMikeyPaneController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppleMikeyPaneController.m; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 55193E4E0B93F2EE004C0C98 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 55193E700B93F35A004C0C98 /* IOKit.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 559CBADF0B5B313000C8FD74 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 55D593750BAE3B7500364849 /* DDHidLib.framework in Frameworks */,
+ 559CBB940B5B31EA00C8FD74 /* IOKit.framework in Frameworks */,
+ 559CBB930B5B31E300C8FD74 /* Cocoa.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 559CBBCA0B5B336600C8FD74 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 8D11072E0486CEB800E47090 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 55D593290BAE3ABD00364849 /* DDHidLib.framework in Frameworks */,
+ 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */,
+ 556E1E690B5359F9002F709C /* IOKit.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 080E96DDFE201D6D7F000001 /* Classes */ = {
+ isa = PBXGroup;
+ children = (
+ 55917B620B53408C005308AC /* HidBrowserController.h */,
+ 55917B630B53408C005308AC /* HidBrowserController.m */,
+ 55917E1A0B53E454005308AC /* HexFormatter.h */,
+ 55917E1B0B53E454005308AC /* HexFormatter.m */,
+ 55DCD9C40B55D35D000648E5 /* WatcherWindowController.h */,
+ 55DCD9C50B55D35D000648E5 /* WatcherWindowController.m */,
+ );
+ name = Classes;
+ sourceTree = "<group>";
+ };
+ 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 556E1E680B5359F9002F709C /* IOKit.framework */,
+ 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */,
+ );
+ name = "Linked Frameworks";
+ sourceTree = "<group>";
+ };
+ 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 29B97324FDCFA39411CA2CEA /* AppKit.framework */,
+ 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */,
+ 29B97325FDCFA39411CA2CEA /* Foundation.framework */,
+ );
+ name = "Other Frameworks";
+ sourceTree = "<group>";
+ };
+ 19C28FACFE9D520D11CA2CBB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 8D1107320486CEB800E47090 /* HIDBrowser.app */,
+ 559CBAE10B5B313000C8FD74 /* HIDDeviceTest.app */,
+ 559CBBCC0B5B336600C8FD74 /* libddhid.a */,
+ 55193E500B93F2EE004C0C98 /* DDHidLib.framework */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 29B97314FDCFA39411CA2CEA /* HIDBrowser */ = {
+ isa = PBXGroup;
+ children = (
+ 559CBAE80B5B31AB00C8FD74 /* device_test */,
+ 559CBAA10B5B2F4400C8FD74 /* browser */,
+ 55917B4C0B533C53005308AC /* lib */,
+ 55BE6DC90B8033010085514D /* vendor */,
+ 29B97323FDCFA39411CA2CEA /* Frameworks */,
+ 19C28FACFE9D520D11CA2CBB /* Products */,
+ 55193E510B93F2EE004C0C98 /* DDHidLib-Info.plist */,
+ 55D592200BAE2E4500364849 /* versions.xcconfig */,
+ );
+ name = HIDBrowser;
+ sourceTree = "<group>";
+ };
+ 29B97315FDCFA39411CA2CEA /* Other Sources */ = {
+ isa = PBXGroup;
+ children = (
+ 32CA4F630368D1EE00C91783 /* HIDBrowser_Prefix.pch */,
+ 29B97316FDCFA39411CA2CEA /* main.m */,
+ );
+ name = "Other Sources";
+ sourceTree = "<group>";
+ };
+ 29B97317FDCFA39411CA2CEA /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 55917F760B54535B005308AC /* DDHidStandardUsages.plist */,
+ 8D1107310486CEB800E47090 /* Info.plist */,
+ 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */,
+ 29B97318FDCFA39411CA2CEA /* MainMenu.nib */,
+ 55DCD9DE0B55D503000648E5 /* EventWatcher.nib */,
+ );
+ name = Resources;
+ sourceTree = "<group>";
+ };
+ 29B97323FDCFA39411CA2CEA /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */,
+ 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+ 5547B9D20B8E1C02003C6ADE /* Classes */ = {
+ isa = PBXGroup;
+ children = (
+ B366F1B416F5E64A00C0BA49 /* AppleMikeyPaneController.h */,
+ B366F1B516F5E64B00C0BA49 /* AppleMikeyPaneController.m */,
+ 55FD65C90B5DD57200325FEF /* DeviceTestController.h */,
+ 55FD65CA0B5DD57200325FEF /* DeviceTestController.m */,
+ 559CBCA70B5B3BCE00C8FD74 /* MousePaneController.h */,
+ 559CBCA80B5B3BCE00C8FD74 /* MousePaneController.m */,
+ 55FD66FB0B5DDD2100325FEF /* JoystickPaneController.h */,
+ 55FD66FC0B5DDD2100325FEF /* JoystickPaneController.m */,
+ 55CA66890BA38AEF0012CF7B /* KeyboardPaneController.h */,
+ 55CA668A0BA38AEF0012CF7B /* KeyboardPaneController.m */,
+ 55170E0B0B8ECCAC00C82155 /* AppleRemotePaneController.h */,
+ 55170E0C0B8ECCAC00C82155 /* AppleRemotePaneController.m */,
+ 55170E630B8ECEF600C82155 /* RemoteFeedbackView.h */,
+ 55170E640B8ECEF600C82155 /* RemoteFeedbackView.m */,
+ 55A000510B5D7C06001B47E5 /* BoolFormatter.h */,
+ 55A000500B5D7C06001B47E5 /* BoolFormatter.m */,
+ 55FD67730B5DDF8200325FEF /* ButtonState.h */,
+ 55FD67740B5DDF8200325FEF /* ButtonState.m */,
+ );
+ name = Classes;
+ sourceTree = "<group>";
+ };
+ 55917B4C0B533C53005308AC /* lib */ = {
+ isa = PBXGroup;
+ children = (
+ B366F1AE16F5DE9800C0BA49 /* DDHidAppleMikey.h */,
+ B366F1AF16F5DE9800C0BA49 /* DDHidAppleMikey.m */,
+ 55917B4F0B533C82005308AC /* DDHidDevice.h */,
+ 55917B500B533C82005308AC /* DDHidDevice.m */,
+ 55917E6F0B5413E7005308AC /* DDHidElement.h */,
+ 55917E700B5413E7005308AC /* DDHidElement.m */,
+ 559CB82B0B595B2F00C8FD74 /* DDHidUsage.h */,
+ 559CB82C0B595B2F00C8FD74 /* DDHidUsage.m */,
+ 559180CA0B575698005308AC /* DDHidQueue.h */,
+ 559180CB0B575698005308AC /* DDHidQueue.m */,
+ 559181A40B576149005308AC /* DDHidEvent.h */,
+ 559181A50B576149005308AC /* DDHidEvent.m */,
+ 55917F610B545104005308AC /* DDHidUsageTables.h */,
+ 55917F620B545104005308AC /* DDHidUsageTables.m */,
+ 55917E720B541541005308AC /* NSDictionary+DDHidExtras.h */,
+ 55917E730B541541005308AC /* NSDictionary+DDHidExtras.m */,
+ 559CBC2A0B5B34C300C8FD74 /* DDHidMouse.h */,
+ 55FD66D30B5DDC3F00325FEF /* DDHidJoystick.h */,
+ 559CBC2B0B5B34C300C8FD74 /* DDHidMouse.m */,
+ 55FD66D40B5DDC3F00325FEF /* DDHidJoystick.m */,
+ 55CA60E30BA0F2530012CF7B /* DDHidKeyboard.h */,
+ 55CA60E40BA0F2530012CF7B /* DDHidKeyboard.m */,
+ 55170D340B8EC2CE00C82155 /* DDHidAppleRemote.h */,
+ 55170D350B8EC2CE00C82155 /* DDHidAppleRemote.m */,
+ 55FC9FD90BB76D8D0095FC7B /* DDHidKeyboardBarcodeScanner.h */,
+ 55FC9FDA0BB76D8D0095FC7B /* DDHidKeyboardBarcodeScanner.m */,
+ 55FD67CB0B5DE18600325FEF /* DDHidLib.h */,
+ );
+ path = lib;
+ sourceTree = "<group>";
+ };
+ 559CBAA10B5B2F4400C8FD74 /* browser */ = {
+ isa = PBXGroup;
+ children = (
+ 080E96DDFE201D6D7F000001 /* Classes */,
+ 29B97315FDCFA39411CA2CEA /* Other Sources */,
+ 29B97317FDCFA39411CA2CEA /* Resources */,
+ );
+ path = browser;
+ sourceTree = "<group>";
+ };
+ 559CBAE80B5B31AB00C8FD74 /* device_test */ = {
+ isa = PBXGroup;
+ children = (
+ 5547B9D20B8E1C02003C6ADE /* Classes */,
+ 559CBAEA0B5B31AB00C8FD74 /* main.m */,
+ 559CBBA20B5B31FD00C8FD74 /* Resources */,
+ );
+ path = device_test;
+ sourceTree = "<group>";
+ };
+ 559CBBA20B5B31FD00C8FD74 /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 55170E660B8ECF0000C82155 /* AppleRemote.tiff */,
+ 559CBAE90B5B31AB00C8FD74 /* Info.plist */,
+ 55D5927B0BAE306E00364849 /* InfoPlist.strings */,
+ 55D592920BAE30B600364849 /* MainMenu.nib */,
+ );
+ name = Resources;
+ sourceTree = "<group>";
+ };
+ 55BE6DC90B8033010085514D /* vendor */ = {
+ isa = PBXGroup;
+ children = (
+ 55BE6DCA0B8033010085514D /* NSXReturnThrowError */,
+ );
+ path = vendor;
+ sourceTree = "<group>";
+ };
+ 55BE6DCA0B8033010085514D /* NSXReturnThrowError */ = {
+ isa = PBXGroup;
+ children = (
+ 55BE6DCB0B8033010085514D /* NSXReturnThrowError.h */,
+ 55BE6DCC0B8033010085514D /* NSXReturnThrowError.m */,
+ );
+ path = NSXReturnThrowError;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+ 55193E4B0B93F2EE004C0C98 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 55193E580B93F31D004C0C98 /* DDHidDevice.h in Headers */,
+ 55193E5A0B93F31D004C0C98 /* DDHidElement.h in Headers */,
+ 55193E5C0B93F31D004C0C98 /* DDHidUsage.h in Headers */,
+ 55193E5E0B93F31D004C0C98 /* DDHidQueue.h in Headers */,
+ 55193E600B93F31D004C0C98 /* DDHidEvent.h in Headers */,
+ 55193E620B93F31D004C0C98 /* DDHidUsageTables.h in Headers */,
+ 55193E640B93F31D004C0C98 /* NSDictionary+DDHidExtras.h in Headers */,
+ 55193E660B93F31D004C0C98 /* DDHidMouse.h in Headers */,
+ 55193E680B93F31D004C0C98 /* DDHidJoystick.h in Headers */,
+ 55193E6A0B93F31D004C0C98 /* DDHidAppleRemote.h in Headers */,
+ 55193E6C0B93F31D004C0C98 /* DDHidLib.h in Headers */,
+ 55193F110B93F36F004C0C98 /* NSXReturnThrowError.h in Headers */,
+ 55D5937B0BAE3B8800364849 /* DDHidKeyboard.h in Headers */,
+ 55FC9FDD0BB76D8D0095FC7B /* DDHidKeyboardBarcodeScanner.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 559CBBC80B5B336600C8FD74 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 559CBBD10B5B337600C8FD74 /* DDHidDevice.h in Headers */,
+ 559CBBD30B5B337600C8FD74 /* DDHidElement.h in Headers */,
+ 559CBBD50B5B337600C8FD74 /* DDHidUsage.h in Headers */,
+ 559CBBD70B5B337600C8FD74 /* DDHidQueue.h in Headers */,
+ 559CBBD90B5B337600C8FD74 /* DDHidEvent.h in Headers */,
+ 559CBBDB0B5B337600C8FD74 /* DDHidUsageTables.h in Headers */,
+ 559CBBDD0B5B337600C8FD74 /* NSDictionary+DDHidExtras.h in Headers */,
+ 559CBC2C0B5B34C300C8FD74 /* DDHidMouse.h in Headers */,
+ 55FD66D50B5DDC3F00325FEF /* DDHidJoystick.h in Headers */,
+ 55FD67CC0B5DE18600325FEF /* DDHidLib.h in Headers */,
+ 55BE6DCD0B8033010085514D /* NSXReturnThrowError.h in Headers */,
+ 55170D360B8EC2CE00C82155 /* DDHidAppleRemote.h in Headers */,
+ 55CA60E50BA0F2530012CF7B /* DDHidKeyboard.h in Headers */,
+ 55FC9FDB0BB76D8D0095FC7B /* DDHidKeyboardBarcodeScanner.h in Headers */,
+ B366F1B016F5DE9800C0BA49 /* DDHidAppleMikey.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+ 55193E4F0B93F2EE004C0C98 /* DDHidLib */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 55193E530B93F2EF004C0C98 /* Build configuration list for PBXNativeTarget "DDHidLib" */;
+ buildPhases = (
+ 55193E4B0B93F2EE004C0C98 /* Headers */,
+ 55193E4C0B93F2EE004C0C98 /* Resources */,
+ 55193E4D0B93F2EE004C0C98 /* Sources */,
+ 55193E4E0B93F2EE004C0C98 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = DDHidLib;
+ productName = DDHidLib;
+ productReference = 55193E500B93F2EE004C0C98 /* DDHidLib.framework */;
+ productType = "com.apple.product-type.framework";
+ };
+ 559CBAE00B5B313000C8FD74 /* HIDDeviceTest */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 559CBAE40B5B313000C8FD74 /* Build configuration list for PBXNativeTarget "HIDDeviceTest" */;
+ buildPhases = (
+ 559CBADD0B5B313000C8FD74 /* Resources */,
+ 559CBADE0B5B313000C8FD74 /* Sources */,
+ 559CBADF0B5B313000C8FD74 /* Frameworks */,
+ 55D593620BAE3B4B00364849 /* Copy Files to Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 55D593610BAE3B3300364849 /* PBXTargetDependency */,
+ );
+ name = HIDDeviceTest;
+ productName = HIDDeviceTest;
+ productReference = 559CBAE10B5B313000C8FD74 /* HIDDeviceTest.app */;
+ productType = "com.apple.product-type.application";
+ };
+ 559CBBCB0B5B336600C8FD74 /* ddhid */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 559CBBE60B5B338B00C8FD74 /* Build configuration list for PBXNativeTarget "ddhid" */;
+ buildPhases = (
+ 559CBBC80B5B336600C8FD74 /* Headers */,
+ 559CBBC90B5B336600C8FD74 /* Sources */,
+ 559CBBCA0B5B336600C8FD74 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = ddhid;
+ productName = ddhid;
+ productReference = 559CBBCC0B5B336600C8FD74 /* libddhid.a */;
+ productType = "com.apple.product-type.library.static";
+ };
+ 8D1107260486CEB800E47090 /* HIDBrowser */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "HIDBrowser" */;
+ buildPhases = (
+ 8D1107290486CEB800E47090 /* Resources */,
+ 8D11072C0486CEB800E47090 /* Sources */,
+ 8D11072E0486CEB800E47090 /* Frameworks */,
+ 55D593350BAE3AC800364849 /* Copy Files to Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 55D593260BAE3AA800364849 /* PBXTargetDependency */,
+ );
+ name = HIDBrowser;
+ productInstallPath = "$(HOME)/Applications";
+ productName = HIDBrowser;
+ productReference = 8D1107320486CEB800E47090 /* HIDBrowser.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 29B97313FDCFA39411CA2CEA /* Project object */ = {
+ isa = PBXProject;
+ buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "DDHidLib" */;
+ compatibilityVersion = "Xcode 2.4";
+ developmentRegion = English;
+ hasScannedForEncodings = 1;
+ knownRegions = (
+ en,
+ );
+ mainGroup = 29B97314FDCFA39411CA2CEA /* HIDBrowser */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 551711110B8F41EB00C82155 /* All */,
+ 8D1107260486CEB800E47090 /* HIDBrowser */,
+ 559CBAE00B5B313000C8FD74 /* HIDDeviceTest */,
+ 559CBBCB0B5B336600C8FD74 /* ddhid */,
+ 55193E4F0B93F2EE004C0C98 /* DDHidLib */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 55193E4C0B93F2EE004C0C98 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 55D593870BAE3BB700364849 /* DDHidStandardUsages.plist in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 559CBADD0B5B313000C8FD74 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 559CBAEB0B5B31AB00C8FD74 /* Info.plist in Resources */,
+ 55170E670B8ECF0000C82155 /* AppleRemote.tiff in Resources */,
+ 55D5927D0BAE306E00364849 /* InfoPlist.strings in Resources */,
+ 55D592940BAE30B600364849 /* MainMenu.nib in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 8D1107290486CEB800E47090 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */,
+ 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */,
+ 55DCD9E00B55D503000648E5 /* EventWatcher.nib in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 55193E4D0B93F2EE004C0C98 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 55193E590B93F31D004C0C98 /* DDHidDevice.m in Sources */,
+ 55193E5B0B93F31D004C0C98 /* DDHidElement.m in Sources */,
+ 55193E5D0B93F31D004C0C98 /* DDHidUsage.m in Sources */,
+ 55193E5F0B93F31D004C0C98 /* DDHidQueue.m in Sources */,
+ 55193E610B93F31D004C0C98 /* DDHidEvent.m in Sources */,
+ 55193E630B93F31D004C0C98 /* DDHidUsageTables.m in Sources */,
+ 55193E650B93F31D004C0C98 /* NSDictionary+DDHidExtras.m in Sources */,
+ 55193E670B93F31D004C0C98 /* DDHidMouse.m in Sources */,
+ 55193E690B93F31D004C0C98 /* DDHidJoystick.m in Sources */,
+ 55193E6B0B93F31D004C0C98 /* DDHidAppleRemote.m in Sources */,
+ 55193F120B93F371004C0C98 /* NSXReturnThrowError.m in Sources */,
+ 55D5937C0BAE3B8800364849 /* DDHidKeyboard.m in Sources */,
+ 55FC9FDE0BB76D8D0095FC7B /* DDHidKeyboardBarcodeScanner.m in Sources */,
+ B366F1B316F5E20800C0BA49 /* DDHidAppleMikey.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 559CBADE0B5B313000C8FD74 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 559CBAEC0B5B31AB00C8FD74 /* main.m in Sources */,
+ 559CBCA90B5B3BCE00C8FD74 /* MousePaneController.m in Sources */,
+ 55A000520B5D7C06001B47E5 /* BoolFormatter.m in Sources */,
+ 55FD65CB0B5DD57200325FEF /* DeviceTestController.m in Sources */,
+ 55FD66FD0B5DDD2100325FEF /* JoystickPaneController.m in Sources */,
+ 55FD67750B5DDF8200325FEF /* ButtonState.m in Sources */,
+ 55170E0D0B8ECCAC00C82155 /* AppleRemotePaneController.m in Sources */,
+ 55170E650B8ECEF600C82155 /* RemoteFeedbackView.m in Sources */,
+ 55CA668B0BA38AEF0012CF7B /* KeyboardPaneController.m in Sources */,
+ B366F1B616F5E64B00C0BA49 /* AppleMikeyPaneController.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 559CBBC90B5B336600C8FD74 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 559CBBD20B5B337600C8FD74 /* DDHidDevice.m in Sources */,
+ 559CBBD40B5B337600C8FD74 /* DDHidElement.m in Sources */,
+ 559CBBD60B5B337600C8FD74 /* DDHidUsage.m in Sources */,
+ 559CBBD80B5B337600C8FD74 /* DDHidQueue.m in Sources */,
+ 559CBBDA0B5B337600C8FD74 /* DDHidEvent.m in Sources */,
+ 559CBBDC0B5B337600C8FD74 /* DDHidUsageTables.m in Sources */,
+ 559CBC260B5B349100C8FD74 /* NSDictionary+DDHidExtras.m in Sources */,
+ 559CBC2D0B5B34C300C8FD74 /* DDHidMouse.m in Sources */,
+ 55FD66D60B5DDC3F00325FEF /* DDHidJoystick.m in Sources */,
+ 55BE6DCE0B8033010085514D /* NSXReturnThrowError.m in Sources */,
+ 55170D370B8EC2CE00C82155 /* DDHidAppleRemote.m in Sources */,
+ 55CA60E60BA0F2530012CF7B /* DDHidKeyboard.m in Sources */,
+ 55FC9FDC0BB76D8D0095FC7B /* DDHidKeyboardBarcodeScanner.m in Sources */,
+ B366F1B116F5DE9800C0BA49 /* DDHidAppleMikey.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 8D11072C0486CEB800E47090 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8D11072D0486CEB800E47090 /* main.m in Sources */,
+ 55917B640B53408C005308AC /* HidBrowserController.m in Sources */,
+ 55917E1C0B53E454005308AC /* HexFormatter.m in Sources */,
+ 55DCD9C60B55D35D000648E5 /* WatcherWindowController.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ 551711130B8F41F500C82155 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 8D1107260486CEB800E47090 /* HIDBrowser */;
+ targetProxy = 551711120B8F41F500C82155 /* PBXContainerItemProxy */;
+ };
+ 551711150B8F41F500C82155 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 559CBAE00B5B313000C8FD74 /* HIDDeviceTest */;
+ targetProxy = 551711140B8F41F500C82155 /* PBXContainerItemProxy */;
+ };
+ 55D593260BAE3AA800364849 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 55193E4F0B93F2EE004C0C98 /* DDHidLib */;
+ targetProxy = 55D593250BAE3AA800364849 /* PBXContainerItemProxy */;
+ };
+ 55D5935D0BAE3B1E00364849 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 55193E4F0B93F2EE004C0C98 /* DDHidLib */;
+ targetProxy = 55D5935C0BAE3B1E00364849 /* PBXContainerItemProxy */;
+ };
+ 55D593610BAE3B3300364849 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 55193E4F0B93F2EE004C0C98 /* DDHidLib */;
+ targetProxy = 55D593600BAE3B3300364849 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+ 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 089C165DFE840E0CC02AAC07 /* English */,
+ );
+ name = InfoPlist.strings;
+ sourceTree = "<group>";
+ };
+ 29B97318FDCFA39411CA2CEA /* MainMenu.nib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 29B97319FDCFA39411CA2CEA /* English */,
+ );
+ name = MainMenu.nib;
+ sourceTree = "<group>";
+ };
+ 55D5927B0BAE306E00364849 /* InfoPlist.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 55D5927C0BAE306E00364849 /* English */,
+ );
+ name = InfoPlist.strings;
+ sourceTree = "<group>";
+ };
+ 55D592920BAE30B600364849 /* MainMenu.nib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 55D592930BAE30B600364849 /* English */,
+ );
+ name = MainMenu.nib;
+ sourceTree = "<group>";
+ };
+ 55DCD9DE0B55D503000648E5 /* EventWatcher.nib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 55DCD9DF0B55D503000648E5 /* English */,
+ );
+ name = EventWatcher.nib;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 551711290B8F420E00C82155 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ PRODUCT_NAME = All;
+ };
+ name = Debug;
+ };
+ 5517112A0B8F420E00C82155 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = YES;
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+ PRODUCT_NAME = All;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ 55193E540B93F2EF004C0C98 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ FRAMEWORK_VERSION = A;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+ GCC_MODEL_TUNING = G5;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h";
+ INFOPLIST_FILE = "DDHidLib-Info.plist";
+ INSTALL_PATH = "@loader_path/../Frameworks";
+ OTHER_LDFLAGS = (
+ "-framework",
+ Foundation,
+ "-framework",
+ AppKit,
+ );
+ PREBINDING = NO;
+ PRODUCT_NAME = DDHidLib;
+ ZERO_LINK = NO;
+ };
+ name = Debug;
+ };
+ 55193E550B93F2EF004C0C98 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = YES;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ FRAMEWORK_VERSION = A;
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+ GCC_MODEL_TUNING = G5;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h";
+ INFOPLIST_FILE = "DDHidLib-Info.plist";
+ INSTALL_PATH = "@loader_path/../Frameworks";
+ OTHER_LDFLAGS = (
+ "-framework",
+ Foundation,
+ "-framework",
+ AppKit,
+ );
+ PREBINDING = NO;
+ PRODUCT_NAME = DDHidLib;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ 559CBAE50B5B313000C8FD74 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 55D592200BAE2E4500364849 /* versions.xcconfig */;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+ GCC_MODEL_TUNING = G5;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h";
+ INFOPLIST_FILE = device_test/Info.plist;
+ INSTALL_PATH = "$(HOME)/Applications";
+ OTHER_LDFLAGS = (
+ "-ObjC",
+ "-framework",
+ Foundation,
+ "-framework",
+ AppKit,
+ );
+ PREBINDING = NO;
+ PRODUCT_NAME = HIDDeviceTest;
+ WRAPPER_EXTENSION = app;
+ ZERO_LINK = NO;
+ };
+ name = Debug;
+ };
+ 559CBAE60B5B313000C8FD74 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 55D592200BAE2E4500364849 /* versions.xcconfig */;
+ buildSettings = {
+ COPY_PHASE_STRIP = YES;
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+ GCC_MODEL_TUNING = G5;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h";
+ INFOPLIST_FILE = device_test/Info.plist;
+ INSTALL_PATH = "$(HOME)/Applications";
+ OTHER_LDFLAGS = (
+ "-ObjC",
+ "-framework",
+ Foundation,
+ "-framework",
+ AppKit,
+ );
+ PREBINDING = NO;
+ PRODUCT_NAME = HIDDeviceTest;
+ WRAPPER_EXTENSION = app;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ 559CBBE70B5B338B00C8FD74 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+ GCC_MODEL_TUNING = G5;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h";
+ INSTALL_PATH = /usr/local/lib;
+ OTHER_LDFLAGS = (
+ "-framework",
+ Foundation,
+ "-framework",
+ AppKit,
+ );
+ PREBINDING = NO;
+ PRODUCT_NAME = ddhid;
+ ZERO_LINK = NO;
+ };
+ name = Debug;
+ };
+ 559CBBE80B5B338B00C8FD74 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = YES;
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+ GCC_MODEL_TUNING = G5;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h";
+ INSTALL_PATH = /usr/local/lib;
+ OTHER_LDFLAGS = (
+ "-framework",
+ Foundation,
+ "-framework",
+ AppKit,
+ );
+ PREBINDING = NO;
+ PRODUCT_NAME = ddhid;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ C01FCF4B08A954540054247B /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 55D592200BAE2E4500364849 /* versions.xcconfig */;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_MODEL_TUNING = G5;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ INFOPLIST_FILE = browser/Info.plist;
+ INSTALL_PATH = "$(HOME)/Applications";
+ OTHER_LDFLAGS = "-ObjC";
+ PRODUCT_NAME = HIDBrowser;
+ WRAPPER_EXTENSION = app;
+ ZERO_LINK = NO;
+ };
+ name = Debug;
+ };
+ C01FCF4C08A954540054247B /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 55D592200BAE2E4500364849 /* versions.xcconfig */;
+ buildSettings = {
+ GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+ GCC_MODEL_TUNING = G5;
+ INFOPLIST_FILE = browser/Info.plist;
+ INSTALL_PATH = "$(HOME)/Applications";
+ OTHER_LDFLAGS = "-ObjC";
+ PRODUCT_NAME = HIDBrowser;
+ WRAPPER_EXTENSION = app;
+ ZERO_LINK = NO;
+ };
+ name = Release;
+ };
+ C01FCF4F08A954540054247B /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 55D592200BAE2E4500364849 /* versions.xcconfig */;
+ buildSettings = {
+ GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.4;
+ PREBINDING = NO;
+ SDKROOT = macosx;
+ VALID_ARCHS = i386;
+ };
+ name = Debug;
+ };
+ C01FCF5008A954540054247B /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 55D592200BAE2E4500364849 /* versions.xcconfig */;
+ buildSettings = {
+ ARCHS = (
+ ppc,
+ i386,
+ );
+ GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.4;
+ PREBINDING = NO;
+ SDKROOT = macosx;
+ VALID_ARCHS = i386;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 551711280B8F420E00C82155 /* Build configuration list for PBXAggregateTarget "All" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 551711290B8F420E00C82155 /* Debug */,
+ 5517112A0B8F420E00C82155 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 55193E530B93F2EF004C0C98 /* Build configuration list for PBXNativeTarget "DDHidLib" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 55193E540B93F2EF004C0C98 /* Debug */,
+ 55193E550B93F2EF004C0C98 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 559CBAE40B5B313000C8FD74 /* Build configuration list for PBXNativeTarget "HIDDeviceTest" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 559CBAE50B5B313000C8FD74 /* Debug */,
+ 559CBAE60B5B313000C8FD74 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 559CBBE60B5B338B00C8FD74 /* Build configuration list for PBXNativeTarget "ddhid" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 559CBBE70B5B338B00C8FD74 /* Debug */,
+ 559CBBE80B5B338B00C8FD74 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "HIDBrowser" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C01FCF4B08A954540054247B /* Debug */,
+ C01FCF4C08A954540054247B /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ C01FCF4E08A954540054247B /* Build configuration list for PBXProject "DDHidLib" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C01FCF4F08A954540054247B /* Debug */,
+ C01FCF5008A954540054247B /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
+}
diff --git a/LICENSE.html b/LICENSE.html
new file mode 100644
index 0000000..5831837
--- /dev/null
+++ b/LICENSE.html
@@ -0,0 +1,181 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN"
+ "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" version="XHTML+RDFa 1.0" dir="ltr">
+
+<head profile="http://www.w3.org/1999/xhtml/vocab">
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<link rel="shortcut icon" href="http://opensource.org/files/garland_favicon.png" type="image/png" />
+<link rel="shortlink" href="/node/66" />
+<link rel="canonical" href="/licenses/MIT" />
+<meta name="Generator" content="Drupal 7 (http://drupal.org)" />
+ <title>The MIT License (MIT) | Open Source Initiative</title>
+ <link type="text/css" rel="stylesheet" href="http://opensource.org/files/css/css_pbm0lsQQJ7A7WCCIMgxLho6mI_kBNgznNUWmTWcnfoE.css" media="all" />
+<link type="text/css" rel="stylesheet" href="http://opensource.org/files/css/css_Frms3llKkCDMuuCHUzEHGgSAc59B2At_Y3KWbmFS9k4.css" media="all" />
+<link type="text/css" rel="stylesheet" href="http://opensource.org/files/css/css_2wI77kyP-rJKVpFW5M3KFcj7Cb99lZalmubKIwWwsmU.css" media="all" />
+<link type="text/css" rel="stylesheet" href="http://opensource.org/files/css/css_k3snrbsthqot7V7ccRZHS9OkCZkwBv4adtNieIVlbEU.css" media="print" />
+
+<!--[if lt IE 7]>
+<link type="text/css" rel="stylesheet" href="http://opensource.org/themes/garland/fix-ie.css?mg005b" media="all" />
+<![endif]-->
+ <script type="text/javascript" src="http://opensource.org/files/js/js_3jHghlMLrjr9xXAC0JufqSSch3oAbkZstSqYdc4uuck.js"></script>
+<script type="text/javascript">
+<!--//--><![CDATA[//><!--
+jQuery.extend(Drupal.settings, {"basePath":"\/","pathPrefix":"","ajaxPageState":{"theme":"garland","theme_token":"oU3oKgkO9Kxh34R6sHTF4WSsGPlfgkgK1fMLCpEJ72I","js":{"misc\/jquery.js":1,"misc\/jquery.once.js":1,"misc\/drupal.js":1},"css":{"modules\/system\/system.base.css":1,"modules\/system\/system.menus.css":1,"modules\/system\/system.messages.css":1,"modules\/system\/system.theme.css":1,"modules\/aggregator\/aggregator.css":1,"modules\/comment\/comment.css":1,"modules\/field\/theme\/field.css":1,"sites\/all\/modules\/mollom\/mollom.css":1,"modules\/node\/node.css":1,"modules\/search\/search.css":1,"modules\/user\/user.css":1,"themes\/garland\/style.css":1,"themes\/garland\/print.css":1,"themes\/garland\/fix-ie.css":1}}});
+//--><!]]>
+</script>
+</head>
+<body class="html not-front not-logged-in one-sidebar sidebar-first page-node page-node- page-node-66 node-type-page fluid-width" >
+ <div id="skip-link">
+ <a href="#main-content" class="element-invisible element-focusable">Skip to main content</a>
+ </div>
+
+ <div id="wrapper">
+ <div id="container" class="clearfix">
+
+ <div id="header">
+ <div id="logo-floater">
+ <div id="branding"><strong><a href="/">
+ <img src="http://opensource.org/files/garland_logo.png" alt="Open Source Initiative " title="Open Source Initiative " id="logo" />
+ <span>Open Source Initiative</span> </a></strong></div>
+ </div>
+
+ </div> <!-- /#header -->
+
+ <div id="sidebar-first" class="sidebar">
+ <div class="region region-sidebar-first">
+ <div id="block-search-form" class="block block-search clearfix">
+
+ <h2 class="title">Search this site:</h2>
+
+ <div class="content">
+ <form action="/licenses/mit-license.php" method="post" id="search-block-form" accept-charset="UTF-8"><div><div class="container-inline">
+ <div class="form-item form-type-textfield form-item-search-block-form">
+ <label class="element-invisible" for="edit-search-block-form--2">Search </label>
+ <input title="Enter the terms you wish to search for." type="text" id="edit-search-block-form--2" name="search_block_form" value="" size="15" maxlength="128" class="form-text" />
+</div>
+<div class="form-actions form-wrapper" id="edit-actions"><input type="submit" id="edit-submit" name="op" value="Search" class="form-submit" /></div><input type="hidden" name="form_build_id" value="form-ADm3Z4uyEPhRis8sKsUf9Oqq50FP1ae1rX3NnMchpDM" />
+<input type="hidden" name="form_id" value="search_block_form" />
+</div>
+</div></form> </div>
+</div>
+<div id="block-system-navigation" class="block block-system block-menu clearfix">
+
+ <h2 class="title">Navigation</h2>
+
+ <div class="content">
+ <ul class="menu"><li class="first collapsed"><a href="/about" title="About the Open Source Initiative">About the OSI</a></li>
+<li class="collapsed"><a href="/osd" title="The actual OSD defining what constitutes an Open Source licence">The Open Source Definition</a></li>
+<li class="collapsed"><a href="/licenses">Open Source Licenses</a></li>
+<li class="collapsed"><a href="/trademark" title="Information about trademark and logo usage ">Trademark and Logo Usage</a></li>
+<li class="leaf"><a href="/faq" title="Frequently Asked Questions about open source and about the OSI.">FAQ</a></li>
+<li class="collapsed"><a href="/osr-intro" title="Open Standards Requirement for Software">Open Standards</a></li>
+<li class="leaf"><a href="/osi-open-source-education" title="OSI&#039;s Open Source Education Initiative and Activities">Open Source Education</a></li>
+<li class="collapsed"><a href="/lists" title="The virtual committees where the OSI&#039;s work gets done">Mailing lists</a></li>
+<li class="collapsed"><a href="/help" title="Resources for questions and further exploration">Getting Help</a></li>
+<li class="collapsed"><a href="http://opensource.org/donate" title="">Donate to the OSI</a></li>
+<li class="leaf"><a href="/members">OSI Individual Membership</a></li>
+<li class="collapsed"><a href="/affiliates" title="Home page for OSI&#039;s membership scheme for non-profits and not-for-profits">OSI Affiliate Membership</a></li>
+<li class="leaf"><a href="/contact" title="">Contact OSI</a></li>
+<li class="last leaf"><a href="/ToS" title="Rules for posting content on this site">Terms of Service</a></li>
+</ul> </div>
+</div>
+ </div>
+ </div>
+
+ <div id="center"><div id="squeeze"><div class="right-corner"><div class="left-corner">
+ <h2 class="element-invisible">You are here</h2><div class="breadcrumb"><a href="/">Home</a></div> <a id="main-content"></a>
+ <div id="tabs-wrapper" class="clearfix"> <h1 class="with-tabs">The MIT License (MIT)</h1>
+ </div> <div class="clearfix">
+ <div class="region region-content">
+ <div id="block-system-main" class="block block-system clearfix">
+
+
+ <div class="content">
+ <div id="node-66" class="node node-page">
+
+
+
+
+ <div class="content clearfix">
+ <img style="float: right; margin: 1em;" width="100" height="137" alt="[OSI Approved License]" src="/trademarks/opensource/OSI-Appro
+ved-License-100x137.png"/>
+ <div class="field field-name-body field-type-text-with-summary field-label-hidden"><div class="field-items"><div class="field-item even"><h1>The MIT License (MIT)</h1>
+
+<tt>
+
+<p>Copyright (c) &lt;year&gt; &lt;copyright holders&gt;</p>
+
+<p>Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:</p>
+
+<p>The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.</p>
+
+<p>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.</p>
+
+
+</div></div></div> </div>
+
+ <div class="clearfix">
+ <div class="links"></div>
+
+ </div>
+
+</div>
+ </div>
+</div>
+ </div>
+ </div>
+ <div class="region region-footer">
+ <div id="block-block-11" class="block block-block clearfix">
+
+
+ <div class="content">
+ <!-- Creative Commons License --><a rel="license" href="http://creativecommons.org/licenses/by/3.0/"><img alt="Creative Commons License" style="border-width: 0" src="http://i.creativecommons.org/l/by/3.0/88x31.png" /></a><br />Opensource.org site content is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 License</a>.<!-- /Creative Commons License -->
+
+<!-- <rdf:RDF xmlns="http://web.resource.org/cc/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
+ <Work rdf:about="">
+ <license rdf:resource="http://creativecommons.org/licenses/by/3.0/" />
+ </Work>
+ <License rdf:about="http://creativecommons.org/licenses/by/3.0/"><permits rdf:resource="http://web.resource.org/cc/Reproduction"/><permits rdf:resource="http://web.resource.org/cc/Distribution"/><requires rdf:resource="http://web.resource.org/cc/Notice"/><requires rdf:resource="http://web.resource.org/cc/Attribution"/><permits rdf:resource="http://web.resource.org/cc/DerivativeWorks"/></License></rdf:RDF>
+-->
+
+| <a href="../ToS">Terms of Service</a>
+ </div>
+</div>
+<div id="block-block-7" class="block block-block clearfix">
+
+
+ <div class="content">
+ <script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
+<!--//--><![CDATA[// ><!--
+
+
+//--><!]]>
+</script><script type="text/javascript">
+<!--//--><![CDATA[// ><!--
+
+_uacct = "UA-3916956-1";
+urchinTracker();
+
+//--><!]]>
+</script> </div>
+</div>
+ </div>
+ </div></div></div></div> <!-- /.left-corner, /.right-corner, /#squeeze, /#center -->
+
+
+ </div> <!-- /#container -->
+ </div> <!-- /#wrapper -->
+ </body>
+</html>
diff --git a/README.md b/README.md
index 4ca735b..5c44eb5 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,10 @@
DDHidLib
-========
+=====
+###by Dave Dribin
-An Objective-C wrapper around IOHIDLib by Dave Dribin \ No newline at end of file
+An Objective-C wrapper around IOHIDLib.
+
+http://www.dribin.org/dave/software/
+
+###Modifications in the repo:
+added experimental support for apple mics with built-in keys. \ No newline at end of file
diff --git a/browser/English.lproj/EventWatcher.nib/classes.nib b/browser/English.lproj/EventWatcher.nib/classes.nib
new file mode 100644
index 0000000..8f04df5
--- /dev/null
+++ b/browser/English.lproj/EventWatcher.nib/classes.nib
@@ -0,0 +1,13 @@
+{
+ IBClasses = (
+ {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
+ {
+ ACTIONS = {clearHistory = id; };
+ CLASS = WatcherWindowController;
+ LANGUAGE = ObjC;
+ OUTLETS = {mEventHistoryController = NSArrayController; };
+ SUPERCLASS = NSWindowController;
+ }
+ );
+ IBVersion = 1;
+} \ No newline at end of file
diff --git a/browser/English.lproj/EventWatcher.nib/info.nib b/browser/English.lproj/EventWatcher.nib/info.nib
new file mode 100644
index 0000000..1c52771
--- /dev/null
+++ b/browser/English.lproj/EventWatcher.nib/info.nib
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IBDocumentLocation</key>
+ <string>69 14 356 240 0 0 1440 878 </string>
+ <key>IBFramework Version</key>
+ <string>446.1</string>
+ <key>IBOpenObjects</key>
+ <array>
+ <integer>5</integer>
+ </array>
+ <key>IBSystem Version</key>
+ <string>8N1037</string>
+</dict>
+</plist>
diff --git a/browser/English.lproj/EventWatcher.nib/keyedobjects.nib b/browser/English.lproj/EventWatcher.nib/keyedobjects.nib
new file mode 100644
index 0000000..61ebe6c
--- /dev/null
+++ b/browser/English.lproj/EventWatcher.nib/keyedobjects.nib
Binary files differ
diff --git a/browser/English.lproj/InfoPlist.strings b/browser/English.lproj/InfoPlist.strings
new file mode 100644
index 0000000..30cfd96
--- /dev/null
+++ b/browser/English.lproj/InfoPlist.strings
Binary files differ
diff --git a/browser/English.lproj/MainMenu.nib/classes.nib b/browser/English.lproj/MainMenu.nib/classes.nib
new file mode 100644
index 0000000..910a1c9
--- /dev/null
+++ b/browser/English.lproj/MainMenu.nib/classes.nib
@@ -0,0 +1,19 @@
+{
+ IBClasses = (
+ {CLASS = DDHidElement; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
+ {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; },
+ {CLASS = HexFormatter; LANGUAGE = ObjC; SUPERCLASS = NSFormatter; },
+ {
+ ACTIONS = {exportPlist = id; watchSelected = id; };
+ CLASS = HidBrowserController;
+ LANGUAGE = ObjC;
+ OUTLETS = {
+ mDevicesController = NSArrayController;
+ mElementsController = NSTreeController;
+ mWindow = NSWindow;
+ };
+ SUPERCLASS = NSObject;
+ }
+ );
+ IBVersion = 1;
+} \ No newline at end of file
diff --git a/browser/English.lproj/MainMenu.nib/info.nib b/browser/English.lproj/MainMenu.nib/info.nib
new file mode 100644
index 0000000..d20a5cf
--- /dev/null
+++ b/browser/English.lproj/MainMenu.nib/info.nib
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>IBDocumentLocation</key>
+ <string>110 86 356 240 0 0 1440 878 </string>
+ <key>IBEditorPositions</key>
+ <dict>
+ <key>29</key>
+ <string>95 721 310 44 0 0 1440 878 </string>
+ </dict>
+ <key>IBFramework Version</key>
+ <string>446.1</string>
+ <key>IBOpenObjects</key>
+ <array>
+ <integer>21</integer>
+ <integer>29</integer>
+ </array>
+ <key>IBSystem Version</key>
+ <string>8N1037</string>
+</dict>
+</plist>
diff --git a/browser/English.lproj/MainMenu.nib/keyedobjects.nib b/browser/English.lproj/MainMenu.nib/keyedobjects.nib
new file mode 100644
index 0000000..904f45d
--- /dev/null
+++ b/browser/English.lproj/MainMenu.nib/keyedobjects.nib
Binary files differ
diff --git a/browser/HIDBrowser_Prefix.pch b/browser/HIDBrowser_Prefix.pch
new file mode 100644
index 0000000..5d5ed48
--- /dev/null
+++ b/browser/HIDBrowser_Prefix.pch
@@ -0,0 +1,7 @@
+//
+// Prefix header for all source files of the 'HIDBrowser' target in the 'HIDBrowser' project
+//
+
+#ifdef __OBJC__
+ #import <Cocoa/Cocoa.h>
+#endif
diff --git a/browser/HexFormatter.h b/browser/HexFormatter.h
new file mode 100644
index 0000000..e3b28c2
--- /dev/null
+++ b/browser/HexFormatter.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+
+@interface HexFormatter : NSFormatter {
+
+}
+
++ (NSString*)format:(long)number;
+
+@end
diff --git a/browser/HexFormatter.m b/browser/HexFormatter.m
new file mode 100644
index 0000000..5ac3f6f
--- /dev/null
+++ b/browser/HexFormatter.m
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import "HexFormatter.h"
+
+
+@implementation HexFormatter
+
++ (NSString*)format:(long)number;
+{
+ return [NSString stringWithFormat: @"0x%02X", number];
+}
+
+
+- (NSString *)stringForObjectValue:(id)anObject {
+ return [HexFormatter format:[anObject longValue]];
+}
+
+- (BOOL)getObjectValue:(id *)anObject forString:(NSString *)string errorDescription:(NSString **)error {
+ return NO;
+}
+
+- (NSAttributedString *)attributedStringForObjectValue:(id)anObject withDefaultAttributes:(NSDictionary *)attributes {
+ return [[[NSAttributedString alloc] initWithString:[self stringForObjectValue:anObject]] autorelease];
+}
+
+
+@end
diff --git a/browser/HidBrowserController.h b/browser/HidBrowserController.h
new file mode 100644
index 0000000..3e7e116
--- /dev/null
+++ b/browser/HidBrowserController.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+
+@interface HidBrowserController : NSObject
+{
+ IBOutlet NSWindow * mWindow;
+ IBOutlet NSArrayController * mDevicesController;
+ IBOutlet NSTreeController * mElementsController;
+ NSArray * mDevices;
+}
+
+- (NSArray *) devices;
+
+- (IBAction) watchSelected: (id) sender;
+
+- (IBAction) exportPlist: (id) sender;
+
+@end
diff --git a/browser/HidBrowserController.m b/browser/HidBrowserController.m
new file mode 100644
index 0000000..4b12267
--- /dev/null
+++ b/browser/HidBrowserController.m
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import "HidBrowserController.h"
+#import "DDHidUsageTables.h"
+#import "DDHidDevice.h"
+#import "DDHidElement.h"
+#import "WatcherWindowController.h"
+
+@implementation HidBrowserController
+
+static BOOL sSleepAtExit = NO;
+
+static void exit_sleeper()
+{
+ while (sSleepAtExit) sleep(60);
+}
+
+- (void) awakeFromNib
+{
+ sSleepAtExit = [[NSUserDefaults standardUserDefaults] boolForKey: @"SleepAtExit"];
+ atexit(exit_sleeper);
+
+ [self willChangeValueForKey: @"devices"];
+ mDevices = [[DDHidDevice allDevices] retain];
+ [self didChangeValueForKey: @"devices"];
+
+ [mWindow center];
+ [mWindow makeKeyAndOrderFront: self];
+}
+
+//===========================================================
+// dealloc
+//===========================================================
+- (void) dealloc
+{
+ [mDevices release];
+
+ mDevices = nil;
+ [super dealloc];
+}
+
+//===========================================================
+// - devices
+//===========================================================
+- (NSArray *) devices
+{
+ return mDevices;
+}
+
+- (DDHidDevice *) selectedDevice;
+{
+ NSArray * selectedDevices = [mDevicesController selectedObjects];
+ if ([selectedDevices count] > 0)
+ return [selectedDevices objectAtIndex: 0];
+ else
+ return nil;
+}
+
+- (IBAction) watchSelected: (id) sender;
+{
+ NSArray * selectedElements = [mElementsController selectedObjects];
+ if ([selectedElements count] == 0)
+ return;
+
+ WatcherWindowController * controller =
+ [[WatcherWindowController alloc] init];
+ [controller setDevice: [self selectedDevice]];
+ [controller setElements: selectedElements];
+ [controller showWindow: self];
+}
+
+- (IBAction) exportPlist: (id) sender;
+{
+ DDHidDevice * selectedDevice = [self selectedDevice];
+ if (selectedDevice == nil)
+ return;
+
+ NSSavePanel * panel = [NSSavePanel savePanel];
+
+ /* set up new attributes */
+ [panel setRequiredFileType: @"plist"];
+ [panel setAllowsOtherFileTypes: NO];
+ [panel setCanSelectHiddenExtension: YES];
+
+ /* display the NSSavePanel */
+ [panel beginSheetForDirectory: NSHomeDirectory()
+ file: @""
+ modalForWindow: [NSApp mainWindow]
+ modalDelegate: self
+ didEndSelector: @selector(exportPlistPanelDidEnd:returnCode:contextInfo:)
+ contextInfo: selectedDevice];
+}
+
+- (void) exportPlistPanelDidEnd: (NSSavePanel *) panel
+ returnCode: (int) returnCode
+ contextInfo: (void *) contextInfo;
+{
+ DDHidDevice * selectedDevice = contextInfo;
+
+ /* if successful, save file under designated name */
+ if (returnCode != NSOKButton)
+ return;
+
+ NSDictionary * deviceProperties = [selectedDevice properties];
+ if (![deviceProperties writeToFile: [panel filename] atomically: YES])
+ NSBeep();
+}
+
+- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication
+{
+ return YES;
+}
+
+- (void)applicationWillTerminate:(NSNotification *)aNotification
+{
+ [self willChangeValueForKey: @"devices"];
+ [mDevices release];
+ mDevices = nil;
+ [self didChangeValueForKey: @"devices"];
+}
+
+@end
diff --git a/browser/Info.plist b/browser/Info.plist
new file mode 100644
index 0000000..feff01c
--- /dev/null
+++ b/browser/Info.plist
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIconFile</key>
+ <string></string>
+ <key>CFBundleIdentifier</key>
+ <string>org.dribin.dave.ddhidlib.HIDBrowser</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>${CURRENT_PROJECT_VERSION}</string>
+ <key>CFBundleShortVersionString</key>
+ <string>${CURRENT_MARKETING_VERSION}</string>
+ <key>NSMainNibFile</key>
+ <string>MainMenu</string>
+ <key>NSPrincipalClass</key>
+ <string>NSApplication</string>
+</dict>
+</plist>
diff --git a/browser/WatcherWindowController.h b/browser/WatcherWindowController.h
new file mode 100644
index 0000000..5cc447a
--- /dev/null
+++ b/browser/WatcherWindowController.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import <Cocoa/Cocoa.h>
+#import "DDHidDevice.h"
+#import "DDHidElement.h"
+
+@class DDHidQueue;
+
+@interface WatcherWindowController : NSWindowController
+{
+ IBOutlet NSArrayController * mEventHistoryController;
+ DDHidDevice * mDevice;
+ NSArray * mElements;
+ DDHidQueue * mQueue;
+ NSMutableArray * mEventHistory;
+ int mNextIndex;
+}
+
+- (DDHidDevice *) device;
+- (void) setDevice: (DDHidDevice *) newDevice;
+
+- (NSArray *) elements;
+- (void) setElements: (NSArray *) newElements;
+
+- (NSMutableArray *) eventHistory;
+- (void) setEventHistory: (NSMutableArray *) anEventHistory;
+- (void) addToEventHistory: (id)mEventHistoryObject;
+- (void) removeFromEventHistory: (id)mEventHistoryObject;
+
+- (BOOL) isWatching;
+- (void) setWatching: (BOOL) watching;
+
+- (IBAction) clearHistory: (id) sender;
+
+@end
diff --git a/browser/WatcherWindowController.m b/browser/WatcherWindowController.m
new file mode 100644
index 0000000..a13c986
--- /dev/null
+++ b/browser/WatcherWindowController.m
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import "WatcherWindowController.h"
+#import "DDHidQueue.h"
+#import "DDHidEvent.h"
+#import "DDHidUsage.h"
+
+@interface WatcherEvent : NSObject
+{
+ NSString * mUsageDescription;
+ DDHidEvent * mEvent;
+ int mIndex;
+}
+
+- (id) initWithUsageDescription: (NSString *) anUsageDecription
+ event: (DDHidEvent *) anEvent
+ index: (int) index;
+
+- (NSString *) usageDescription;
+- (DDHidEvent *) event;
+- (int) index;
+
+@end
+
+@implementation WatcherEvent : NSObject
+
+- (id) initWithUsageDescription: (NSString *) anUsageDescription
+ event: (DDHidEvent *) anEvent
+ index: (int) index
+{
+ if (self = [super init])
+ {
+ mUsageDescription = [anUsageDescription retain];
+ mEvent = [anEvent retain];
+ mIndex = index;
+ }
+ return self;
+}
+
+//===========================================================
+// dealloc
+//===========================================================
+- (void) dealloc
+{
+ [mUsageDescription release];
+ [mEvent release];
+
+ mUsageDescription = nil;
+ mEvent = nil;
+ [super dealloc];
+}
+
+//===========================================================
+// - usageDescription
+//===========================================================
+- (NSString *) usageDescription
+{
+ return mUsageDescription;
+}
+
+//===========================================================
+// - event
+//===========================================================
+- (DDHidEvent *) event
+{
+ return mEvent;
+}
+
+//===========================================================
+// - index
+//===========================================================
+- (int) index
+{
+ return mIndex;
+}
+
+@end
+
+@implementation WatcherWindowController
+
+- (id) init
+{
+ self = [super initWithWindowNibName: @"EventWatcher" owner: self];
+ if (self == nil)
+ return nil;
+
+ mEventHistory = [[NSMutableArray alloc] init];
+ mNextIndex = 1;
+
+ return self;
+}
+
+
+//===========================================================
+// dealloc
+//===========================================================
+- (void) dealloc
+{
+ [mQueue release];
+ [mDevice release];
+ [mElements release];
+ [mEventHistory release];
+
+ mQueue = nil;
+ mDevice = nil;
+ mElements = nil;
+ mEventHistory = nil;
+ [super dealloc];
+}
+
+- (void)windowWillClose:(NSNotification *)notification
+{
+ [mQueue release];
+ mQueue = nil;
+ [mDevice close];
+ [self autorelease];
+}
+
+- (IBAction)showWindow:(id)sender
+{
+ [super showWindow: sender];
+}
+
+- (void) ddhidQueueHasEvents: (DDHidQueue *) hidQueue;
+{
+ WatcherEvent * watcherEvent;
+ watcherEvent =
+ [[WatcherEvent alloc] initWithUsageDescription: @"-----------------------------"
+ event: nil
+ index: mNextIndex++];
+ [watcherEvent autorelease];
+ [mEventHistoryController addObject: watcherEvent];
+
+ NSMutableArray * newEvents = [NSMutableArray array];
+ DDHidEvent * event;
+ while (event = [hidQueue nextEvent])
+ {
+ DDHidElement * element = [mDevice elementForCookie: [event elementCookie]];
+ watcherEvent =
+ [[WatcherEvent alloc] initWithUsageDescription: [[element usage] usageNameWithIds]
+ event: event
+ index: mNextIndex++];
+ [watcherEvent autorelease];
+ [newEvents addObject: watcherEvent];
+ }
+
+ [mEventHistoryController addObjects: newEvents];
+}
+
+- (void) windowDidLoad;
+{
+ [mDevice open];
+ mQueue = [[mDevice createQueueWithSize: 30] retain];
+ [mQueue setDelegate: self];
+ [mQueue addElements: mElements];
+ [self willChangeValueForKey: @"watching"];
+ [mQueue startOnCurrentRunLoop];
+ [self didChangeValueForKey: @"watching"];
+}
+
+//===========================================================
+// device
+//===========================================================
+- (DDHidDevice *) device
+{
+ return [[mDevice retain] autorelease];
+}
+
+- (void) setDevice: (DDHidDevice *) newDevice
+{
+ if (mDevice != newDevice)
+ {
+ [mDevice release];
+ mDevice = [newDevice retain];
+ }
+}
+
+//===========================================================
+// elements
+//===========================================================
+- (NSArray *) elements
+{
+ return [[mElements retain] autorelease];
+}
+
+- (void) setElements: (NSArray *) newElements
+{
+ if (mElements != newElements)
+ {
+ [mElements release];
+ mElements = [newElements retain];
+ }
+}
+
+//===========================================================
+// eventHistory
+//===========================================================
+- (NSMutableArray *) eventHistory
+{
+ return mEventHistory;
+}
+
+- (void) setEventHistory: (NSMutableArray *) anEventHistory
+{
+ if (mEventHistory != anEventHistory)
+ {
+ [mEventHistory release];
+ mEventHistory = [anEventHistory retain];
+ }
+}
+- (void) addToEventHistory: (id)mEventHistoryObject
+{
+ [[self eventHistory] addObject: mEventHistoryObject];
+}
+- (void) removeFromEventHistory: (id)mEventHistoryObject
+{
+ [[self eventHistory] removeObject: mEventHistoryObject];
+}
+
+- (BOOL) isWatching;
+{
+ if (mQueue == nil)
+ return NO;
+ return [mQueue isStarted];
+}
+
+- (void) setWatching: (BOOL) watching;
+{
+ BOOL isStarted = [mQueue isStarted];
+ if (isStarted == watching)
+ return;
+
+ if (watching)
+ [mQueue startOnCurrentRunLoop];
+ else
+ [mQueue stop];
+}
+
+- (IBAction) clearHistory: (id) sender;
+{
+ [self willChangeValueForKey: @"eventHistory"];
+ [mEventHistory removeAllObjects];
+ mNextIndex = 1;
+ [self didChangeValueForKey: @"eventHistory"];
+}
+
+@end
diff --git a/browser/main.m b/browser/main.m
new file mode 100644
index 0000000..f05b99f
--- /dev/null
+++ b/browser/main.m
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+int main(int argc, char *argv[])
+{
+ return NSApplicationMain(argc, (const char **) argv);
+}
diff --git a/changelog.yml b/changelog.yml
new file mode 100644
index 0000000..743fff5
--- /dev/null
+++ b/changelog.yml
@@ -0,0 +1,24 @@
+- version: "1.1"
+ date: 2008-04-22
+ changes:
+ - Added logical joysticks for devices with multiple top-level elements.
+ Should allow devices like PS/2 to USB converters to work better.
+ - Change joystick normalized values to +/- 65536.
+ - Update Apple Remote codes for Leopard.
+ - Improved keyboard barcode scanning for certain devices.
+ - Added internal debugging code to help detect memory leaks.
+
+- version: "1.0.1"
+ date: 2007-04-03
+ changes:
+ - "Replace deprecated stringWithCString: with stringWithUTF8String:."
+ - Make DDHidKeyboard.h public so it gets copied to the framework.
+ - Plugged some memory leaks.
+ - Added a class for barcode scanners, thanks to Lucas Newman of Delicious
+ Monster.
+ - Add support for point of view hat switches on joysticks.
+
+- version: "1.0"
+ date: 2007-03-19
+ changes:
+ - Initial release.
diff --git a/device_test/AppleMikeyPaneController.h b/device_test/AppleMikeyPaneController.h
new file mode 100644
index 0000000..28f6fc1
--- /dev/null
+++ b/device_test/AppleMikeyPaneController.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+
+@class DDHidAppleMikey;
+
+@interface AppleMikeyPaneController : NSObject
+{
+ IBOutlet NSArrayController * mMikeysController;
+ IBOutlet NSArrayController * mMikeysEventsController;
+
+ NSArray * mMikeys;
+ unsigned mMikeyIndex;
+ NSMutableArray * mEvents;
+
+ // Don't retain these
+ DDHidAppleMikey * mCurrentMikey;
+}
+
+- (NSArray *) mMikeys;
+- (void) setMikeys: (NSArray *) theMikeys;
+
+- (unsigned) mikeyIndex;
+- (void) setMikeyIndex: (unsigned) theMikeyIndex;
+
+- (NSMutableArray *) events;
+- (void) setEvents: (NSMutableArray *) theEvents;
+- (void) addEvent: (id)theEvent;
+- (void) removeEvent: (id)theEvent;
+
+@end
+
+@interface AppleMikeyPaneController (DDHidAppleMikeyDelegate)
+
+- (void) ddhidAppleMikey: (DDHidAppleMikey *) mikey
+ press: (unsigned) usageId
+ upOrDown:(BOOL)upOrDown;
+
+@end
diff --git a/device_test/AppleMikeyPaneController.m b/device_test/AppleMikeyPaneController.m
new file mode 100644
index 0000000..0760688
--- /dev/null
+++ b/device_test/AppleMikeyPaneController.m
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import "AppleMikeyPaneController.h"
+#import "DDHidLib.h"
+#include <IOKit/hid/IOHIDUsageTables.h>
+
+@implementation AppleMikeyPaneController
+
+- (id) init;
+{
+ self = [super init];
+ if (self == nil)
+ return nil;
+
+ mEvents = [[NSMutableArray alloc] init];
+
+ return self;
+}
+
+- (void) awakeFromNib;
+{
+ NSArray * mikeys = [DDHidAppleMikey allMikeys];
+
+ [mikeys makeObjectsPerformSelector: @selector(setDelegate:)
+ withObject: self];
+ [self setMikeys: mikeys];
+
+ if ([mikeys count] > 0)
+ [self setMikeyIndex: 0];
+ else
+ [self setMikeyIndex: NSNotFound];
+}
+
+//===========================================================
+// dealloc
+//===========================================================
+- (void) dealloc
+{
+ [mMikeys release];
+ [mEvents release];
+
+ mMikeys = nil;
+ mEvents = nil;
+ [super dealloc];
+}
+
+//===========================================================
+// mikeys
+//===========================================================
+- (NSArray *) mikeys
+{
+ return mMikeys;
+}
+
+- (void) setMikeys: (NSArray *) theMikeys
+{
+ if (mMikeys != theMikeys)
+ {
+ [mMikeys release];
+ mMikeys = [theMikeys retain];
+ }
+}
+//===========================================================
+// mikeyIndex
+//===========================================================
+- (unsigned) mikeyIndex
+{
+ return mMikeyIndex;
+}
+
+- (void) setMikeyIndex: (unsigned) theMikeyIndex
+{
+ if (mCurrentMikey != nil)
+ {
+ [mCurrentMikey stopListening];
+ mCurrentMikey = nil;
+ }
+ mMikeyIndex = theMikeyIndex;
+ [mMikeysController setSelectionIndex: mMikeyIndex];
+ [self willChangeValueForKey: @"events"];
+ [mEvents removeAllObjects];
+ [self didChangeValueForKey: @"events"];
+ if (mMikeyIndex != NSNotFound)
+ {
+ mCurrentMikey = [mMikeys objectAtIndex: mMikeyIndex];
+ [mCurrentMikey startListening];
+ }
+}
+
+//===========================================================
+// events
+//===========================================================
+- (NSMutableArray *) events
+{
+ return mEvents;
+}
+
+- (void) setEvents: (NSMutableArray *) theEvents
+{
+ if (mEvents != theEvents)
+ {
+ [mEvents release];
+ mEvents = [theEvents retain];
+ }
+}
+- (void) addEvent: (id)theEvent
+{
+ [[self events] addObject: theEvent];
+}
+- (void) removeEvent: (id)theEvent
+{
+ [[self events] removeObject: theEvent];
+}
+
+@end
+
+@implementation AppleMikeyPaneController (DDHidAppleMikeyDelegate)
+
+- (void) ddhidAppleMikey:(DDHidAppleMikey *)mikey press:(unsigned int)usageId upOrDown:(BOOL)upOrDown
+{
+ NSString *usage = nil;
+ if(usageId==kHIDUsage_GD_SystemMenuDown) {
+ usage = @"MenuDown";
+ }
+ else if(usageId == kHIDUsage_GD_SystemMenuUp) {
+ usage = @"MenuUp";
+ }
+
+ if(!usage)
+ return;
+
+ NSMutableDictionary * row = [mMikeysEventsController newObject];
+ [row setObject: upOrDown ? @"Down" : @"Up" forKey: @"event"];
+ [row setObject:usage forKey: @"description"];
+ [mMikeysEventsController addObject: row];
+}
+
+@end
diff --git a/device_test/AppleRemote.tiff b/device_test/AppleRemote.tiff
new file mode 100644
index 0000000..7e002ca
--- /dev/null
+++ b/device_test/AppleRemote.tiff
Binary files differ
diff --git a/device_test/AppleRemotePaneController.h b/device_test/AppleRemotePaneController.h
new file mode 100644
index 0000000..ca4a9e9
--- /dev/null
+++ b/device_test/AppleRemotePaneController.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import <Cocoa/Cocoa.h>
+#import "DDHidLib.h"
+
+@class DDHidAppleRemote;
+@class RemoteFeedbackView;
+
+@interface AppleRemotePaneController : NSObject
+{
+ IBOutlet NSButton * mStartStopButton;
+ IBOutlet RemoteFeedbackView * mFeedbackView;
+ IBOutlet NSTextField * mFeedbackText;
+
+ DDHidAppleRemote * mRemote;
+ BOOL mOpenInExclusiveMode;
+}
+
+- (DDHidAppleRemote *) remote;
+
+- (IBAction) toggleListening: (id) sender;
+
+- (BOOL) openInExclusiveMode;
+- (void) setOpenInExclusiveMode: (BOOL) flag;
+
+- (void) ddhidAppleRemoteButton: (DDHidAppleRemoteEventIdentifier) buttonIdentifier
+ pressedDown: (BOOL) pressedDown;
+
+@end
diff --git a/device_test/AppleRemotePaneController.m b/device_test/AppleRemotePaneController.m
new file mode 100644
index 0000000..7cbaf52
--- /dev/null
+++ b/device_test/AppleRemotePaneController.m
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import "AppleRemotePaneController.h"
+#import "RemoteFeedbackView.h"
+
+@implementation AppleRemotePaneController
+
+- (void) awakeFromNib;
+{
+ [self willChangeValueForKey: @"remote"];
+ mRemote = [[DDHidAppleRemote firstRemote] retain];
+ [self didChangeValueForKey: @"remote"];
+
+ [mRemote setDelegate: self];
+ [self setOpenInExclusiveMode: YES];
+}
+
+//===========================================================
+// dealloc
+//===========================================================
+- (void) dealloc
+{
+ [mRemote release];
+
+ mRemote = nil;
+ [super dealloc];
+}
+
+- (DDHidAppleRemote *) remote;
+{
+ return mRemote;
+}
+
+- (IBAction) toggleListening: (id) sender;
+{
+ NSAssert(mRemote != nil, @"Remote is nil");
+
+ if ([mRemote isListening])
+ {
+ [mRemote stopListening];
+ [mStartStopButton setTitle: @"Start Listening"];
+ }
+ else
+ {
+ [mRemote setListenInExclusiveMode: mOpenInExclusiveMode];
+ [mRemote startListening];
+ [mStartStopButton setTitle: @"Stop Listening"];
+ }
+}
+
+//===========================================================
+// openInExclusiveMode
+//===========================================================
+- (BOOL) openInExclusiveMode
+{
+ return mOpenInExclusiveMode;
+}
+
+- (void) setOpenInExclusiveMode: (BOOL) flag
+{
+ mOpenInExclusiveMode = flag;
+}
+
+- (void) ddhidAppleRemoteButton: (DDHidAppleRemoteEventIdentifier) buttonIdentifier
+ pressedDown: (BOOL) pressedDown;
+{
+ NSString * buttonName= nil;
+ NSString * pressed = @"";
+
+ switch(buttonIdentifier)
+ {
+ case kDDHidRemoteButtonVolume_Plus:
+ buttonName = @"Volume up";
+ if (pressedDown) pressed = @"(down)"; else pressed = @"(up)";
+ break;
+ case kDDHidRemoteButtonVolume_Minus:
+ buttonName = @"Volume down";
+ if (pressedDown) pressed = @"(down)"; else pressed = @"(up)";
+ break;
+ case kDDHidRemoteButtonMenu:
+ buttonName = @"Menu";
+ break;
+ case kDDHidRemoteButtonPlay:
+ buttonName = @"Play";
+ break;
+ case kDDHidRemoteButtonRight:
+ buttonName = @"Right";
+ break;
+ case kDDHidRemoteButtonLeft:
+ buttonName = @"Left";
+ break;
+ case kDDHidRemoteButtonRight_Hold:
+ buttonName = @"Right holding";
+ if (pressedDown) pressed = @"(down)"; else pressed = @"(up)";
+ break;
+ case kDDHidRemoteButtonLeft_Hold:
+ buttonName = @"Left holding";
+ if (pressedDown) pressed = @"(down)"; else pressed = @"(up)";
+ break;
+ case kDDHidRemoteButtonPlay_Sleep:
+ buttonName = @"Play (sleep mode)";
+ break;
+ case kDDHidRemoteButtonMenu_Hold:
+ buttonName = @"Menu (long)";
+ break;
+ case kDDHidRemoteControl_Switched:
+ buttonName = @"Remote Control Switched";
+ break;
+ case kDDHidRemoteControl_Paired:
+ buttonName = @"Remote Control Paired";
+ break;
+ default:
+ NSLog(@"Unmapped event for button %d", buttonIdentifier);
+ break;
+ }
+ [mFeedbackText setStringValue:[NSString stringWithFormat:@"%@ %@",
+ buttonName, pressed]];
+
+ [mFeedbackView ddhidAppleRemoteButton: buttonIdentifier
+ pressedDown: pressedDown];
+}
+
+@end
diff --git a/device_test/BoolFormatter.h b/device_test/BoolFormatter.h
new file mode 100644
index 0000000..79661cb
--- /dev/null
+++ b/device_test/BoolFormatter.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+
+@interface BoolFormatter : NSFormatter
+{
+ id labels;
+}
+
+- (id)initWithLables:(id)_l;
+
+@end
diff --git a/device_test/BoolFormatter.m b/device_test/BoolFormatter.m
new file mode 100644
index 0000000..7f302f9
--- /dev/null
+++ b/device_test/BoolFormatter.m
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import "BoolFormatter.h"
+
+
+@implementation BoolFormatter
+
+- (id)initWithLables:(id)_l {
+ if ((self = [super init]) != nil) {
+ self->labels = [_l retain];
+ }
+ return self;
+}
+
+- (void)dealloc {
+ [self->labels release];
+ [super dealloc];
+}
+
+- (BOOL) boolForObjectValue: (id) object
+{
+ BOOL result;
+ if ([object respondsToSelector: @selector(boolValue)])
+ result = [object boolValue] ? YES : NO;
+ else
+ result = NO;
+ return result;
+}
+
+- (NSString *)stringForObjectValue:(id)_obj
+{
+ NSString *str;
+
+ if ([self boolForObjectValue: _obj])
+ str = @"Yes";
+ else
+ str = @"No";
+
+ return (self->labels != nil)
+ ? (NSString *)[self->labels valueForKey:str] : str;
+}
+
+- (NSAttributedString *)attributedStringForObjectValue:(id)anObject
+ withDefaultAttributes:(NSDictionary *)defaultAttributes
+{
+ NSDictionary * yesAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSColor redColor], NSBackgroundColorAttributeName,
+ nil];
+ NSDictionary * attributes = defaultAttributes;
+ if ([self boolForObjectValue: anObject])
+ attributes = yesAttributes;
+
+ NSAttributedString * string =
+ [[NSAttributedString alloc] initWithString: [self stringForObjectValue: anObject]
+ attributes: attributes];
+ [string autorelease];
+ return string;
+}
+
+@end
diff --git a/device_test/ButtonState.h b/device_test/ButtonState.h
new file mode 100644
index 0000000..63bde74
--- /dev/null
+++ b/device_test/ButtonState.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+@interface ButtonState : NSObject
+{
+ NSString * mName;
+ BOOL mPressed;
+}
+
+- (NSString *) name;
+
+- (BOOL) pressed;
+- (void) setPressed: (BOOL) flag;
+
+@end
diff --git a/device_test/ButtonState.m b/device_test/ButtonState.m
new file mode 100644
index 0000000..d093b52
--- /dev/null
+++ b/device_test/ButtonState.m
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import "ButtonState.h"
+
+@implementation ButtonState
+
+- (id) initWithName: (NSString *) name
+{
+ self = [super init];
+ if (self == nil)
+ return nil;
+
+ mName = [name retain];
+ mPressed = NO;
+
+ return self;
+}
+
+//===========================================================
+// dealloc
+//===========================================================
+- (void) dealloc
+{
+ [mName release];
+
+ mName = nil;
+ [super dealloc];
+}
+
+//===========================================================
+// - name
+//===========================================================
+- (NSString *) name
+{
+ return mName;
+}
+
+//===========================================================
+// - pressed
+//===========================================================
+- (BOOL) pressed
+{
+ return mPressed;
+}
+
+//===========================================================
+// - setPressed:
+//===========================================================
+- (void) setPressed: (BOOL) flag
+{
+ mPressed = flag;
+}
+
+@end
+
diff --git a/device_test/DeviceTestController.h b/device_test/DeviceTestController.h
new file mode 100644
index 0000000..bb03cf1
--- /dev/null
+++ b/device_test/DeviceTestController.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+@class MousePaneController;
+
+@interface DeviceTestController : NSObject
+{
+ IBOutlet NSWindow * mWindow;
+ IBOutlet MousePaneController * mMousePaneController;
+}
+
+@end
diff --git a/device_test/DeviceTestController.m b/device_test/DeviceTestController.m
new file mode 100644
index 0000000..58d0f91
--- /dev/null
+++ b/device_test/DeviceTestController.m
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import "DeviceTestController.h"
+
+static BOOL sSleepAtExit = NO;
+
+static void exit_sleeper()
+{
+ while (sSleepAtExit) sleep(60);
+}
+
+@implementation DeviceTestController
+
+- (void) awakeFromNib
+{
+ sSleepAtExit = [[NSUserDefaults standardUserDefaults] boolForKey: @"SleepAtExit"];
+ atexit(exit_sleeper);
+
+ [mWindow center];
+ [mWindow makeKeyAndOrderFront: self];
+}
+
+- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication
+{
+ return YES;
+}
+@end
diff --git a/device_test/English.lproj/InfoPlist.strings b/device_test/English.lproj/InfoPlist.strings
new file mode 100644
index 0000000..30cfd96
--- /dev/null
+++ b/device_test/English.lproj/InfoPlist.strings
Binary files differ
diff --git a/device_test/English.lproj/MainMenu.nib/designable.nib b/device_test/English.lproj/MainMenu.nib/designable.nib
new file mode 100644
index 0000000..fbb8f5a
--- /dev/null
+++ b/device_test/English.lproj/MainMenu.nib/designable.nib
@@ -0,0 +1,5311 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archive type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="8.00">
+ <data>
+ <int key="IBDocument.SystemTarget">1070</int>
+ <string key="IBDocument.SystemVersion">11G63</string>
+ <string key="IBDocument.InterfaceBuilderVersion">3084</string>
+ <string key="IBDocument.AppKitVersion">1138.51</string>
+ <string key="IBDocument.HIToolboxVersion">569.00</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginVersions">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="NS.object.0">3084</string>
+ </object>
+ <array key="IBDocument.IntegratedClassDependencies">
+ <string>NSArrayController</string>
+ <string>NSBox</string>
+ <string>NSButton</string>
+ <string>NSButtonCell</string>
+ <string>NSCustomObject</string>
+ <string>NSCustomView</string>
+ <string>NSLevelIndicator</string>
+ <string>NSLevelIndicatorCell</string>
+ <string>NSMenu</string>
+ <string>NSMenuItem</string>
+ <string>NSPopUpButton</string>
+ <string>NSPopUpButtonCell</string>
+ <string>NSScrollView</string>
+ <string>NSScroller</string>
+ <string>NSTabView</string>
+ <string>NSTabViewItem</string>
+ <string>NSTableColumn</string>
+ <string>NSTableHeaderView</string>
+ <string>NSTableView</string>
+ <string>NSTextField</string>
+ <string>NSTextFieldCell</string>
+ <string>NSView</string>
+ <string>NSWindowTemplate</string>
+ </array>
+ <array key="IBDocument.PluginDependencies">
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ </array>
+ <object class="NSMutableDictionary" key="IBDocument.Metadata">
+ <string key="NS.key.0">PluginDependencyRecalculationVersion</string>
+ <integer value="1" key="NS.object.0"/>
+ </object>
+ <array class="NSMutableArray" key="IBDocument.RootObjects" id="693470140">
+ <object class="NSCustomObject" id="867122125">
+ <object class="NSMutableString" key="NSClassName">
+ <characters key="NS.bytes">NSApplication</characters>
+ </object>
+ </object>
+ <object class="NSCustomObject" id="908386337">
+ <string key="NSClassName">FirstResponder</string>
+ </object>
+ <object class="NSCustomObject" id="426702588">
+ <string key="NSClassName">NSApplication</string>
+ </object>
+ <object class="NSWindowTemplate" id="982793345">
+ <int key="NSWindowStyleMask">15</int>
+ <int key="NSWindowBacking">2</int>
+ <string key="NSWindowRect">{{183, 341}, {529, 499}}</string>
+ <int key="NSWTFlags">1881669632</int>
+ <string key="NSWindowTitle">HID Device Test</string>
+ <string key="NSWindowClass">NSWindow</string>
+ <object class="NSMutableString" key="NSViewClass">
+ <characters key="NS.bytes">View</characters>
+ </object>
+ <nil key="NSUserInterfaceItemIdentifier"/>
+ <string key="NSWindowContentMinSize">{213, 107}</string>
+ <object class="NSView" key="NSWindowView" id="1006738540">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">256</int>
+ <array class="NSMutableArray" key="NSSubviews">
+ <object class="NSTabView" id="644721648">
+ <reference key="NSNextResponder" ref="1006738540"/>
+ <int key="NSvFlags">274</int>
+ <string key="NSFrame">{{13, 10}, {503, 483}}</string>
+ <reference key="NSSuperview" ref="1006738540"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="348322794"/>
+ <array class="NSMutableArray" key="NSTabViewItems">
+ <object class="NSTabViewItem" id="301669676">
+ <object class="NSMutableString" key="NSIdentifier">
+ <characters key="NS.bytes">1</characters>
+ </object>
+ <object class="NSView" key="NSView" id="854750114">
+ <nil key="NSNextResponder"/>
+ <int key="NSvFlags">256</int>
+ <array class="NSMutableArray" key="NSSubviews">
+ <object class="NSTextField" id="803418548">
+ <reference key="NSNextResponder" ref="854750114"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{17, 399}, {50, 17}}</string>
+ <reference key="NSSuperview" ref="854750114"/>
+ <reference key="NSNextKeyView" ref="1023428307"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="960206382">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">272629760</int>
+ <string key="NSContents">Mouse:</string>
+ <object class="NSFont" key="NSSupport" id="11966484">
+ <string key="NSName">LucidaGrande</string>
+ <double key="NSSize">13</double>
+ <int key="NSfFlags">1044</int>
+ </object>
+ <reference key="NSControlView" ref="803418548"/>
+ <object class="NSColor" key="NSBackgroundColor" id="520461807">
+ <int key="NSColorSpace">6</int>
+ <string key="NSCatalogName">System</string>
+ <string key="NSColorName">controlColor</string>
+ <object class="NSColor" key="NSColor" id="531362288">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MC42NjY2NjY2NjY3AA</bytes>
+ </object>
+ </object>
+ <object class="NSColor" key="NSTextColor" id="309990206">
+ <int key="NSColorSpace">6</int>
+ <string key="NSCatalogName">System</string>
+ <string key="NSColorName">controlTextColor</string>
+ <object class="NSColor" key="NSColor" id="557825989">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MAA</bytes>
+ </object>
+ </object>
+ </object>
+ </object>
+ <object class="NSPopUpButton" id="1023428307">
+ <reference key="NSNextResponder" ref="854750114"/>
+ <int key="NSvFlags">266</int>
+ <string key="NSFrame">{{69, 393}, {397, 26}}</string>
+ <reference key="NSSuperview" ref="854750114"/>
+ <reference key="NSNextKeyView" ref="186449852"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSPopUpButtonCell" key="NSCell" id="874323760">
+ <int key="NSCellFlags">-2076049856</int>
+ <int key="NSCellFlags2">2048</int>
+ <reference key="NSSupport" ref="11966484"/>
+ <reference key="NSControlView" ref="1023428307"/>
+ <int key="NSButtonFlags">109199615</int>
+ <int key="NSButtonFlags2">1</int>
+ <object class="NSFont" key="NSAlternateImage" id="121555804">
+ <string key="NSName">LucidaGrande</string>
+ <double key="NSSize">13</double>
+ <int key="NSfFlags">16</int>
+ </object>
+ <string key="NSAlternateContents"/>
+ <object class="NSMutableString" key="NSKeyEquivalent">
+ <characters key="NS.bytes"/>
+ </object>
+ <int key="NSPeriodicDelay">400</int>
+ <int key="NSPeriodicInterval">75</int>
+ <object class="NSMenuItem" key="NSMenuItem" id="821687636">
+ <reference key="NSMenu" ref="70472645"/>
+ <string key="NSTitle">Item1</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <int key="NSState">1</int>
+ <object class="NSCustomResource" key="NSOnImage" id="555564785">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">NSMenuCheckmark</string>
+ </object>
+ <object class="NSCustomResource" key="NSMixedImage" id="189791066">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">NSMenuMixedState</string>
+ </object>
+ <string key="NSAction">_popUpItemAction:</string>
+ <reference key="NSTarget" ref="874323760"/>
+ </object>
+ <bool key="NSMenuItemRespectAlignment">YES</bool>
+ <object class="NSMenu" key="NSMenu" id="70472645">
+ <object class="NSMutableString" key="NSTitle">
+ <characters key="NS.bytes">OtherViews</characters>
+ </object>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <reference ref="821687636"/>
+ <object class="NSMenuItem" id="554006839">
+ <reference key="NSMenu" ref="70472645"/>
+ <string key="NSTitle">Item2</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ <string key="NSAction">_popUpItemAction:</string>
+ <reference key="NSTarget" ref="874323760"/>
+ </object>
+ <object class="NSMenuItem" id="781805482">
+ <reference key="NSMenu" ref="70472645"/>
+ <string key="NSTitle">Item3</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ <string key="NSAction">_popUpItemAction:</string>
+ <reference key="NSTarget" ref="874323760"/>
+ </object>
+ </array>
+ </object>
+ <int key="NSPreferredEdge">3</int>
+ <bool key="NSUsesItemFromMenu">YES</bool>
+ <bool key="NSAltersState">YES</bool>
+ <int key="NSArrowPosition">1</int>
+ </object>
+ </object>
+ <object class="NSTextField" id="186449852">
+ <reference key="NSNextResponder" ref="854750114"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{17, 372}, {93, 17}}</string>
+ <reference key="NSSuperview" ref="854750114"/>
+ <reference key="NSNextKeyView" ref="445056641"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="721914736">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">272629760</int>
+ <string key="NSContents">Manufacturer:</string>
+ <reference key="NSSupport" ref="11966484"/>
+ <reference key="NSControlView" ref="186449852"/>
+ <reference key="NSBackgroundColor" ref="520461807"/>
+ <reference key="NSTextColor" ref="309990206"/>
+ </object>
+ </object>
+ <object class="NSTextField" id="445056641">
+ <reference key="NSNextResponder" ref="854750114"/>
+ <int key="NSvFlags">266</int>
+ <string key="NSFrame">{{112, 372}, {354, 17}}</string>
+ <reference key="NSSuperview" ref="854750114"/>
+ <reference key="NSNextKeyView" ref="299472703"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="1051972028">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">272629760</int>
+ <string key="NSContents">System Font Text</string>
+ <reference key="NSSupport" ref="11966484"/>
+ <reference key="NSControlView" ref="445056641"/>
+ <reference key="NSBackgroundColor" ref="520461807"/>
+ <reference key="NSTextColor" ref="309990206"/>
+ </object>
+ </object>
+ <object class="NSTextField" id="848268071">
+ <reference key="NSNextResponder" ref="854750114"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{48, 338}, {62, 17}}</string>
+ <reference key="NSSuperview" ref="854750114"/>
+ <reference key="NSNextKeyView" ref="867143968"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="777783325">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">272629760</int>
+ <string key="NSContents">Mouse X:</string>
+ <reference key="NSSupport" ref="11966484"/>
+ <reference key="NSControlView" ref="848268071"/>
+ <reference key="NSBackgroundColor" ref="520461807"/>
+ <reference key="NSTextColor" ref="309990206"/>
+ </object>
+ </object>
+ <object class="NSBox" id="299472703">
+ <reference key="NSNextResponder" ref="854750114"/>
+ <int key="NSvFlags">266</int>
+ <string key="NSFrame">{{12, 361}, {459, 5}}</string>
+ <reference key="NSSuperview" ref="854750114"/>
+ <reference key="NSNextKeyView" ref="848268071"/>
+ <string key="NSOffsets">{0, 0}</string>
+ <object class="NSTextFieldCell" key="NSTitleCell">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">0</int>
+ <string key="NSContents">Box</string>
+ <reference key="NSSupport" ref="11966484"/>
+ <object class="NSColor" key="NSBackgroundColor" id="147273098">
+ <int key="NSColorSpace">6</int>
+ <string key="NSCatalogName">System</string>
+ <string key="NSColorName">textBackgroundColor</string>
+ <object class="NSColor" key="NSColor" id="991614945">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MQA</bytes>
+ </object>
+ </object>
+ <object class="NSColor" key="NSTextColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MCAwLjgwMDAwMDAxAA</bytes>
+ </object>
+ </object>
+ <int key="NSBorderType">3</int>
+ <int key="NSBoxType">2</int>
+ <int key="NSTitlePosition">0</int>
+ <bool key="NSTransparent">NO</bool>
+ </object>
+ <object class="NSTextField" id="548001438">
+ <reference key="NSNextResponder" ref="854750114"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{46, 312}, {62, 17}}</string>
+ <reference key="NSSuperview" ref="854750114"/>
+ <reference key="NSNextKeyView" ref="114543662"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="873471934">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">272629760</int>
+ <string key="NSContents">Mouse Y:</string>
+ <reference key="NSSupport" ref="11966484"/>
+ <reference key="NSControlView" ref="548001438"/>
+ <reference key="NSBackgroundColor" ref="520461807"/>
+ <reference key="NSTextColor" ref="309990206"/>
+ </object>
+ </object>
+ <object class="NSTextField" id="198193797">
+ <reference key="NSNextResponder" ref="854750114"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{17, 286}, {91, 17}}</string>
+ <reference key="NSSuperview" ref="854750114"/>
+ <reference key="NSNextKeyView" ref="679224553"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="213114820">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">272629760</int>
+ <string key="NSContents">Mouse Wheel:</string>
+ <reference key="NSSupport" ref="11966484"/>
+ <reference key="NSControlView" ref="198193797"/>
+ <reference key="NSBackgroundColor" ref="520461807"/>
+ <reference key="NSTextColor" ref="309990206"/>
+ </object>
+ </object>
+ <object class="NSLevelIndicator" id="867143968">
+ <reference key="NSNextResponder" ref="854750114"/>
+ <int key="NSvFlags">266</int>
+ <string key="NSFrame">{{113, 338}, {350, 16}}</string>
+ <reference key="NSSuperview" ref="854750114"/>
+ <reference key="NSNextKeyView" ref="548001438"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSLevelIndicatorCell" key="NSCell" id="465679605">
+ <int key="NSCellFlags">130560</int>
+ <int key="NSCellFlags2">0</int>
+ <reference key="NSControlView" ref="867143968"/>
+ <double key="NSMaxValue">5000</double>
+ <int key="NSIndicatorStyle">1</int>
+ </object>
+ </object>
+ <object class="NSLevelIndicator" id="114543662">
+ <reference key="NSNextResponder" ref="854750114"/>
+ <int key="NSvFlags">266</int>
+ <string key="NSFrame">{{113, 312}, {350, 16}}</string>
+ <reference key="NSSuperview" ref="854750114"/>
+ <reference key="NSNextKeyView" ref="198193797"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSLevelIndicatorCell" key="NSCell" id="14328985">
+ <int key="NSCellFlags">130560</int>
+ <int key="NSCellFlags2">0</int>
+ <reference key="NSControlView" ref="114543662"/>
+ <double key="NSMaxValue">5000</double>
+ <int key="NSIndicatorStyle">1</int>
+ </object>
+ </object>
+ <object class="NSLevelIndicator" id="679224553">
+ <reference key="NSNextResponder" ref="854750114"/>
+ <int key="NSvFlags">266</int>
+ <string key="NSFrame">{{113, 286}, {350, 16}}</string>
+ <reference key="NSSuperview" ref="854750114"/>
+ <reference key="NSNextKeyView" ref="1019553122"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSLevelIndicatorCell" key="NSCell" id="537133846">
+ <int key="NSCellFlags">130560</int>
+ <int key="NSCellFlags2">0</int>
+ <reference key="NSControlView" ref="679224553"/>
+ <double key="NSMaxValue">5</double>
+ <int key="NSIndicatorStyle">1</int>
+ </object>
+ </object>
+ <object class="NSScrollView" id="1019553122">
+ <reference key="NSNextResponder" ref="854750114"/>
+ <int key="NSvFlags">272</int>
+ <array class="NSMutableArray" key="NSSubviews">
+ <object class="NSClipView" id="1025379532">
+ <reference key="NSNextResponder" ref="1019553122"/>
+ <int key="NSvFlags">2304</int>
+ <array class="NSMutableArray" key="NSSubviews">
+ <object class="NSTableView" id="392699757">
+ <reference key="NSNextResponder" ref="1025379532"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrameSize">{157, 240}</string>
+ <reference key="NSSuperview" ref="1025379532"/>
+ <reference key="NSNextKeyView" ref="803957232"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTableHeaderView" key="NSHeaderView" id="772621236">
+ <reference key="NSNextResponder" ref="862989901"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrameSize">{157, 17}</string>
+ <reference key="NSSuperview" ref="862989901"/>
+ <reference key="NSNextKeyView" ref="569263196"/>
+ <reference key="NSTableView" ref="392699757"/>
+ </object>
+ <object class="_NSCornerView" key="NSCornerView" id="569263196">
+ <reference key="NSNextResponder" ref="1019553122"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrame">{{158, 0}, {16, 17}}</string>
+ <reference key="NSSuperview" ref="1019553122"/>
+ <reference key="NSNextKeyView" ref="1025379532"/>
+ </object>
+ <array class="NSMutableArray" key="NSTableColumns">
+ <object class="NSTableColumn" id="925696421">
+ <double key="NSWidth">65</double>
+ <double key="NSMinWidth">40</double>
+ <double key="NSMaxWidth">1000</double>
+ <object class="NSTableHeaderCell" key="NSHeaderCell">
+ <int key="NSCellFlags">75628096</int>
+ <int key="NSCellFlags2">2048</int>
+ <string key="NSContents">Button</string>
+ <object class="NSFont" key="NSSupport" id="26">
+ <string key="NSName">LucidaGrande</string>
+ <double key="NSSize">11</double>
+ <int key="NSfFlags">3100</int>
+ </object>
+ <object class="NSColor" key="NSBackgroundColor" id="1032951786">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MC4zMzMzMzI5OQA</bytes>
+ </object>
+ <object class="NSColor" key="NSTextColor" id="906593754">
+ <int key="NSColorSpace">6</int>
+ <string key="NSCatalogName">System</string>
+ <string key="NSColorName">headerTextColor</string>
+ <reference key="NSColor" ref="557825989"/>
+ </object>
+ </object>
+ <object class="NSTextFieldCell" key="NSDataCell" id="907171440">
+ <int key="NSCellFlags">337772096</int>
+ <int key="NSCellFlags2">2048</int>
+ <reference key="NSSupport" ref="11966484"/>
+ <reference key="NSControlView" ref="392699757"/>
+ <object class="NSColor" key="NSBackgroundColor" id="791991748">
+ <int key="NSColorSpace">6</int>
+ <string key="NSCatalogName">System</string>
+ <string key="NSColorName">controlBackgroundColor</string>
+ <reference key="NSColor" ref="531362288"/>
+ </object>
+ <reference key="NSTextColor" ref="309990206"/>
+ </object>
+ <int key="NSResizingMask">3</int>
+ <bool key="NSIsResizeable">YES</bool>
+ <bool key="NSIsEditable">YES</bool>
+ <reference key="NSTableView" ref="392699757"/>
+ </object>
+ <object class="NSTableColumn" id="108449693">
+ <double key="NSWidth">85.97607421875</double>
+ <double key="NSMinWidth">48.97607421875</double>
+ <double key="NSMaxWidth">1000</double>
+ <object class="NSTableHeaderCell" key="NSHeaderCell">
+ <int key="NSCellFlags">75628096</int>
+ <int key="NSCellFlags2">2048</int>
+ <string key="NSContents">Pressed</string>
+ <reference key="NSSupport" ref="26"/>
+ <reference key="NSBackgroundColor" ref="1032951786"/>
+ <reference key="NSTextColor" ref="906593754"/>
+ </object>
+ <object class="NSTextFieldCell" key="NSDataCell" id="282094758">
+ <int key="NSCellFlags">337772032</int>
+ <int key="NSCellFlags2">0</int>
+ <object class="NSFont" key="NSSupport" id="905429554">
+ <string key="NSName">LucidaGrande</string>
+ <double key="NSSize">12</double>
+ <int key="NSfFlags">16</int>
+ </object>
+ <reference key="NSControlView" ref="392699757"/>
+ <reference key="NSBackgroundColor" ref="147273098"/>
+ <reference key="NSTextColor" ref="309990206"/>
+ </object>
+ <int key="NSResizingMask">3</int>
+ <bool key="NSIsResizeable">YES</bool>
+ <bool key="NSIsEditable">YES</bool>
+ <reference key="NSTableView" ref="392699757"/>
+ </object>
+ </array>
+ <double key="NSIntercellSpacingWidth">3</double>
+ <double key="NSIntercellSpacingHeight">2</double>
+ <reference key="NSBackgroundColor" ref="991614945"/>
+ <object class="NSColor" key="NSGridColor" id="155750304">
+ <int key="NSColorSpace">6</int>
+ <string key="NSCatalogName">System</string>
+ <string key="NSColorName">gridColor</string>
+ <object class="NSColor" key="NSColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MC41AA</bytes>
+ </object>
+ </object>
+ <double key="NSRowHeight">17</double>
+ <int key="NSTvFlags">-700448768</int>
+ <reference key="NSDelegate"/>
+ <reference key="NSDataSource"/>
+ <int key="NSColumnAutoresizingStyle">5</int>
+ <int key="NSDraggingSourceMaskForLocal">15</int>
+ <int key="NSDraggingSourceMaskForNonLocal">0</int>
+ <bool key="NSAllowsTypeSelect">YES</bool>
+ <int key="NSTableViewDraggingDestinationStyle">0</int>
+ <int key="NSTableViewGroupRowStyle">1</int>
+ </object>
+ </array>
+ <string key="NSFrame">{{1, 17}, {157, 240}}</string>
+ <reference key="NSSuperview" ref="1019553122"/>
+ <reference key="NSNextKeyView" ref="392699757"/>
+ <reference key="NSDocView" ref="392699757"/>
+ <reference key="NSBGColor" ref="791991748"/>
+ <int key="NScvFlags">4</int>
+ </object>
+ <object class="NSScroller" id="803957232">
+ <reference key="NSNextResponder" ref="1019553122"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrame">{{158, 17}, {15, 240}}</string>
+ <reference key="NSSuperview" ref="1019553122"/>
+ <reference key="NSNextKeyView"/>
+ <reference key="NSTarget" ref="1019553122"/>
+ <string key="NSAction">_doScroller:</string>
+ <double key="NSPercent">0.89473682641983032</double>
+ </object>
+ <object class="NSScroller" id="722307718">
+ <reference key="NSNextResponder" ref="1019553122"/>
+ <int key="NSvFlags">-2147483392</int>
+ <string key="NSFrame">{{-100, -100}, {131, 15}}</string>
+ <reference key="NSSuperview" ref="1019553122"/>
+ <reference key="NSNextKeyView" ref="862989901"/>
+ <int key="NSsFlags">1</int>
+ <reference key="NSTarget" ref="1019553122"/>
+ <string key="NSAction">_doScroller:</string>
+ <double key="NSPercent">0.99047619104385376</double>
+ </object>
+ <object class="NSClipView" id="862989901">
+ <reference key="NSNextResponder" ref="1019553122"/>
+ <int key="NSvFlags">2304</int>
+ <array class="NSMutableArray" key="NSSubviews">
+ <reference ref="772621236"/>
+ </array>
+ <string key="NSFrame">{{1, 0}, {157, 17}}</string>
+ <reference key="NSSuperview" ref="1019553122"/>
+ <reference key="NSNextKeyView" ref="772621236"/>
+ <reference key="NSDocView" ref="772621236"/>
+ <reference key="NSBGColor" ref="791991748"/>
+ <int key="NScvFlags">4</int>
+ </object>
+ <reference ref="569263196"/>
+ </array>
+ <string key="NSFrame">{{113, 20}, {174, 258}}</string>
+ <reference key="NSSuperview" ref="854750114"/>
+ <reference key="NSNextKeyView" ref="722307718"/>
+ <int key="NSsFlags">133138</int>
+ <reference key="NSVScroller" ref="803957232"/>
+ <reference key="NSHScroller" ref="722307718"/>
+ <reference key="NSContentView" ref="1025379532"/>
+ <reference key="NSHeaderClipView" ref="862989901"/>
+ <reference key="NSCornerView" ref="569263196"/>
+ <bytes key="NSScrollAmts">QSAAAEEgAABBmAAAQZgAAA</bytes>
+ </object>
+ </array>
+ <string key="NSFrame">{{10, 33}, {483, 437}}</string>
+ <reference key="NSNextKeyView" ref="803418548"/>
+ </object>
+ <string key="NSLabel">Mice</string>
+ <reference key="NSColor" ref="520461807"/>
+ <reference key="NSTabView" ref="644721648"/>
+ </object>
+ <object class="NSTabViewItem" id="637701892">
+ <object class="NSMutableString" key="NSIdentifier">
+ <characters key="NS.bytes">2</characters>
+ </object>
+ <object class="NSView" key="NSView" id="639734842">
+ <nil key="NSNextResponder"/>
+ <int key="NSvFlags">256</int>
+ <array class="NSMutableArray" key="NSSubviews">
+ <object class="NSTextField" id="604537169">
+ <reference key="NSNextResponder" ref="639734842"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{17, 399}, {57, 17}}</string>
+ <reference key="NSSuperview" ref="639734842"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="361458923">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">272629760</int>
+ <string key="NSContents">Joystick:</string>
+ <reference key="NSSupport" ref="11966484"/>
+ <reference key="NSControlView" ref="604537169"/>
+ <reference key="NSBackgroundColor" ref="520461807"/>
+ <reference key="NSTextColor" ref="309990206"/>
+ </object>
+ </object>
+ <object class="NSPopUpButton" id="470251532">
+ <reference key="NSNextResponder" ref="639734842"/>
+ <int key="NSvFlags">266</int>
+ <string key="NSFrame">{{76, 393}, {390, 26}}</string>
+ <reference key="NSSuperview" ref="639734842"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSPopUpButtonCell" key="NSCell" id="656700384">
+ <int key="NSCellFlags">-2076049856</int>
+ <int key="NSCellFlags2">2048</int>
+ <reference key="NSSupport" ref="11966484"/>
+ <reference key="NSControlView" ref="470251532"/>
+ <int key="NSButtonFlags">109199615</int>
+ <int key="NSButtonFlags2">1</int>
+ <reference key="NSAlternateImage" ref="121555804"/>
+ <string key="NSAlternateContents"/>
+ <object class="NSMutableString" key="NSKeyEquivalent">
+ <characters key="NS.bytes"/>
+ </object>
+ <int key="NSPeriodicDelay">400</int>
+ <int key="NSPeriodicInterval">75</int>
+ <object class="NSMenuItem" key="NSMenuItem" id="642014613">
+ <reference key="NSMenu" ref="794327235"/>
+ <string key="NSTitle">Item1</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <int key="NSState">1</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ <string key="NSAction">_popUpItemAction:</string>
+ <reference key="NSTarget" ref="656700384"/>
+ </object>
+ <bool key="NSMenuItemRespectAlignment">YES</bool>
+ <object class="NSMenu" key="NSMenu" id="794327235">
+ <object class="NSMutableString" key="NSTitle">
+ <characters key="NS.bytes">OtherViews</characters>
+ </object>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <reference ref="642014613"/>
+ <object class="NSMenuItem" id="424623477">
+ <reference key="NSMenu" ref="794327235"/>
+ <string key="NSTitle">Item2</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ <string key="NSAction">_popUpItemAction:</string>
+ <reference key="NSTarget" ref="656700384"/>
+ </object>
+ <object class="NSMenuItem" id="563627306">
+ <reference key="NSMenu" ref="794327235"/>
+ <string key="NSTitle">Item3</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ <string key="NSAction">_popUpItemAction:</string>
+ <reference key="NSTarget" ref="656700384"/>
+ </object>
+ </array>
+ </object>
+ <int key="NSPreferredEdge">3</int>
+ <bool key="NSUsesItemFromMenu">YES</bool>
+ <bool key="NSAltersState">YES</bool>
+ <int key="NSArrowPosition">1</int>
+ </object>
+ </object>
+ <object class="NSTextField" id="30575616">
+ <reference key="NSNextResponder" ref="639734842"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{17, 372}, {93, 17}}</string>
+ <reference key="NSSuperview" ref="639734842"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="895842563">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">272629760</int>
+ <string key="NSContents">Manufacturer:</string>
+ <reference key="NSSupport" ref="11966484"/>
+ <reference key="NSControlView" ref="30575616"/>
+ <reference key="NSBackgroundColor" ref="520461807"/>
+ <reference key="NSTextColor" ref="309990206"/>
+ </object>
+ </object>
+ <object class="NSTextField" id="28013203">
+ <reference key="NSNextResponder" ref="639734842"/>
+ <int key="NSvFlags">266</int>
+ <string key="NSFrame">{{112, 372}, {354, 17}}</string>
+ <reference key="NSSuperview" ref="639734842"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="646237192">
+ <int key="NSCellFlags">69336577</int>
+ <int key="NSCellFlags2">272629760</int>
+ <string key="NSContents">System Font Text</string>
+ <reference key="NSSupport" ref="11966484"/>
+ <reference key="NSControlView" ref="28013203"/>
+ <reference key="NSBackgroundColor" ref="520461807"/>
+ <reference key="NSTextColor" ref="309990206"/>
+ </object>
+ </object>
+ <object class="NSScrollView" id="416538861">
+ <reference key="NSNextResponder" ref="639734842"/>
+ <int key="NSvFlags">276</int>
+ <array class="NSMutableArray" key="NSSubviews">
+ <object class="NSClipView" id="578574056">
+ <reference key="NSNextResponder" ref="416538861"/>
+ <int key="NSvFlags">2304</int>
+ <array class="NSMutableArray" key="NSSubviews">
+ <object class="NSTableView" id="209939006">
+ <reference key="NSNextResponder" ref="578574056"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrameSize">{177, 267}</string>
+ <reference key="NSSuperview" ref="578574056"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTableHeaderView" key="NSHeaderView" id="644754426">
+ <reference key="NSNextResponder" ref="226206000"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrameSize">{177, 17}</string>
+ <reference key="NSSuperview" ref="226206000"/>
+ <reference key="NSTableView" ref="209939006"/>
+ </object>
+ <object class="_NSCornerView" key="NSCornerView" id="694675632">
+ <reference key="NSNextResponder" ref="416538861"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrame">{{178, 0}, {16, 17}}</string>
+ <reference key="NSSuperview" ref="416538861"/>
+ </object>
+ <array class="NSMutableArray" key="NSTableColumns">
+ <object class="NSTableColumn" id="214598876">
+ <double key="NSWidth">80</double>
+ <double key="NSMinWidth">40</double>
+ <double key="NSMaxWidth">1000</double>
+ <object class="NSTableHeaderCell" key="NSHeaderCell">
+ <int key="NSCellFlags">75628096</int>
+ <int key="NSCellFlags2">2048</int>
+ <string key="NSContents">Button</string>
+ <reference key="NSSupport" ref="26"/>
+ <object class="NSColor" key="NSBackgroundColor" id="693116718">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MC4zMzMzMzI5OQA</bytes>
+ </object>
+ <reference key="NSTextColor" ref="906593754"/>
+ </object>
+ <object class="NSTextFieldCell" key="NSDataCell" id="826160026">
+ <int key="NSCellFlags">337772096</int>
+ <int key="NSCellFlags2">2048</int>
+ <reference key="NSSupport" ref="11966484"/>
+ <reference key="NSControlView" ref="209939006"/>
+ <reference key="NSBackgroundColor" ref="791991748"/>
+ <reference key="NSTextColor" ref="309990206"/>
+ </object>
+ <int key="NSResizingMask">3</int>
+ <bool key="NSIsResizeable">YES</bool>
+ <reference key="NSTableView" ref="209939006"/>
+ </object>
+ <object class="NSTableColumn" id="234886615">
+ <double key="NSWidth">90.97607421875</double>
+ <double key="NSMinWidth">48.97607421875</double>
+ <double key="NSMaxWidth">1000</double>
+ <object class="NSTableHeaderCell" key="NSHeaderCell">
+ <int key="NSCellFlags">75628096</int>
+ <int key="NSCellFlags2">2048</int>
+ <string key="NSContents">Pressed</string>
+ <reference key="NSSupport" ref="26"/>
+ <reference key="NSBackgroundColor" ref="693116718"/>
+ <reference key="NSTextColor" ref="906593754"/>
+ </object>
+ <object class="NSTextFieldCell" key="NSDataCell" id="324020026">
+ <int key="NSCellFlags">337772032</int>
+ <int key="NSCellFlags2">0</int>
+ <reference key="NSSupport" ref="905429554"/>
+ <reference key="NSControlView" ref="209939006"/>
+ <reference key="NSBackgroundColor" ref="147273098"/>
+ <reference key="NSTextColor" ref="309990206"/>
+ </object>
+ <int key="NSResizingMask">3</int>
+ <bool key="NSIsResizeable">YES</bool>
+ <reference key="NSTableView" ref="209939006"/>
+ </object>
+ </array>
+ <double key="NSIntercellSpacingWidth">3</double>
+ <double key="NSIntercellSpacingHeight">2</double>
+ <reference key="NSBackgroundColor" ref="991614945"/>
+ <reference key="NSGridColor" ref="155750304"/>
+ <double key="NSRowHeight">17</double>
+ <int key="NSTvFlags">-700448768</int>
+ <reference key="NSDelegate"/>
+ <reference key="NSDataSource"/>
+ <int key="NSColumnAutoresizingStyle">5</int>
+ <int key="NSDraggingSourceMaskForLocal">15</int>
+ <int key="NSDraggingSourceMaskForNonLocal">0</int>
+ <bool key="NSAllowsTypeSelect">YES</bool>
+ <int key="NSTableViewDraggingDestinationStyle">0</int>
+ <int key="NSTableViewGroupRowStyle">1</int>
+ </object>
+ </array>
+ <string key="NSFrame">{{1, 17}, {177, 267}}</string>
+ <reference key="NSSuperview" ref="416538861"/>
+ <reference key="NSNextKeyView" ref="209939006"/>
+ <reference key="NSDocView" ref="209939006"/>
+ <reference key="NSBGColor" ref="791991748"/>
+ <int key="NScvFlags">4</int>
+ </object>
+ <object class="NSScroller" id="548447063">
+ <reference key="NSNextResponder" ref="416538861"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrame">{{178, 17}, {15, 267}}</string>
+ <reference key="NSSuperview" ref="416538861"/>
+ <reference key="NSTarget" ref="416538861"/>
+ <string key="NSAction">_doScroller:</string>
+ <double key="NSPercent">0.95789474248886108</double>
+ </object>
+ <object class="NSScroller" id="128836592">
+ <reference key="NSNextResponder" ref="416538861"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrame">{{-100, -100}, {177, 15}}</string>
+ <reference key="NSSuperview" ref="416538861"/>
+ <int key="NSsFlags">1</int>
+ <reference key="NSTarget" ref="416538861"/>
+ <string key="NSAction">_doScroller:</string>
+ <double key="NSPercent">0.99047619104385376</double>
+ </object>
+ <object class="NSClipView" id="226206000">
+ <reference key="NSNextResponder" ref="416538861"/>
+ <int key="NSvFlags">2304</int>
+ <array class="NSMutableArray" key="NSSubviews">
+ <reference ref="644754426"/>
+ </array>
+ <string key="NSFrame">{{1, 0}, {177, 17}}</string>
+ <reference key="NSSuperview" ref="416538861"/>
+ <reference key="NSNextKeyView" ref="644754426"/>
+ <reference key="NSDocView" ref="644754426"/>
+ <reference key="NSBGColor" ref="791991748"/>
+ <int key="NScvFlags">4</int>
+ </object>
+ <reference ref="694675632"/>
+ </array>
+ <string key="NSFrame">{{74, 20}, {194, 285}}</string>
+ <reference key="NSSuperview" ref="639734842"/>
+ <reference key="NSNextKeyView" ref="578574056"/>
+ <int key="NSsFlags">133138</int>
+ <reference key="NSVScroller" ref="548447063"/>
+ <reference key="NSHScroller" ref="128836592"/>
+ <reference key="NSContentView" ref="578574056"/>
+ <reference key="NSHeaderClipView" ref="226206000"/>
+ <bytes key="NSScrollAmts">QSAAAEEgAABBmAAAQZgAAA</bytes>
+ </object>
+ <object class="NSBox" id="737187669">
+ <reference key="NSNextResponder" ref="639734842"/>
+ <int key="NSvFlags">266</int>
+ <string key="NSFrame">{{12, 361}, {459, 5}}</string>
+ <reference key="NSSuperview" ref="639734842"/>
+ <string key="NSOffsets">{0, 0}</string>
+ <object class="NSTextFieldCell" key="NSTitleCell">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">0</int>
+ <string key="NSContents">Box</string>
+ <reference key="NSSupport" ref="11966484"/>
+ <reference key="NSBackgroundColor" ref="147273098"/>
+ <object class="NSColor" key="NSTextColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MCAwLjgwMDAwMDAxAA</bytes>
+ </object>
+ </object>
+ <int key="NSBorderType">3</int>
+ <int key="NSBoxType">2</int>
+ <int key="NSTitlePosition">0</int>
+ <bool key="NSTransparent">NO</bool>
+ </object>
+ <object class="NSLevelIndicator" id="152294097">
+ <reference key="NSNextResponder" ref="639734842"/>
+ <int key="NSvFlags">266</int>
+ <string key="NSFrame">{{74, 337}, {389, 16}}</string>
+ <reference key="NSSuperview" ref="639734842"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSLevelIndicatorCell" key="NSCell" id="688209869">
+ <int key="NSCellFlags">130560</int>
+ <int key="NSCellFlags2">0</int>
+ <reference key="NSControlView" ref="152294097"/>
+ <double key="NSMinValue">-32768</double>
+ <double key="NSMaxValue">32768</double>
+ <int key="NSIndicatorStyle">1</int>
+ </object>
+ </object>
+ <object class="NSLevelIndicator" id="507655026">
+ <reference key="NSNextResponder" ref="639734842"/>
+ <int key="NSvFlags">266</int>
+ <string key="NSFrame">{{74, 313}, {389, 16}}</string>
+ <reference key="NSSuperview" ref="639734842"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSLevelIndicatorCell" key="NSCell" id="191024010">
+ <int key="NSCellFlags">130560</int>
+ <int key="NSCellFlags2">0</int>
+ <reference key="NSControlView" ref="507655026"/>
+ <double key="NSMinValue">-32768</double>
+ <double key="NSMaxValue">32768</double>
+ <int key="NSIndicatorStyle">1</int>
+ </object>
+ </object>
+ <object class="NSTextField" id="1035429346">
+ <reference key="NSNextResponder" ref="639734842"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{17, 337}, {52, 17}}</string>
+ <reference key="NSSuperview" ref="639734842"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="678112624">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">272629760</int>
+ <string key="NSContents">X-Axis:</string>
+ <reference key="NSSupport" ref="11966484"/>
+ <reference key="NSControlView" ref="1035429346"/>
+ <reference key="NSBackgroundColor" ref="520461807"/>
+ <reference key="NSTextColor" ref="309990206"/>
+ </object>
+ </object>
+ <object class="NSTextField" id="299566195">
+ <reference key="NSNextResponder" ref="639734842"/>
+ <int key="NSvFlags">268</int>
+ <string key="NSFrame">{{17, 313}, {52, 17}}</string>
+ <reference key="NSSuperview" ref="639734842"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="760716940">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">272629760</int>
+ <string key="NSContents">Y-Axis:</string>
+ <reference key="NSSupport" ref="11966484"/>
+ <reference key="NSControlView" ref="299566195"/>
+ <reference key="NSBackgroundColor" ref="520461807"/>
+ <reference key="NSTextColor" ref="309990206"/>
+ </object>
+ </object>
+ </array>
+ <string key="NSFrame">{{10, 33}, {483, 437}}</string>
+ </object>
+ <string key="NSLabel">Joysticks</string>
+ <reference key="NSColor" ref="520461807"/>
+ <reference key="NSTabView" ref="644721648"/>
+ </object>
+ <object class="NSTabViewItem" id="805145155">
+ <object class="NSView" key="NSView" id="425526148">
+ <nil key="NSNextResponder"/>
+ <int key="NSvFlags">256</int>
+ <array class="NSMutableArray" key="NSSubviews">
+ <object class="NSPopUpButton" id="801273994">
+ <reference key="NSNextResponder" ref="425526148"/>
+ <int key="NSvFlags">266</int>
+ <string key="NSFrame">{{87, 393}, {379, 26}}</string>
+ <reference key="NSSuperview" ref="425526148"/>
+ <reference key="NSNextKeyView" ref="936527210"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSPopUpButtonCell" key="NSCell" id="124405559">
+ <int key="NSCellFlags">-2076049856</int>
+ <int key="NSCellFlags2">2048</int>
+ <reference key="NSSupport" ref="11966484"/>
+ <reference key="NSControlView" ref="801273994"/>
+ <int key="NSButtonFlags">109199615</int>
+ <int key="NSButtonFlags2">1</int>
+ <reference key="NSAlternateImage" ref="121555804"/>
+ <string key="NSAlternateContents"/>
+ <object class="NSMutableString" key="NSKeyEquivalent">
+ <characters key="NS.bytes"/>
+ </object>
+ <int key="NSPeriodicDelay">400</int>
+ <int key="NSPeriodicInterval">75</int>
+ <object class="NSMenuItem" key="NSMenuItem" id="296793368">
+ <reference key="NSMenu" ref="17814120"/>
+ <string key="NSTitle">Item1</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <int key="NSState">1</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ <string key="NSAction">_popUpItemAction:</string>
+ <reference key="NSTarget" ref="124405559"/>
+ </object>
+ <bool key="NSMenuItemRespectAlignment">YES</bool>
+ <object class="NSMenu" key="NSMenu" id="17814120">
+ <object class="NSMutableString" key="NSTitle">
+ <characters key="NS.bytes">OtherViews</characters>
+ </object>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <reference ref="296793368"/>
+ <object class="NSMenuItem" id="882835994">
+ <reference key="NSMenu" ref="17814120"/>
+ <string key="NSTitle">Item2</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ <string key="NSAction">_popUpItemAction:</string>
+ <reference key="NSTarget" ref="124405559"/>
+ </object>
+ <object class="NSMenuItem" id="157934231">
+ <reference key="NSMenu" ref="17814120"/>
+ <string key="NSTitle">Item3</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ <string key="NSAction">_popUpItemAction:</string>
+ <reference key="NSTarget" ref="124405559"/>
+ </object>
+ </array>
+ </object>
+ <int key="NSPreferredEdge">3</int>
+ <bool key="NSUsesItemFromMenu">YES</bool>
+ <bool key="NSAltersState">YES</bool>
+ <int key="NSArrowPosition">1</int>
+ </object>
+ </object>
+ <object class="NSTextField" id="821770352">
+ <reference key="NSNextResponder" ref="425526148"/>
+ <int key="NSvFlags">264</int>
+ <string key="NSFrame">{{17, 399}, {68, 17}}</string>
+ <reference key="NSSuperview" ref="425526148"/>
+ <reference key="NSNextKeyView" ref="801273994"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="635585675">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">272629760</int>
+ <string key="NSContents">Keyboard:</string>
+ <reference key="NSSupport" ref="11966484"/>
+ <reference key="NSControlView" ref="821770352"/>
+ <reference key="NSBackgroundColor" ref="520461807"/>
+ <reference key="NSTextColor" ref="309990206"/>
+ </object>
+ </object>
+ <object class="NSTextField" id="846710279">
+ <reference key="NSNextResponder" ref="425526148"/>
+ <int key="NSvFlags">266</int>
+ <string key="NSFrame">{{112, 372}, {354, 17}}</string>
+ <reference key="NSSuperview" ref="425526148"/>
+ <reference key="NSNextKeyView" ref="293480414"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="271966601">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">272629760</int>
+ <string key="NSContents">System Font Text</string>
+ <reference key="NSSupport" ref="11966484"/>
+ <reference key="NSControlView" ref="846710279"/>
+ <reference key="NSBackgroundColor" ref="520461807"/>
+ <reference key="NSTextColor" ref="309990206"/>
+ </object>
+ </object>
+ <object class="NSTextField" id="936527210">
+ <reference key="NSNextResponder" ref="425526148"/>
+ <int key="NSvFlags">264</int>
+ <string key="NSFrame">{{17, 372}, {93, 17}}</string>
+ <reference key="NSSuperview" ref="425526148"/>
+ <reference key="NSNextKeyView" ref="846710279"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="600387788">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">272629760</int>
+ <string key="NSContents">Manufacturer:</string>
+ <reference key="NSSupport" ref="11966484"/>
+ <reference key="NSControlView" ref="936527210"/>
+ <reference key="NSBackgroundColor" ref="520461807"/>
+ <reference key="NSTextColor" ref="309990206"/>
+ </object>
+ </object>
+ <object class="NSBox" id="293480414">
+ <reference key="NSNextResponder" ref="425526148"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrame">{{12, 361}, {459, 5}}</string>
+ <reference key="NSSuperview" ref="425526148"/>
+ <reference key="NSNextKeyView" ref="352565696"/>
+ <string key="NSOffsets">{0, 0}</string>
+ <object class="NSTextFieldCell" key="NSTitleCell">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">0</int>
+ <string key="NSContents">Box</string>
+ <reference key="NSSupport" ref="11966484"/>
+ <reference key="NSBackgroundColor" ref="147273098"/>
+ <object class="NSColor" key="NSTextColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MCAwLjgwMDAwMDAxAA</bytes>
+ </object>
+ </object>
+ <int key="NSBorderType">3</int>
+ <int key="NSBoxType">2</int>
+ <int key="NSTitlePosition">0</int>
+ <bool key="NSTransparent">NO</bool>
+ </object>
+ <object class="NSScrollView" id="352565696">
+ <reference key="NSNextResponder" ref="425526148"/>
+ <int key="NSvFlags">256</int>
+ <array class="NSMutableArray" key="NSSubviews">
+ <object class="NSClipView" id="243217988">
+ <reference key="NSNextResponder" ref="352565696"/>
+ <int key="NSvFlags">2304</int>
+ <array class="NSMutableArray" key="NSSubviews">
+ <object class="NSTableView" id="1058080016">
+ <reference key="NSNextResponder" ref="243217988"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrameSize">{426, 333}</string>
+ <reference key="NSSuperview" ref="243217988"/>
+ <reference key="NSNextKeyView" ref="899917373"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="_NSCornerView" key="NSCornerView">
+ <nil key="NSNextResponder"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrame">{{427, 0}, {16, 17}}</string>
+ </object>
+ <array class="NSMutableArray" key="NSTableColumns">
+ <object class="NSTableColumn" id="104560874">
+ <double key="NSWidth">94</double>
+ <double key="NSMinWidth">40</double>
+ <double key="NSMaxWidth">1000</double>
+ <object class="NSTableHeaderCell" key="NSHeaderCell">
+ <int key="NSCellFlags">75628096</int>
+ <int key="NSCellFlags2">2048</int>
+ <string key="NSContents"/>
+ <reference key="NSSupport" ref="26"/>
+ <object class="NSColor" key="NSBackgroundColor" id="73149108">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MC4zMzMzMzI5OQA</bytes>
+ </object>
+ <reference key="NSTextColor" ref="906593754"/>
+ </object>
+ <object class="NSTextFieldCell" key="NSDataCell" id="493334896">
+ <int key="NSCellFlags">337772096</int>
+ <int key="NSCellFlags2">2048</int>
+ <reference key="NSSupport" ref="11966484"/>
+ <reference key="NSControlView" ref="1058080016"/>
+ <reference key="NSBackgroundColor" ref="791991748"/>
+ <reference key="NSTextColor" ref="309990206"/>
+ </object>
+ <int key="NSResizingMask">3</int>
+ <bool key="NSIsResizeable">YES</bool>
+ <bool key="NSIsEditable">YES</bool>
+ <reference key="NSTableView" ref="1058080016"/>
+ </object>
+ <object class="NSTableColumn" id="25394885">
+ <double key="NSWidth">326</double>
+ <double key="NSMinWidth">40</double>
+ <double key="NSMaxWidth">1000</double>
+ <object class="NSTableHeaderCell" key="NSHeaderCell">
+ <int key="NSCellFlags">75628096</int>
+ <int key="NSCellFlags2">2048</int>
+ <string key="NSContents"/>
+ <reference key="NSSupport" ref="26"/>
+ <reference key="NSBackgroundColor" ref="73149108"/>
+ <reference key="NSTextColor" ref="906593754"/>
+ </object>
+ <object class="NSTextFieldCell" key="NSDataCell" id="376526475">
+ <int key="NSCellFlags">337772096</int>
+ <int key="NSCellFlags2">2048</int>
+ <reference key="NSSupport" ref="11966484"/>
+ <reference key="NSControlView" ref="1058080016"/>
+ <reference key="NSBackgroundColor" ref="791991748"/>
+ <reference key="NSTextColor" ref="309990206"/>
+ </object>
+ <int key="NSResizingMask">3</int>
+ <bool key="NSIsResizeable">YES</bool>
+ <bool key="NSIsEditable">YES</bool>
+ <reference key="NSTableView" ref="1058080016"/>
+ </object>
+ </array>
+ <double key="NSIntercellSpacingWidth">3</double>
+ <double key="NSIntercellSpacingHeight">2</double>
+ <reference key="NSBackgroundColor" ref="991614945"/>
+ <reference key="NSGridColor" ref="155750304"/>
+ <double key="NSRowHeight">17</double>
+ <int key="NSTvFlags">306184192</int>
+ <reference key="NSDelegate"/>
+ <reference key="NSDataSource"/>
+ <int key="NSColumnAutoresizingStyle">4</int>
+ <int key="NSDraggingSourceMaskForLocal">15</int>
+ <int key="NSDraggingSourceMaskForNonLocal">0</int>
+ <bool key="NSAllowsTypeSelect">YES</bool>
+ <int key="NSTableViewDraggingDestinationStyle">0</int>
+ <int key="NSTableViewGroupRowStyle">1</int>
+ </object>
+ </array>
+ <string key="NSFrame">{{1, 1}, {426, 333}}</string>
+ <reference key="NSSuperview" ref="352565696"/>
+ <reference key="NSNextKeyView" ref="1058080016"/>
+ <reference key="NSDocView" ref="1058080016"/>
+ <reference key="NSBGColor" ref="791991748"/>
+ <int key="NScvFlags">4</int>
+ </object>
+ <object class="NSScroller" id="899917373">
+ <reference key="NSNextResponder" ref="352565696"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrame">{{427, 1}, {15, 333}}</string>
+ <reference key="NSSuperview" ref="352565696"/>
+ <reference key="NSNextKeyView"/>
+ <reference key="NSTarget" ref="352565696"/>
+ <string key="NSAction">_doScroller:</string>
+ <double key="NSPercent">0.96315789222717285</double>
+ </object>
+ <object class="NSScroller" id="626352804">
+ <reference key="NSNextResponder" ref="352565696"/>
+ <int key="NSvFlags">-2147483392</int>
+ <string key="NSFrame">{{-100, -100}, {426, 15}}</string>
+ <reference key="NSSuperview" ref="352565696"/>
+ <reference key="NSNextKeyView" ref="243217988"/>
+ <int key="NSsFlags">1</int>
+ <reference key="NSTarget" ref="352565696"/>
+ <string key="NSAction">_doScroller:</string>
+ <double key="NSPercent">0.99047619104385376</double>
+ </object>
+ </array>
+ <string key="NSFrame">{{20, 20}, {443, 335}}</string>
+ <reference key="NSSuperview" ref="425526148"/>
+ <reference key="NSNextKeyView" ref="626352804"/>
+ <int key="NSsFlags">133138</int>
+ <reference key="NSVScroller" ref="899917373"/>
+ <reference key="NSHScroller" ref="626352804"/>
+ <reference key="NSContentView" ref="243217988"/>
+ <bytes key="NSScrollAmts">QSAAAEEgAABBmAAAQZgAAA</bytes>
+ </object>
+ </array>
+ <string key="NSFrame">{{10, 33}, {483, 437}}</string>
+ <reference key="NSNextKeyView" ref="821770352"/>
+ </object>
+ <string key="NSLabel">Keyboards</string>
+ <reference key="NSColor" ref="520461807"/>
+ <reference key="NSTabView" ref="644721648"/>
+ </object>
+ <object class="NSTabViewItem" id="206151473">
+ <object class="NSView" key="NSView" id="103723724">
+ <nil key="NSNextResponder"/>
+ <int key="NSvFlags">256</int>
+ <array class="NSMutableArray" key="NSSubviews">
+ <object class="NSCustomView" id="279154427">
+ <reference key="NSNextResponder" ref="103723724"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrame">{{188, 137}, {107, 280}}</string>
+ <reference key="NSSuperview" ref="103723724"/>
+ <reference key="NSNextKeyView" ref="682296781"/>
+ <string key="NSClassName">RemoteFeedbackView</string>
+ <string key="NSExtension">NSView</string>
+ </object>
+ <object class="NSButton" id="927927578">
+ <reference key="NSNextResponder" ref="103723724"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrame">{{176, 67}, {131, 32}}</string>
+ <reference key="NSSuperview" ref="103723724"/>
+ <reference key="NSNextKeyView" ref="1042890665"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSButtonCell" key="NSCell" id="625781673">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">134217728</int>
+ <string key="NSContents">Start Listening</string>
+ <reference key="NSSupport" ref="11966484"/>
+ <reference key="NSControlView" ref="927927578"/>
+ <int key="NSButtonFlags">-2038284033</int>
+ <int key="NSButtonFlags2">1</int>
+ <reference key="NSAlternateImage" ref="11966484"/>
+ <string key="NSAlternateContents"/>
+ <object class="NSMutableString" key="NSKeyEquivalent">
+ <characters key="NS.bytes"/>
+ </object>
+ <int key="NSPeriodicDelay">200</int>
+ <int key="NSPeriodicInterval">25</int>
+ </object>
+ </object>
+ <object class="NSButton" id="1042890665">
+ <reference key="NSNextResponder" ref="103723724"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrame">{{165, 39}, {151, 18}}</string>
+ <reference key="NSSuperview" ref="103723724"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSButtonCell" key="NSCell" id="113061213">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">131072</int>
+ <string key="NSContents">Open in exclusive mode</string>
+ <reference key="NSSupport" ref="26"/>
+ <reference key="NSControlView" ref="1042890665"/>
+ <int key="NSButtonFlags">1211912703</int>
+ <int key="NSButtonFlags2">2</int>
+ <object class="NSButtonImageSource" key="NSAlternateImage">
+ <string key="NSImageName">NSSwitch</string>
+ </object>
+ <string key="NSAlternateContents"/>
+ <string key="NSKeyEquivalent"/>
+ <int key="NSPeriodicDelay">200</int>
+ <int key="NSPeriodicInterval">25</int>
+ </object>
+ </object>
+ <object class="NSTextField" id="682296781">
+ <reference key="NSNextResponder" ref="103723724"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrame">{{165, 115}, {152, 14}}</string>
+ <reference key="NSSuperview" ref="103723724"/>
+ <reference key="NSNextKeyView" ref="927927578"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="1014225370">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">138543104</int>
+ <string key="NSContents">-</string>
+ <reference key="NSSupport" ref="26"/>
+ <reference key="NSControlView" ref="682296781"/>
+ <reference key="NSBackgroundColor" ref="520461807"/>
+ <reference key="NSTextColor" ref="309990206"/>
+ </object>
+ </object>
+ <object class="NSTextField" id="80389755">
+ <reference key="NSNextResponder" ref="103723724"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrame">{{194, 423}, {63, 14}}</string>
+ <reference key="NSSuperview" ref="103723724"/>
+ <reference key="NSNextKeyView" ref="179085848"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="357183005">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">272629760</int>
+ <string key="NSContents">Remote ID:</string>
+ <reference key="NSSupport" ref="26"/>
+ <reference key="NSControlView" ref="80389755"/>
+ <reference key="NSBackgroundColor" ref="520461807"/>
+ <reference key="NSTextColor" ref="309990206"/>
+ </object>
+ </object>
+ <object class="NSTextField" id="179085848">
+ <reference key="NSNextResponder" ref="103723724"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrame">{{259, 423}, {32, 14}}</string>
+ <reference key="NSSuperview" ref="103723724"/>
+ <reference key="NSNextKeyView" ref="279154427"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="319211686">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">272629760</int>
+ <string key="NSContents">9999</string>
+ <reference key="NSSupport" ref="26"/>
+ <reference key="NSControlView" ref="179085848"/>
+ <reference key="NSBackgroundColor" ref="520461807"/>
+ <reference key="NSTextColor" ref="309990206"/>
+ </object>
+ </object>
+ </array>
+ <string key="NSFrame">{{10, 33}, {483, 437}}</string>
+ <reference key="NSNextKeyView" ref="80389755"/>
+ </object>
+ <string key="NSLabel">Remote</string>
+ <reference key="NSColor" ref="520461807"/>
+ <reference key="NSTabView" ref="644721648"/>
+ </object>
+ <object class="NSTabViewItem" id="341515874">
+ <object class="NSView" key="NSView" id="348322794">
+ <reference key="NSNextResponder" ref="644721648"/>
+ <int key="NSvFlags">256</int>
+ <array class="NSMutableArray" key="NSSubviews">
+ <object class="NSPopUpButton" id="198711655">
+ <reference key="NSNextResponder" ref="348322794"/>
+ <int key="NSvFlags">266</int>
+ <string key="NSFrame">{{87, 393}, {379, 26}}</string>
+ <reference key="NSSuperview" ref="348322794"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="417902156"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSPopUpButtonCell" key="NSCell" id="646203599">
+ <int key="NSCellFlags">-2076049856</int>
+ <int key="NSCellFlags2">2048</int>
+ <reference key="NSSupport" ref="11966484"/>
+ <reference key="NSControlView" ref="198711655"/>
+ <int key="NSButtonFlags">109199615</int>
+ <int key="NSButtonFlags2">1</int>
+ <reference key="NSAlternateImage" ref="121555804"/>
+ <string key="NSAlternateContents"/>
+ <object class="NSMutableString" key="NSKeyEquivalent">
+ <characters key="NS.bytes"/>
+ </object>
+ <int key="NSPeriodicDelay">400</int>
+ <int key="NSPeriodicInterval">75</int>
+ <object class="NSMenuItem" key="NSMenuItem" id="209592817">
+ <reference key="NSMenu" ref="1033926023"/>
+ <string key="NSTitle">Item1</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <int key="NSState">1</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ <string key="NSAction">_popUpItemAction:</string>
+ <reference key="NSTarget" ref="646203599"/>
+ </object>
+ <bool key="NSMenuItemRespectAlignment">YES</bool>
+ <object class="NSMenu" key="NSMenu" id="1033926023">
+ <object class="NSMutableString" key="NSTitle">
+ <characters key="NS.bytes">OtherViews</characters>
+ </object>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <reference ref="209592817"/>
+ <object class="NSMenuItem" id="799967634">
+ <reference key="NSMenu" ref="1033926023"/>
+ <string key="NSTitle">Item2</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ <string key="NSAction">_popUpItemAction:</string>
+ <reference key="NSTarget" ref="646203599"/>
+ </object>
+ <object class="NSMenuItem" id="1019206975">
+ <reference key="NSMenu" ref="1033926023"/>
+ <string key="NSTitle">Item3</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ <string key="NSAction">_popUpItemAction:</string>
+ <reference key="NSTarget" ref="646203599"/>
+ </object>
+ </array>
+ </object>
+ <int key="NSPreferredEdge">3</int>
+ <bool key="NSUsesItemFromMenu">YES</bool>
+ <bool key="NSAltersState">YES</bool>
+ <int key="NSArrowPosition">1</int>
+ </object>
+ </object>
+ <object class="NSTextField" id="533537148">
+ <reference key="NSNextResponder" ref="348322794"/>
+ <int key="NSvFlags">264</int>
+ <string key="NSFrame">{{17, 399}, {41, 17}}</string>
+ <reference key="NSSuperview" ref="348322794"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="198711655"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="1028846042">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">272629760</int>
+ <string key="NSContents">Mikey</string>
+ <reference key="NSSupport" ref="11966484"/>
+ <reference key="NSControlView" ref="533537148"/>
+ <reference key="NSBackgroundColor" ref="520461807"/>
+ <reference key="NSTextColor" ref="309990206"/>
+ </object>
+ </object>
+ <object class="NSTextField" id="775775215">
+ <reference key="NSNextResponder" ref="348322794"/>
+ <int key="NSvFlags">266</int>
+ <string key="NSFrame">{{112, 372}, {354, 17}}</string>
+ <reference key="NSSuperview" ref="348322794"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="648226226"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="60166265">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">272629760</int>
+ <string key="NSContents">System Font Text</string>
+ <reference key="NSSupport" ref="11966484"/>
+ <reference key="NSControlView" ref="775775215"/>
+ <reference key="NSBackgroundColor" ref="520461807"/>
+ <reference key="NSTextColor" ref="309990206"/>
+ </object>
+ </object>
+ <object class="NSTextField" id="417902156">
+ <reference key="NSNextResponder" ref="348322794"/>
+ <int key="NSvFlags">264</int>
+ <string key="NSFrame">{{17, 372}, {93, 17}}</string>
+ <reference key="NSSuperview" ref="348322794"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="775775215"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSTextFieldCell" key="NSCell" id="839783436">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">272629760</int>
+ <string key="NSContents">Manufacturer:</string>
+ <reference key="NSSupport" ref="11966484"/>
+ <reference key="NSControlView" ref="417902156"/>
+ <reference key="NSBackgroundColor" ref="520461807"/>
+ <reference key="NSTextColor" ref="309990206"/>
+ </object>
+ </object>
+ <object class="NSBox" id="648226226">
+ <reference key="NSNextResponder" ref="348322794"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrame">{{12, 361}, {459, 5}}</string>
+ <reference key="NSSuperview" ref="348322794"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="969348819"/>
+ <string key="NSOffsets">{0, 0}</string>
+ <object class="NSTextFieldCell" key="NSTitleCell">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">0</int>
+ <string key="NSContents">Box</string>
+ <reference key="NSSupport" ref="11966484"/>
+ <reference key="NSBackgroundColor" ref="147273098"/>
+ <object class="NSColor" key="NSTextColor">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MCAwLjgwMDAwMDAxAA</bytes>
+ </object>
+ </object>
+ <int key="NSBorderType">3</int>
+ <int key="NSBoxType">2</int>
+ <int key="NSTitlePosition">0</int>
+ <bool key="NSTransparent">NO</bool>
+ </object>
+ <object class="NSScrollView" id="969348819">
+ <reference key="NSNextResponder" ref="348322794"/>
+ <int key="NSvFlags">256</int>
+ <array class="NSMutableArray" key="NSSubviews">
+ <object class="NSClipView" id="1062920427">
+ <reference key="NSNextResponder" ref="969348819"/>
+ <int key="NSvFlags">2304</int>
+ <array class="NSMutableArray" key="NSSubviews">
+ <object class="NSTableView" id="6762116">
+ <reference key="NSNextResponder" ref="1062920427"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrameSize">{426, 333}</string>
+ <reference key="NSSuperview" ref="1062920427"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="524946031"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="_NSCornerView" key="NSCornerView">
+ <nil key="NSNextResponder"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrame">{{427, 0}, {16, 17}}</string>
+ </object>
+ <array class="NSMutableArray" key="NSTableColumns">
+ <object class="NSTableColumn" id="1010687613">
+ <double key="NSWidth">94</double>
+ <double key="NSMinWidth">40</double>
+ <double key="NSMaxWidth">1000</double>
+ <object class="NSTableHeaderCell" key="NSHeaderCell">
+ <int key="NSCellFlags">75628096</int>
+ <int key="NSCellFlags2">2048</int>
+ <string key="NSContents"/>
+ <reference key="NSSupport" ref="26"/>
+ <object class="NSColor" key="NSBackgroundColor" id="785507273">
+ <int key="NSColorSpace">3</int>
+ <bytes key="NSWhite">MC4zMzMzMzI5OQA</bytes>
+ </object>
+ <reference key="NSTextColor" ref="906593754"/>
+ </object>
+ <object class="NSTextFieldCell" key="NSDataCell" id="373004376">
+ <int key="NSCellFlags">337772096</int>
+ <int key="NSCellFlags2">2048</int>
+ <reference key="NSSupport" ref="11966484"/>
+ <reference key="NSControlView" ref="6762116"/>
+ <reference key="NSBackgroundColor" ref="791991748"/>
+ <reference key="NSTextColor" ref="309990206"/>
+ </object>
+ <int key="NSResizingMask">3</int>
+ <bool key="NSIsResizeable">YES</bool>
+ <bool key="NSIsEditable">YES</bool>
+ <reference key="NSTableView" ref="6762116"/>
+ </object>
+ <object class="NSTableColumn" id="762433403">
+ <double key="NSWidth">326</double>
+ <double key="NSMinWidth">40</double>
+ <double key="NSMaxWidth">1000</double>
+ <object class="NSTableHeaderCell" key="NSHeaderCell">
+ <int key="NSCellFlags">75628096</int>
+ <int key="NSCellFlags2">2048</int>
+ <string key="NSContents"/>
+ <reference key="NSSupport" ref="26"/>
+ <reference key="NSBackgroundColor" ref="785507273"/>
+ <reference key="NSTextColor" ref="906593754"/>
+ </object>
+ <object class="NSTextFieldCell" key="NSDataCell" id="258874923">
+ <int key="NSCellFlags">337772096</int>
+ <int key="NSCellFlags2">2048</int>
+ <reference key="NSSupport" ref="11966484"/>
+ <reference key="NSControlView" ref="6762116"/>
+ <reference key="NSBackgroundColor" ref="791991748"/>
+ <reference key="NSTextColor" ref="309990206"/>
+ </object>
+ <int key="NSResizingMask">3</int>
+ <bool key="NSIsResizeable">YES</bool>
+ <bool key="NSIsEditable">YES</bool>
+ <reference key="NSTableView" ref="6762116"/>
+ </object>
+ </array>
+ <double key="NSIntercellSpacingWidth">3</double>
+ <double key="NSIntercellSpacingHeight">2</double>
+ <reference key="NSBackgroundColor" ref="991614945"/>
+ <reference key="NSGridColor" ref="155750304"/>
+ <double key="NSRowHeight">17</double>
+ <int key="NSTvFlags">306184192</int>
+ <reference key="NSDelegate"/>
+ <reference key="NSDataSource"/>
+ <int key="NSColumnAutoresizingStyle">4</int>
+ <int key="NSDraggingSourceMaskForLocal">15</int>
+ <int key="NSDraggingSourceMaskForNonLocal">0</int>
+ <bool key="NSAllowsTypeSelect">YES</bool>
+ <int key="NSTableViewDraggingDestinationStyle">0</int>
+ <int key="NSTableViewGroupRowStyle">1</int>
+ </object>
+ </array>
+ <string key="NSFrame">{{1, 1}, {426, 333}}</string>
+ <reference key="NSSuperview" ref="969348819"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="6762116"/>
+ <reference key="NSDocView" ref="6762116"/>
+ <reference key="NSBGColor" ref="791991748"/>
+ <int key="NScvFlags">4</int>
+ </object>
+ <object class="NSScroller" id="524946031">
+ <reference key="NSNextResponder" ref="969348819"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrame">{{427, 1}, {15, 333}}</string>
+ <reference key="NSSuperview" ref="969348819"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView"/>
+ <reference key="NSTarget" ref="969348819"/>
+ <string key="NSAction">_doScroller:</string>
+ <double key="NSPercent">0.96315789222717285</double>
+ </object>
+ <object class="NSScroller" id="388049267">
+ <reference key="NSNextResponder" ref="969348819"/>
+ <int key="NSvFlags">-2147483392</int>
+ <string key="NSFrame">{{-100, -100}, {426, 15}}</string>
+ <reference key="NSSuperview" ref="969348819"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="1062920427"/>
+ <int key="NSsFlags">1</int>
+ <reference key="NSTarget" ref="969348819"/>
+ <string key="NSAction">_doScroller:</string>
+ <double key="NSPercent">0.99047619104385376</double>
+ </object>
+ </array>
+ <string key="NSFrame">{{20, 20}, {443, 335}}</string>
+ <reference key="NSSuperview" ref="348322794"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="388049267"/>
+ <int key="NSsFlags">133138</int>
+ <reference key="NSVScroller" ref="524946031"/>
+ <reference key="NSHScroller" ref="388049267"/>
+ <reference key="NSContentView" ref="1062920427"/>
+ <bytes key="NSScrollAmts">QSAAAEEgAABBmAAAQZgAAA</bytes>
+ </object>
+ </array>
+ <string key="NSFrame">{{10, 33}, {483, 437}}</string>
+ <reference key="NSSuperview" ref="644721648"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="533537148"/>
+ </object>
+ <string key="NSLabel">Mikeys</string>
+ <reference key="NSColor" ref="520461807"/>
+ <reference key="NSTabView" ref="644721648"/>
+ </object>
+ </array>
+ <reference key="NSSelectedTabViewItem" ref="341515874"/>
+ <reference key="NSFont" ref="11966484"/>
+ <int key="NSTvFlags">0</int>
+ <bool key="NSAllowTruncatedLabels">YES</bool>
+ <bool key="NSDrawsBackground">YES</bool>
+ <array class="NSMutableArray" key="NSSubviews">
+ <reference ref="348322794"/>
+ </array>
+ </object>
+ </array>
+ <string key="NSFrameSize">{529, 499}</string>
+ <reference key="NSSuperview"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView" ref="644721648"/>
+ </object>
+ <string key="NSScreenRect">{{0, 0}, {1920, 1178}}</string>
+ <string key="NSMinSize">{213, 129}</string>
+ <string key="NSMaxSize">{10000000000000, 10000000000000}</string>
+ <bool key="NSWindowIsRestorable">YES</bool>
+ </object>
+ <object class="NSMenu" id="985818309">
+ <string key="NSTitle">MainMenu</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="718640928">
+ <reference key="NSMenu" ref="985818309"/>
+ <string key="NSTitle">HIDDeviceTest</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="334835152">
+ <string key="NSTitle">HIDDeviceTest</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="824448059">
+ <reference key="NSMenu" ref="334835152"/>
+ <string key="NSTitle">About HIDDeviceTest</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="164663327">
+ <reference key="NSMenu" ref="334835152"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="441187593">
+ <reference key="NSMenu" ref="334835152"/>
+ <string key="NSTitle">Preferences…</string>
+ <string key="NSKeyEquiv">,</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="516492413">
+ <reference key="NSMenu" ref="334835152"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="75425932">
+ <reference key="NSMenu" ref="334835152"/>
+ <string key="NSTitle">Services</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="718887502">
+ <object class="NSMutableString" key="NSTitle">
+ <characters key="NS.bytes">Services</characters>
+ </object>
+ <array class="NSMutableArray" key="NSMenuItems"/>
+ <string key="NSName">_NSServicesMenu</string>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="740657299">
+ <reference key="NSMenu" ref="334835152"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="924050144">
+ <reference key="NSMenu" ref="334835152"/>
+ <string key="NSTitle">Hide HIDDeviceTest</string>
+ <string key="NSKeyEquiv">h</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="640088582">
+ <reference key="NSMenu" ref="334835152"/>
+ <string key="NSTitle">Hide Others</string>
+ <string key="NSKeyEquiv">h</string>
+ <int key="NSKeyEquivModMask">1572864</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="103269932">
+ <reference key="NSMenu" ref="334835152"/>
+ <string key="NSTitle">Show All</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="1035629316">
+ <reference key="NSMenu" ref="334835152"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="1061266757">
+ <reference key="NSMenu" ref="334835152"/>
+ <string key="NSTitle">Quit HIDDeviceTest</string>
+ <string key="NSKeyEquiv">q</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ </array>
+ <string key="NSName">_NSAppleMenu</string>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="141310426">
+ <reference key="NSMenu" ref="985818309"/>
+ <string key="NSTitle">File</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="946423102">
+ <object class="NSMutableString" key="NSTitle">
+ <characters key="NS.bytes">File</characters>
+ </object>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="395391345">
+ <reference key="NSMenu" ref="946423102"/>
+ <string key="NSTitle">New</string>
+ <string key="NSKeyEquiv">n</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="739670817">
+ <reference key="NSMenu" ref="946423102"/>
+ <string key="NSTitle">Open…</string>
+ <string key="NSKeyEquiv">o</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="272198838">
+ <reference key="NSMenu" ref="946423102"/>
+ <string key="NSTitle">Open Recent</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="606750118">
+ <object class="NSMutableString" key="NSTitle">
+ <characters key="NS.bytes">Open Recent</characters>
+ </object>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="430142160">
+ <reference key="NSMenu" ref="606750118"/>
+ <string key="NSTitle">Clear Menu</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ </array>
+ <string key="NSName">_NSRecentDocumentsMenu</string>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="131606599">
+ <reference key="NSMenu" ref="946423102"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="962434548">
+ <reference key="NSMenu" ref="946423102"/>
+ <string key="NSTitle">Close</string>
+ <string key="NSKeyEquiv">w</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="932001322">
+ <reference key="NSMenu" ref="946423102"/>
+ <string key="NSTitle">Save</string>
+ <string key="NSKeyEquiv">s</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="1052462246">
+ <reference key="NSMenu" ref="946423102"/>
+ <string key="NSTitle">Save As…</string>
+ <string key="NSKeyEquiv">S</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="1038775041">
+ <reference key="NSMenu" ref="946423102"/>
+ <string key="NSTitle">Revert</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="1038134261">
+ <reference key="NSMenu" ref="946423102"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="280140765">
+ <reference key="NSMenu" ref="946423102"/>
+ <string key="NSTitle">Page Setup…</string>
+ <string key="NSKeyEquiv">P</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="460995318">
+ <reference key="NSMenu" ref="946423102"/>
+ <string key="NSTitle">Print…</string>
+ <string key="NSKeyEquiv">p</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ </array>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="471057131">
+ <reference key="NSMenu" ref="985818309"/>
+ <string key="NSTitle">Edit</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="883281215">
+ <object class="NSMutableString" key="NSTitle">
+ <characters key="NS.bytes">Edit</characters>
+ </object>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="609227008">
+ <reference key="NSMenu" ref="883281215"/>
+ <string key="NSTitle">Undo</string>
+ <string key="NSKeyEquiv">z</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="64556550">
+ <reference key="NSMenu" ref="883281215"/>
+ <string key="NSTitle">Redo</string>
+ <string key="NSKeyEquiv">Z</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="1030974022">
+ <reference key="NSMenu" ref="883281215"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="89134411">
+ <reference key="NSMenu" ref="883281215"/>
+ <string key="NSTitle">Cut</string>
+ <string key="NSKeyEquiv">x</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="190362399">
+ <reference key="NSMenu" ref="883281215"/>
+ <string key="NSTitle">Copy</string>
+ <string key="NSKeyEquiv">c</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="944061161">
+ <reference key="NSMenu" ref="883281215"/>
+ <string key="NSTitle">Paste</string>
+ <string key="NSKeyEquiv">v</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="586425156">
+ <reference key="NSMenu" ref="883281215"/>
+ <string key="NSTitle">Paste and Match Style</string>
+ <string key="NSKeyEquiv">V</string>
+ <int key="NSKeyEquivModMask">1572864</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="27756945">
+ <reference key="NSMenu" ref="883281215"/>
+ <string key="NSTitle">Delete</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="848176626">
+ <reference key="NSMenu" ref="883281215"/>
+ <string key="NSTitle">Select All</string>
+ <string key="NSKeyEquiv">a</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="872585626">
+ <reference key="NSMenu" ref="883281215"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="613523294">
+ <reference key="NSMenu" ref="883281215"/>
+ <string key="NSTitle">Find</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="1515871">
+ <object class="NSMutableString" key="NSTitle">
+ <characters key="NS.bytes">Find</characters>
+ </object>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="739763715">
+ <reference key="NSMenu" ref="1515871"/>
+ <string key="NSTitle">Find…</string>
+ <string key="NSKeyEquiv">f</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ <int key="NSTag">1</int>
+ </object>
+ <object class="NSMenuItem" id="792228336">
+ <reference key="NSMenu" ref="1515871"/>
+ <string key="NSTitle">Find Next</string>
+ <string key="NSKeyEquiv">g</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ <int key="NSTag">2</int>
+ </object>
+ <object class="NSMenuItem" id="835718921">
+ <reference key="NSMenu" ref="1515871"/>
+ <string key="NSTitle">Find Previous</string>
+ <string key="NSKeyEquiv">G</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ <int key="NSTag">3</int>
+ </object>
+ <object class="NSMenuItem" id="533142018">
+ <reference key="NSMenu" ref="1515871"/>
+ <string key="NSTitle">Use Selection for Find</string>
+ <string key="NSKeyEquiv">e</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ <int key="NSTag">7</int>
+ </object>
+ <object class="NSMenuItem" id="779751270">
+ <reference key="NSMenu" ref="1515871"/>
+ <string key="NSTitle">Jump to Selection</string>
+ <string key="NSKeyEquiv">j</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ </array>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="450567093">
+ <reference key="NSMenu" ref="883281215"/>
+ <string key="NSTitle">Spelling</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="759043215">
+ <string key="NSTitle">Spelling</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="753598553">
+ <reference key="NSMenu" ref="759043215"/>
+ <string key="NSTitle">Spelling…</string>
+ <string key="NSKeyEquiv">:</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="556128115">
+ <reference key="NSMenu" ref="759043215"/>
+ <string key="NSTitle">Check Spelling</string>
+ <string key="NSKeyEquiv">;</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="644053629">
+ <reference key="NSMenu" ref="759043215"/>
+ <string key="NSTitle">Check Spelling as You Type</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ </array>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="236999817">
+ <reference key="NSMenu" ref="883281215"/>
+ <string key="NSTitle">Speech</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="317192418">
+ <string key="NSTitle">Speech</string>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="1070789972">
+ <reference key="NSMenu" ref="317192418"/>
+ <string key="NSTitle">Start Speaking</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="63041679">
+ <reference key="NSMenu" ref="317192418"/>
+ <string key="NSTitle">Stop Speaking</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ </array>
+ </object>
+ </object>
+ </array>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="677671214">
+ <reference key="NSMenu" ref="985818309"/>
+ <string key="NSTitle">Window</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="1036944217">
+ <object class="NSMutableString" key="NSTitle">
+ <characters key="NS.bytes">Window</characters>
+ </object>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="176418040">
+ <reference key="NSMenu" ref="1036944217"/>
+ <string key="NSTitle">Minimize</string>
+ <string key="NSKeyEquiv">m</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="833041214">
+ <reference key="NSMenu" ref="1036944217"/>
+ <string key="NSTitle">Zoom</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="829519296">
+ <reference key="NSMenu" ref="1036944217"/>
+ <bool key="NSIsDisabled">YES</bool>
+ <bool key="NSIsSeparator">YES</bool>
+ <string key="NSTitle"/>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ <object class="NSMenuItem" id="709479120">
+ <reference key="NSMenu" ref="1036944217"/>
+ <string key="NSTitle">Bring All to Front</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ </array>
+ <string key="NSName">_NSWindowsMenu</string>
+ </object>
+ </object>
+ <object class="NSMenuItem" id="250164583">
+ <reference key="NSMenu" ref="985818309"/>
+ <string key="NSTitle">Help</string>
+ <string key="NSKeyEquiv"/>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ <string key="NSAction">submenuAction:</string>
+ <object class="NSMenu" key="NSSubmenu" id="1058608410">
+ <object class="NSMutableString" key="NSTitle">
+ <characters key="NS.bytes">Help</characters>
+ </object>
+ <array class="NSMutableArray" key="NSMenuItems">
+ <object class="NSMenuItem" id="563664873">
+ <reference key="NSMenu" ref="1058608410"/>
+ <string key="NSTitle">NewApplication Help</string>
+ <string key="NSKeyEquiv">?</string>
+ <int key="NSKeyEquivModMask">1048576</int>
+ <int key="NSMnemonicLoc">2147483647</int>
+ <reference key="NSOnImage" ref="555564785"/>
+ <reference key="NSMixedImage" ref="189791066"/>
+ </object>
+ </array>
+ </object>
+ </object>
+ </array>
+ <string key="NSName">_NSMainMenu</string>
+ </object>
+ <object class="NSCustomObject" id="883305570">
+ <string key="NSClassName">DeviceTestController</string>
+ </object>
+ <object class="NSArrayController" id="99488775">
+ <array class="NSMutableArray" key="NSDeclaredKeys">
+ <string>productName</string>
+ <string>manufacturer</string>
+ </array>
+ <object class="_NSManagedProxy" key="_NSManagedProxy"/>
+ <bool key="NSAvoidsEmptySelection">YES</bool>
+ <bool key="NSPreservesSelection">YES</bool>
+ <bool key="NSSelectsInsertedObjects">YES</bool>
+ <bool key="NSFilterRestrictsInsertion">YES</bool>
+ <bool key="NSClearsFilterPredicateOnInsertion">YES</bool>
+ </object>
+ <object class="NSArrayController" id="72508071">
+ <array class="NSMutableArray" key="NSDeclaredKeys">
+ <string>name</string>
+ <string>pressed</string>
+ </array>
+ <object class="_NSManagedProxy" key="_NSManagedProxy"/>
+ <bool key="NSAvoidsEmptySelection">YES</bool>
+ <bool key="NSPreservesSelection">YES</bool>
+ <bool key="NSSelectsInsertedObjects">YES</bool>
+ <bool key="NSFilterRestrictsInsertion">YES</bool>
+ <bool key="NSClearsFilterPredicateOnInsertion">YES</bool>
+ </object>
+ <object class="NSCustomObject" id="1034941619">
+ <string key="NSClassName">BoolFormatter</string>
+ </object>
+ <object class="NSCustomObject" id="630057591">
+ <string key="NSClassName">MousePaneController</string>
+ </object>
+ <object class="NSCustomObject" id="752502322">
+ <string key="NSClassName">JoystickPaneController</string>
+ </object>
+ <object class="NSArrayController" id="891320766">
+ <array class="NSMutableArray" key="NSDeclaredKeys">
+ <string>productName</string>
+ <string>manufacturer</string>
+ </array>
+ <object class="_NSManagedProxy" key="_NSManagedProxy"/>
+ <bool key="NSAvoidsEmptySelection">YES</bool>
+ <bool key="NSPreservesSelection">YES</bool>
+ <bool key="NSSelectsInsertedObjects">YES</bool>
+ <bool key="NSFilterRestrictsInsertion">YES</bool>
+ <bool key="NSClearsFilterPredicateOnInsertion">YES</bool>
+ </object>
+ <object class="NSArrayController" id="761638104">
+ <array class="NSMutableArray" key="NSDeclaredKeys">
+ <string>name</string>
+ <string>pressed</string>
+ </array>
+ <object class="_NSManagedProxy" key="_NSManagedProxy"/>
+ <bool key="NSAvoidsEmptySelection">YES</bool>
+ <bool key="NSPreservesSelection">YES</bool>
+ <bool key="NSSelectsInsertedObjects">YES</bool>
+ <bool key="NSFilterRestrictsInsertion">YES</bool>
+ <bool key="NSClearsFilterPredicateOnInsertion">YES</bool>
+ </object>
+ <object class="NSCustomObject" id="441492835">
+ <string key="NSClassName">AppleRemotePaneController</string>
+ </object>
+ <object class="NSCustomObject" id="98452829">
+ <string key="NSClassName">KeyboardPaneController</string>
+ </object>
+ <object class="NSArrayController" id="438538984">
+ <array class="NSMutableArray" key="NSDeclaredKeys">
+ <string>productName</string>
+ <string>manufacturer</string>
+ </array>
+ <bool key="NSEditable">YES</bool>
+ <object class="_NSManagedProxy" key="_NSManagedProxy"/>
+ <bool key="NSAvoidsEmptySelection">YES</bool>
+ <bool key="NSPreservesSelection">YES</bool>
+ <bool key="NSSelectsInsertedObjects">YES</bool>
+ <bool key="NSFilterRestrictsInsertion">YES</bool>
+ <bool key="NSClearsFilterPredicateOnInsertion">YES</bool>
+ </object>
+ <object class="NSArrayController" id="306908374">
+ <array class="NSMutableArray" key="NSDeclaredKeys">
+ <string>event</string>
+ <string>description</string>
+ </array>
+ <bool key="NSEditable">YES</bool>
+ <object class="_NSManagedProxy" key="_NSManagedProxy"/>
+ <bool key="NSAvoidsEmptySelection">YES</bool>
+ <bool key="NSPreservesSelection">YES</bool>
+ <bool key="NSSelectsInsertedObjects">YES</bool>
+ <bool key="NSFilterRestrictsInsertion">YES</bool>
+ <bool key="NSClearsFilterPredicateOnInsertion">YES</bool>
+ </object>
+ <object class="NSCustomObject" id="131495452">
+ <string key="NSClassName">AppleMikeyPaneController</string>
+ </object>
+ <object class="NSArrayController" id="414111609">
+ <array class="NSMutableArray" key="NSDeclaredKeys">
+ <string>productName</string>
+ <string>manufacturer</string>
+ </array>
+ <bool key="NSEditable">YES</bool>
+ <object class="_NSManagedProxy" key="_NSManagedProxy"/>
+ <bool key="NSAvoidsEmptySelection">YES</bool>
+ <bool key="NSPreservesSelection">YES</bool>
+ <bool key="NSSelectsInsertedObjects">YES</bool>
+ <bool key="NSFilterRestrictsInsertion">YES</bool>
+ <bool key="NSClearsFilterPredicateOnInsertion">YES</bool>
+ </object>
+ <object class="NSArrayController" id="189836260">
+ <array class="NSMutableArray" key="NSDeclaredKeys">
+ <string>event</string>
+ <string>description</string>
+ </array>
+ <bool key="NSEditable">YES</bool>
+ <object class="_NSManagedProxy" key="_NSManagedProxy"/>
+ <bool key="NSAvoidsEmptySelection">YES</bool>
+ <bool key="NSPreservesSelection">YES</bool>
+ <bool key="NSSelectsInsertedObjects">YES</bool>
+ <bool key="NSFilterRestrictsInsertion">YES</bool>
+ <bool key="NSClearsFilterPredicateOnInsertion">YES</bool>
+ </object>
+ <object class="NSView" id="1024145421">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrameSize">{125, 1}</string>
+ <reference key="NSSuperview"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView"/>
+ </object>
+ <object class="NSView" id="408097814">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrameSize">{125, 1}</string>
+ <reference key="NSSuperview"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView"/>
+ </object>
+ <object class="NSView" id="897756721">
+ <reference key="NSNextResponder"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrameSize">{125, 1}</string>
+ <reference key="NSSuperview"/>
+ <reference key="NSWindow"/>
+ <reference key="NSNextKeyView"/>
+ </object>
+ </array>
+ <object class="IBObjectContainer" key="IBDocument.Objects">
+ <array class="NSMutableArray" key="connectionRecords">
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">terminate:</string>
+ <reference key="source" ref="867122125"/>
+ <reference key="destination" ref="1061266757"/>
+ </object>
+ <int key="connectionID">139</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">orderFrontStandardAboutPanel:</string>
+ <reference key="source" ref="867122125"/>
+ <reference key="destination" ref="824448059"/>
+ </object>
+ <int key="connectionID">142</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">hideOtherApplications:</string>
+ <reference key="source" ref="867122125"/>
+ <reference key="destination" ref="640088582"/>
+ </object>
+ <int key="connectionID">146</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">hide:</string>
+ <reference key="source" ref="867122125"/>
+ <reference key="destination" ref="924050144"/>
+ </object>
+ <int key="connectionID">152</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">unhideAllApplications:</string>
+ <reference key="source" ref="867122125"/>
+ <reference key="destination" ref="103269932"/>
+ </object>
+ <int key="connectionID">153</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">delegate</string>
+ <reference key="source" ref="867122125"/>
+ <reference key="destination" ref="883305570"/>
+ </object>
+ <int key="connectionID">396</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">performMiniaturize:</string>
+ <reference key="source" ref="908386337"/>
+ <reference key="destination" ref="176418040"/>
+ </object>
+ <int key="connectionID">37</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">arrangeInFront:</string>
+ <reference key="source" ref="908386337"/>
+ <reference key="destination" ref="709479120"/>
+ </object>
+ <int key="connectionID">39</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">print:</string>
+ <reference key="source" ref="908386337"/>
+ <reference key="destination" ref="460995318"/>
+ </object>
+ <int key="connectionID">86</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">runPageLayout:</string>
+ <reference key="source" ref="908386337"/>
+ <reference key="destination" ref="280140765"/>
+ </object>
+ <int key="connectionID">87</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">showHelp:</string>
+ <reference key="source" ref="908386337"/>
+ <reference key="destination" ref="563664873"/>
+ </object>
+ <int key="connectionID">122</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">clearRecentDocuments:</string>
+ <reference key="source" ref="908386337"/>
+ <reference key="destination" ref="430142160"/>
+ </object>
+ <int key="connectionID">127</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">performClose:</string>
+ <reference key="source" ref="908386337"/>
+ <reference key="destination" ref="962434548"/>
+ </object>
+ <int key="connectionID">193</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">toggleContinuousSpellChecking:</string>
+ <reference key="source" ref="908386337"/>
+ <reference key="destination" ref="644053629"/>
+ </object>
+ <int key="connectionID">222</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">undo:</string>
+ <reference key="source" ref="908386337"/>
+ <reference key="destination" ref="609227008"/>
+ </object>
+ <int key="connectionID">223</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">copy:</string>
+ <reference key="source" ref="908386337"/>
+ <reference key="destination" ref="190362399"/>
+ </object>
+ <int key="connectionID">224</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">checkSpelling:</string>
+ <reference key="source" ref="908386337"/>
+ <reference key="destination" ref="556128115"/>
+ </object>
+ <int key="connectionID">225</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">paste:</string>
+ <reference key="source" ref="908386337"/>
+ <reference key="destination" ref="944061161"/>
+ </object>
+ <int key="connectionID">226</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">stopSpeaking:</string>
+ <reference key="source" ref="908386337"/>
+ <reference key="destination" ref="63041679"/>
+ </object>
+ <int key="connectionID">227</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">cut:</string>
+ <reference key="source" ref="908386337"/>
+ <reference key="destination" ref="89134411"/>
+ </object>
+ <int key="connectionID">228</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">showGuessPanel:</string>
+ <reference key="source" ref="908386337"/>
+ <reference key="destination" ref="753598553"/>
+ </object>
+ <int key="connectionID">230</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">redo:</string>
+ <reference key="source" ref="908386337"/>
+ <reference key="destination" ref="64556550"/>
+ </object>
+ <int key="connectionID">231</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">selectAll:</string>
+ <reference key="source" ref="908386337"/>
+ <reference key="destination" ref="848176626"/>
+ </object>
+ <int key="connectionID">232</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">startSpeaking:</string>
+ <reference key="source" ref="908386337"/>
+ <reference key="destination" ref="1070789972"/>
+ </object>
+ <int key="connectionID">233</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">delete:</string>
+ <reference key="source" ref="908386337"/>
+ <reference key="destination" ref="27756945"/>
+ </object>
+ <int key="connectionID">235</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">performZoom:</string>
+ <reference key="source" ref="908386337"/>
+ <reference key="destination" ref="833041214"/>
+ </object>
+ <int key="connectionID">240</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">performFindPanelAction:</string>
+ <reference key="source" ref="908386337"/>
+ <reference key="destination" ref="739763715"/>
+ </object>
+ <int key="connectionID">241</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">performFindPanelAction:</string>
+ <reference key="source" ref="908386337"/>
+ <reference key="destination" ref="792228336"/>
+ </object>
+ <int key="connectionID">242</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">performFindPanelAction:</string>
+ <reference key="source" ref="908386337"/>
+ <reference key="destination" ref="835718921"/>
+ </object>
+ <int key="connectionID">243</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">performFindPanelAction:</string>
+ <reference key="source" ref="908386337"/>
+ <reference key="destination" ref="533142018"/>
+ </object>
+ <int key="connectionID">244</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">centerSelectionInVisibleArea:</string>
+ <reference key="source" ref="908386337"/>
+ <reference key="destination" ref="779751270"/>
+ </object>
+ <int key="connectionID">245</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">pasteAsPlainText:</string>
+ <reference key="source" ref="908386337"/>
+ <reference key="destination" ref="586425156"/>
+ </object>
+ <int key="connectionID">247</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">content: arrangedObjects.productName</string>
+ <reference key="source" ref="1023428307"/>
+ <reference key="destination" ref="99488775"/>
+ <object class="NSNibBindingConnector" key="connector" id="689694088">
+ <reference key="NSSource" ref="1023428307"/>
+ <reference key="NSDestination" ref="99488775"/>
+ <string key="NSLabel">content: arrangedObjects.productName</string>
+ <string key="NSBinding">content</string>
+ <string key="NSKeyPath">arrangedObjects.productName</string>
+ <dictionary key="NSOptions">
+ <string key="NSNoSelectionPlaceholder">Foo</string>
+ <string key="NSNotApplicablePlaceholder">Bar</string>
+ <string key="NSNullPlaceholder">No Mice</string>
+ </dictionary>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">342</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">selectedIndex: mouseIndex</string>
+ <reference key="source" ref="1023428307"/>
+ <reference key="destination" ref="630057591"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="1023428307"/>
+ <reference key="NSDestination" ref="630057591"/>
+ <string key="NSLabel">selectedIndex: mouseIndex</string>
+ <string key="NSBinding">selectedIndex</string>
+ <string key="NSKeyPath">mouseIndex</string>
+ <reference key="NSPreviousConnector" ref="689694088"/>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">355</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">mMousePaneController</string>
+ <reference key="source" ref="883305570"/>
+ <reference key="destination" ref="630057591"/>
+ </object>
+ <int key="connectionID">346</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">mWindow</string>
+ <reference key="source" ref="883305570"/>
+ <reference key="destination" ref="982793345"/>
+ </object>
+ <int key="connectionID">397</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">contentArray: mice</string>
+ <reference key="source" ref="99488775"/>
+ <reference key="destination" ref="630057591"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="99488775"/>
+ <reference key="NSDestination" ref="630057591"/>
+ <string key="NSLabel">contentArray: mice</string>
+ <string key="NSBinding">contentArray</string>
+ <string key="NSKeyPath">mice</string>
+ <object class="NSDictionary" key="NSOptions">
+ <string key="NS.key.0">NSConditionallySetsEditable</string>
+ <boolean value="NO" key="NS.object.0"/>
+ </object>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">354</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">value: selection.manufacturer</string>
+ <reference key="source" ref="445056641"/>
+ <reference key="destination" ref="99488775"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="445056641"/>
+ <reference key="NSDestination" ref="99488775"/>
+ <string key="NSLabel">value: selection.manufacturer</string>
+ <string key="NSBinding">value</string>
+ <string key="NSKeyPath">selection.manufacturer</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">267</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">maxValue: maxValue</string>
+ <reference key="source" ref="867143968"/>
+ <reference key="destination" ref="630057591"/>
+ <object class="NSNibBindingConnector" key="connector" id="464702103">
+ <reference key="NSSource" ref="867143968"/>
+ <reference key="NSDestination" ref="630057591"/>
+ <string key="NSLabel">maxValue: maxValue</string>
+ <string key="NSBinding">maxValue</string>
+ <string key="NSKeyPath">maxValue</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">347</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">value: mouseX</string>
+ <reference key="source" ref="867143968"/>
+ <reference key="destination" ref="630057591"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="867143968"/>
+ <reference key="NSDestination" ref="630057591"/>
+ <string key="NSLabel">value: mouseX</string>
+ <string key="NSBinding">value</string>
+ <string key="NSKeyPath">mouseX</string>
+ <reference key="NSPreviousConnector" ref="464702103"/>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">356</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">maxValue: maxValue</string>
+ <reference key="source" ref="114543662"/>
+ <reference key="destination" ref="630057591"/>
+ <object class="NSNibBindingConnector" key="connector" id="866111129">
+ <reference key="NSSource" ref="114543662"/>
+ <reference key="NSDestination" ref="630057591"/>
+ <string key="NSLabel">maxValue: maxValue</string>
+ <string key="NSBinding">maxValue</string>
+ <string key="NSKeyPath">maxValue</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">349</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">value: mouseY</string>
+ <reference key="source" ref="114543662"/>
+ <reference key="destination" ref="630057591"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="114543662"/>
+ <reference key="NSDestination" ref="630057591"/>
+ <string key="NSLabel">value: mouseY</string>
+ <string key="NSBinding">value</string>
+ <string key="NSKeyPath">mouseY</string>
+ <reference key="NSPreviousConnector" ref="866111129"/>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">357</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">maxValue: maxValue</string>
+ <reference key="source" ref="679224553"/>
+ <reference key="destination" ref="630057591"/>
+ <object class="NSNibBindingConnector" key="connector" id="618528643">
+ <reference key="NSSource" ref="679224553"/>
+ <reference key="NSDestination" ref="630057591"/>
+ <string key="NSLabel">maxValue: maxValue</string>
+ <string key="NSBinding">maxValue</string>
+ <string key="NSKeyPath">maxValue</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">351</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">value: mouseWheel</string>
+ <reference key="source" ref="679224553"/>
+ <reference key="destination" ref="630057591"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="679224553"/>
+ <reference key="NSDestination" ref="630057591"/>
+ <string key="NSLabel">value: mouseWheel</string>
+ <string key="NSBinding">value</string>
+ <string key="NSKeyPath">mouseWheel</string>
+ <reference key="NSPreviousConnector" ref="618528643"/>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">358</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">value: arrangedObjects.name</string>
+ <reference key="source" ref="925696421"/>
+ <reference key="destination" ref="72508071"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="925696421"/>
+ <reference key="NSDestination" ref="72508071"/>
+ <string key="NSLabel">value: arrangedObjects.name</string>
+ <string key="NSBinding">value</string>
+ <string key="NSKeyPath">arrangedObjects.name</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">316</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">value: arrangedObjects.pressed</string>
+ <reference key="source" ref="108449693"/>
+ <reference key="destination" ref="72508071"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="108449693"/>
+ <reference key="NSDestination" ref="72508071"/>
+ <string key="NSLabel">value: arrangedObjects.pressed</string>
+ <string key="NSBinding">value</string>
+ <string key="NSKeyPath">arrangedObjects.pressed</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">317</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">contentArray: mouseButtons</string>
+ <reference key="source" ref="72508071"/>
+ <reference key="destination" ref="630057591"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="72508071"/>
+ <reference key="NSDestination" ref="630057591"/>
+ <string key="NSLabel">contentArray: mouseButtons</string>
+ <string key="NSBinding">contentArray</string>
+ <string key="NSKeyPath">mouseButtons</string>
+ <object class="NSDictionary" key="NSOptions">
+ <string key="NS.key.0">NSConditionallySetsEditable</string>
+ <boolean value="NO" key="NS.object.0"/>
+ </object>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">353</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">formatter</string>
+ <reference key="source" ref="282094758"/>
+ <reference key="destination" ref="1034941619"/>
+ </object>
+ <int key="connectionID">323</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">mMiceController</string>
+ <reference key="source" ref="630057591"/>
+ <reference key="destination" ref="99488775"/>
+ </object>
+ <int key="connectionID">345</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">mJoysticksController</string>
+ <reference key="source" ref="752502322"/>
+ <reference key="destination" ref="891320766"/>
+ </object>
+ <int key="connectionID">374</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">content: arrangedObjects.productName</string>
+ <reference key="source" ref="470251532"/>
+ <reference key="destination" ref="891320766"/>
+ <object class="NSNibBindingConnector" key="connector" id="151560195">
+ <reference key="NSSource" ref="470251532"/>
+ <reference key="NSDestination" ref="891320766"/>
+ <string key="NSLabel">content: arrangedObjects.productName</string>
+ <string key="NSBinding">content</string>
+ <string key="NSKeyPath">arrangedObjects.productName</string>
+ <object class="NSDictionary" key="NSOptions">
+ <string key="NS.key.0">NSNullPlaceholder</string>
+ <string key="NS.object.0">No Joysticks</string>
+ </object>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">394</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">selectedIndex: joystickIndex</string>
+ <reference key="source" ref="470251532"/>
+ <reference key="destination" ref="752502322"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="470251532"/>
+ <reference key="NSDestination" ref="752502322"/>
+ <string key="NSLabel">selectedIndex: joystickIndex</string>
+ <string key="NSBinding">selectedIndex</string>
+ <string key="NSKeyPath">joystickIndex</string>
+ <reference key="NSPreviousConnector" ref="151560195"/>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">395</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">value: selection.manufacturer</string>
+ <reference key="source" ref="28013203"/>
+ <reference key="destination" ref="891320766"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="28013203"/>
+ <reference key="NSDestination" ref="891320766"/>
+ <string key="NSLabel">value: selection.manufacturer</string>
+ <string key="NSBinding">value</string>
+ <string key="NSKeyPath">selection.manufacturer</string>
+ <object class="NSDictionary" key="NSOptions">
+ <string key="NS.key.0">NSNoSelectionPlaceholder</string>
+ <string type="base64-UTF8" key="NS.object.0">IA</string>
+ </object>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">393</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">contentArray: joysticks</string>
+ <reference key="source" ref="891320766"/>
+ <reference key="destination" ref="752502322"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="891320766"/>
+ <reference key="NSDestination" ref="752502322"/>
+ <string key="NSLabel">contentArray: joysticks</string>
+ <string key="NSBinding">contentArray</string>
+ <string key="NSKeyPath">joysticks</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">369</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">value: arrangedObjects.pressed</string>
+ <reference key="source" ref="234886615"/>
+ <reference key="destination" ref="761638104"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="234886615"/>
+ <reference key="NSDestination" ref="761638104"/>
+ <string key="NSLabel">value: arrangedObjects.pressed</string>
+ <string key="NSBinding">value</string>
+ <string key="NSKeyPath">arrangedObjects.pressed</string>
+ <object class="NSDictionary" key="NSOptions">
+ <string key="NS.key.0">NSConditionallySetsEditable</string>
+ <boolean value="YES" key="NS.object.0"/>
+ </object>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">401</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">value: arrangedObjects.name</string>
+ <reference key="source" ref="214598876"/>
+ <reference key="destination" ref="761638104"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="214598876"/>
+ <reference key="NSDestination" ref="761638104"/>
+ <string key="NSLabel">value: arrangedObjects.name</string>
+ <string key="NSBinding">value</string>
+ <string key="NSKeyPath">arrangedObjects.name</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">385</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">contentArray: joystickButtons</string>
+ <reference key="source" ref="761638104"/>
+ <reference key="destination" ref="752502322"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="761638104"/>
+ <reference key="NSDestination" ref="752502322"/>
+ <string key="NSLabel">contentArray: joystickButtons</string>
+ <string key="NSBinding">contentArray</string>
+ <string key="NSKeyPath">joystickButtons</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">383</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">formatter</string>
+ <reference key="source" ref="324020026"/>
+ <reference key="destination" ref="1034941619"/>
+ </object>
+ <int key="connectionID">388</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">value: xAxis</string>
+ <reference key="source" ref="152294097"/>
+ <reference key="destination" ref="752502322"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="152294097"/>
+ <reference key="NSDestination" ref="752502322"/>
+ <string key="NSLabel">value: xAxis</string>
+ <string key="NSBinding">value</string>
+ <string key="NSKeyPath">xAxis</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">404</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">value: yAxis</string>
+ <reference key="source" ref="507655026"/>
+ <reference key="destination" ref="752502322"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="507655026"/>
+ <reference key="NSDestination" ref="752502322"/>
+ <string key="NSLabel">value: yAxis</string>
+ <string key="NSBinding">value</string>
+ <string key="NSKeyPath">yAxis</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">405</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">toggleListening:</string>
+ <reference key="source" ref="441492835"/>
+ <reference key="destination" ref="927927578"/>
+ </object>
+ <int key="connectionID">412</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">mStartStopButton</string>
+ <reference key="source" ref="441492835"/>
+ <reference key="destination" ref="927927578"/>
+ </object>
+ <int key="connectionID">414</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">mFeedbackView</string>
+ <reference key="source" ref="441492835"/>
+ <reference key="destination" ref="279154427"/>
+ </object>
+ <int key="connectionID">415</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">mFeedbackText</string>
+ <reference key="source" ref="441492835"/>
+ <reference key="destination" ref="682296781"/>
+ </object>
+ <int key="connectionID">419</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">value: openInExclusiveMode</string>
+ <reference key="source" ref="1042890665"/>
+ <reference key="destination" ref="441492835"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="1042890665"/>
+ <reference key="NSDestination" ref="441492835"/>
+ <string key="NSLabel">value: openInExclusiveMode</string>
+ <string key="NSBinding">value</string>
+ <string key="NSKeyPath">openInExclusiveMode</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">413</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">value: remote.remoteId</string>
+ <reference key="source" ref="179085848"/>
+ <reference key="destination" ref="441492835"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="179085848"/>
+ <reference key="NSDestination" ref="441492835"/>
+ <string key="NSLabel">value: remote.remoteId</string>
+ <string key="NSBinding">value</string>
+ <string key="NSKeyPath">remote.remoteId</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">422</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">mKeyboardsController</string>
+ <reference key="source" ref="98452829"/>
+ <reference key="destination" ref="438538984"/>
+ </object>
+ <int key="connectionID">454</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">mKeyboardEventsController</string>
+ <reference key="source" ref="98452829"/>
+ <reference key="destination" ref="306908374"/>
+ </object>
+ <int key="connectionID">457</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">content: arrangedObjects.productName</string>
+ <reference key="source" ref="801273994"/>
+ <reference key="destination" ref="438538984"/>
+ <object class="NSNibBindingConnector" key="connector" id="931493043">
+ <reference key="NSSource" ref="801273994"/>
+ <reference key="NSDestination" ref="438538984"/>
+ <string key="NSLabel">content: arrangedObjects.productName</string>
+ <string key="NSBinding">content</string>
+ <string key="NSKeyPath">arrangedObjects.productName</string>
+ <object class="NSDictionary" key="NSOptions">
+ <string key="NS.key.0">NSNullPlaceholder</string>
+ <string key="NS.object.0">No Joysticks</string>
+ </object>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">440</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">selectedIndex: keyboardIndex</string>
+ <reference key="source" ref="801273994"/>
+ <reference key="destination" ref="98452829"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="801273994"/>
+ <reference key="NSDestination" ref="98452829"/>
+ <string key="NSLabel">selectedIndex: keyboardIndex</string>
+ <string key="NSBinding">selectedIndex</string>
+ <string key="NSKeyPath">keyboardIndex</string>
+ <reference key="NSPreviousConnector" ref="931493043"/>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">441</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">value: selection.manufacturer</string>
+ <reference key="source" ref="846710279"/>
+ <reference key="destination" ref="438538984"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="846710279"/>
+ <reference key="NSDestination" ref="438538984"/>
+ <string key="NSLabel">value: selection.manufacturer</string>
+ <string key="NSBinding">value</string>
+ <string key="NSKeyPath">selection.manufacturer</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">439</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">contentArray: keyboards</string>
+ <reference key="source" ref="438538984"/>
+ <reference key="destination" ref="98452829"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="438538984"/>
+ <reference key="NSDestination" ref="98452829"/>
+ <string key="NSLabel">contentArray: keyboards</string>
+ <string key="NSBinding">contentArray</string>
+ <string key="NSKeyPath">keyboards</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">433</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">value: arrangedObjects.event</string>
+ <reference key="source" ref="104560874"/>
+ <reference key="destination" ref="306908374"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="104560874"/>
+ <reference key="NSDestination" ref="306908374"/>
+ <string key="NSLabel">value: arrangedObjects.event</string>
+ <string key="NSBinding">value</string>
+ <string key="NSKeyPath">arrangedObjects.event</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">459</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">value: arrangedObjects.description</string>
+ <reference key="source" ref="25394885"/>
+ <reference key="destination" ref="306908374"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="25394885"/>
+ <reference key="NSDestination" ref="306908374"/>
+ <string key="NSLabel">value: arrangedObjects.description</string>
+ <string key="NSBinding">value</string>
+ <string key="NSKeyPath">arrangedObjects.description</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">460</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">contentArray: events</string>
+ <reference key="source" ref="306908374"/>
+ <reference key="destination" ref="98452829"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="306908374"/>
+ <reference key="NSDestination" ref="98452829"/>
+ <string key="NSLabel">contentArray: events</string>
+ <string key="NSBinding">contentArray</string>
+ <string key="NSKeyPath">events</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">456</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">mMikeysController</string>
+ <reference key="source" ref="131495452"/>
+ <reference key="destination" ref="414111609"/>
+ </object>
+ <int key="connectionID">504</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">mMikeysEventsController</string>
+ <reference key="source" ref="131495452"/>
+ <reference key="destination" ref="189836260"/>
+ </object>
+ <int key="connectionID">505</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">contentArray: mikeys</string>
+ <reference key="source" ref="414111609"/>
+ <reference key="destination" ref="131495452"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="414111609"/>
+ <reference key="NSDestination" ref="131495452"/>
+ <string key="NSLabel">contentArray: mikeys</string>
+ <string key="NSBinding">contentArray</string>
+ <string key="NSKeyPath">mikeys</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">538</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">contentArray: events</string>
+ <reference key="source" ref="189836260"/>
+ <reference key="destination" ref="131495452"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="189836260"/>
+ <reference key="NSDestination" ref="131495452"/>
+ <string key="NSLabel">contentArray: events</string>
+ <string key="NSBinding">contentArray</string>
+ <string key="NSKeyPath">events</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">540</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">value: selection.manufacturer</string>
+ <reference key="source" ref="775775215"/>
+ <reference key="destination" ref="414111609"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="775775215"/>
+ <reference key="NSDestination" ref="414111609"/>
+ <string key="NSLabel">value: selection.manufacturer</string>
+ <string key="NSBinding">value</string>
+ <string key="NSKeyPath">selection.manufacturer</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">544</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">content: arrangedObjects.productName</string>
+ <reference key="source" ref="198711655"/>
+ <reference key="destination" ref="414111609"/>
+ <object class="NSNibBindingConnector" key="connector" id="551539712">
+ <reference key="NSSource" ref="198711655"/>
+ <reference key="NSDestination" ref="414111609"/>
+ <string key="NSLabel">content: arrangedObjects.productName</string>
+ <string key="NSBinding">content</string>
+ <string key="NSKeyPath">arrangedObjects.productName</string>
+ <object class="NSDictionary" key="NSOptions">
+ <string key="NS.key.0">NSNullPlaceholder</string>
+ <string key="NS.object.0">No Mikeys</string>
+ </object>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">541</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">selectedIndex: mikeyIndex</string>
+ <reference key="source" ref="198711655"/>
+ <reference key="destination" ref="131495452"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="198711655"/>
+ <reference key="NSDestination" ref="131495452"/>
+ <string key="NSLabel">selectedIndex: mikeyIndex</string>
+ <string key="NSBinding">selectedIndex</string>
+ <string key="NSKeyPath">mikeyIndex</string>
+ <reference key="NSPreviousConnector" ref="551539712"/>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">542</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">value: arrangedObjects.description</string>
+ <reference key="source" ref="762433403"/>
+ <reference key="destination" ref="189836260"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="762433403"/>
+ <reference key="NSDestination" ref="189836260"/>
+ <string key="NSLabel">value: arrangedObjects.description</string>
+ <string key="NSBinding">value</string>
+ <string key="NSKeyPath">arrangedObjects.description</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">536</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBBindingConnection" key="connection">
+ <string key="label">value: arrangedObjects.event</string>
+ <reference key="source" ref="1010687613"/>
+ <reference key="destination" ref="189836260"/>
+ <object class="NSNibBindingConnector" key="connector">
+ <reference key="NSSource" ref="1010687613"/>
+ <reference key="NSDestination" ref="189836260"/>
+ <string key="NSLabel">value: arrangedObjects.event</string>
+ <string key="NSBinding">value</string>
+ <string key="NSKeyPath">arrangedObjects.event</string>
+ <int key="NSNibBindingConnectorVersion">2</int>
+ </object>
+ </object>
+ <int key="connectionID">535</int>
+ </object>
+ </array>
+ <object class="IBMutableOrderedSet" key="objectRecords">
+ <array key="orderedObjects">
+ <object class="IBObjectRecord">
+ <int key="objectID">0</int>
+ <array key="object" id="0"/>
+ <reference key="children" ref="693470140"/>
+ <nil key="parent"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-2</int>
+ <reference key="object" ref="867122125"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">File's Owner</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-1</int>
+ <reference key="object" ref="908386337"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">First Responder</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">21</int>
+ <reference key="object" ref="982793345"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="1006738540"/>
+ </array>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">Window</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">2</int>
+ <reference key="object" ref="1006738540"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="644721648"/>
+ </array>
+ <reference key="parent" ref="982793345"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">248</int>
+ <reference key="object" ref="644721648"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="637701892"/>
+ <reference ref="301669676"/>
+ <reference ref="805145155"/>
+ <reference ref="206151473"/>
+ <reference ref="341515874"/>
+ </array>
+ <reference key="parent" ref="1006738540"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">249</int>
+ <reference key="object" ref="637701892"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="639734842"/>
+ </array>
+ <reference key="parent" ref="644721648"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">250</int>
+ <reference key="object" ref="639734842"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="604537169"/>
+ <reference ref="470251532"/>
+ <reference ref="30575616"/>
+ <reference ref="28013203"/>
+ <reference ref="416538861"/>
+ <reference ref="737187669"/>
+ <reference ref="152294097"/>
+ <reference ref="507655026"/>
+ <reference ref="1035429346"/>
+ <reference ref="299566195"/>
+ </array>
+ <reference key="parent" ref="637701892"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">360</int>
+ <reference key="object" ref="604537169"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="361458923"/>
+ </array>
+ <reference key="parent" ref="639734842"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">361</int>
+ <reference key="object" ref="470251532"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="656700384"/>
+ </array>
+ <reference key="parent" ref="639734842"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">366</int>
+ <reference key="object" ref="30575616"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="895842563"/>
+ </array>
+ <reference key="parent" ref="639734842"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">367</int>
+ <reference key="object" ref="28013203"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="646237192"/>
+ </array>
+ <reference key="parent" ref="639734842"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">376</int>
+ <reference key="object" ref="416538861"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="209939006"/>
+ <reference ref="128836592"/>
+ <reference ref="644754426"/>
+ <reference ref="548447063"/>
+ </array>
+ <reference key="parent" ref="639734842"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">377</int>
+ <reference key="object" ref="209939006"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="234886615"/>
+ <reference ref="214598876"/>
+ </array>
+ <reference key="parent" ref="416538861"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">378</int>
+ <reference key="object" ref="234886615"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="324020026"/>
+ </array>
+ <reference key="parent" ref="209939006"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">387</int>
+ <reference key="object" ref="324020026"/>
+ <reference key="parent" ref="234886615"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">379</int>
+ <reference key="object" ref="214598876"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="826160026"/>
+ </array>
+ <reference key="parent" ref="209939006"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">380</int>
+ <reference key="object" ref="737187669"/>
+ <array class="NSMutableArray" key="children"/>
+ <reference key="parent" ref="639734842"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">398</int>
+ <reference key="object" ref="152294097"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="688209869"/>
+ </array>
+ <reference key="parent" ref="639734842"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">399</int>
+ <reference key="object" ref="507655026"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="191024010"/>
+ </array>
+ <reference key="parent" ref="639734842"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">402</int>
+ <reference key="object" ref="1035429346"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="678112624"/>
+ </array>
+ <reference key="parent" ref="639734842"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">403</int>
+ <reference key="object" ref="299566195"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="760716940"/>
+ </array>
+ <reference key="parent" ref="639734842"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">251</int>
+ <reference key="object" ref="301669676"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="854750114"/>
+ </array>
+ <reference key="parent" ref="644721648"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">252</int>
+ <reference key="object" ref="854750114"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="803418548"/>
+ <reference ref="1023428307"/>
+ <reference ref="186449852"/>
+ <reference ref="445056641"/>
+ <reference ref="848268071"/>
+ <reference ref="299472703"/>
+ <reference ref="548001438"/>
+ <reference ref="198193797"/>
+ <reference ref="867143968"/>
+ <reference ref="114543662"/>
+ <reference ref="679224553"/>
+ <reference ref="1019553122"/>
+ </array>
+ <reference key="parent" ref="301669676"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">255</int>
+ <reference key="object" ref="803418548"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="960206382"/>
+ </array>
+ <reference key="parent" ref="854750114"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">256</int>
+ <reference key="object" ref="1023428307"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="874323760"/>
+ </array>
+ <reference key="parent" ref="854750114"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">265</int>
+ <reference key="object" ref="186449852"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="721914736"/>
+ </array>
+ <reference key="parent" ref="854750114"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">266</int>
+ <reference key="object" ref="445056641"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="1051972028"/>
+ </array>
+ <reference key="parent" ref="854750114"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">270</int>
+ <reference key="object" ref="848268071"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="777783325"/>
+ </array>
+ <reference key="parent" ref="854750114"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">271</int>
+ <reference key="object" ref="299472703"/>
+ <array class="NSMutableArray" key="children"/>
+ <reference key="parent" ref="854750114"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">273</int>
+ <reference key="object" ref="548001438"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="873471934"/>
+ </array>
+ <reference key="parent" ref="854750114"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">274</int>
+ <reference key="object" ref="198193797"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="213114820"/>
+ </array>
+ <reference key="parent" ref="854750114"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">281</int>
+ <reference key="object" ref="867143968"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="465679605"/>
+ </array>
+ <reference key="parent" ref="854750114"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">288</int>
+ <reference key="object" ref="114543662"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="14328985"/>
+ </array>
+ <reference key="parent" ref="854750114"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">294</int>
+ <reference key="object" ref="679224553"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="537133846"/>
+ </array>
+ <reference key="parent" ref="854750114"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">310</int>
+ <reference key="object" ref="1019553122"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="392699757"/>
+ <reference ref="722307718"/>
+ <reference ref="772621236"/>
+ <reference ref="803957232"/>
+ </array>
+ <reference key="parent" ref="854750114"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">311</int>
+ <reference key="object" ref="392699757"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="925696421"/>
+ <reference ref="108449693"/>
+ </array>
+ <reference key="parent" ref="1019553122"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">312</int>
+ <reference key="object" ref="925696421"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="907171440"/>
+ </array>
+ <reference key="parent" ref="392699757"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">313</int>
+ <reference key="object" ref="108449693"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="282094758"/>
+ </array>
+ <reference key="parent" ref="392699757"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">321</int>
+ <reference key="object" ref="282094758"/>
+ <reference key="parent" ref="108449693"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">253</int>
+ <reference key="object" ref="805145155"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="425526148"/>
+ </array>
+ <reference key="parent" ref="644721648"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">254</int>
+ <reference key="object" ref="425526148"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="801273994"/>
+ <reference ref="821770352"/>
+ <reference ref="846710279"/>
+ <reference ref="936527210"/>
+ <reference ref="293480414"/>
+ <reference ref="352565696"/>
+ </array>
+ <reference key="parent" ref="805145155"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">424</int>
+ <reference key="object" ref="801273994"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="124405559"/>
+ </array>
+ <reference key="parent" ref="425526148"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">429</int>
+ <reference key="object" ref="821770352"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="635585675"/>
+ </array>
+ <reference key="parent" ref="425526148"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">430</int>
+ <reference key="object" ref="846710279"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="271966601"/>
+ </array>
+ <reference key="parent" ref="425526148"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">431</int>
+ <reference key="object" ref="936527210"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="600387788"/>
+ </array>
+ <reference key="parent" ref="425526148"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">448</int>
+ <reference key="object" ref="293480414"/>
+ <array class="NSMutableArray" key="children"/>
+ <reference key="parent" ref="425526148"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">450</int>
+ <reference key="object" ref="352565696"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="1058080016"/>
+ <reference ref="626352804"/>
+ <reference ref="899917373"/>
+ </array>
+ <reference key="parent" ref="425526148"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">451</int>
+ <reference key="object" ref="1058080016"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="104560874"/>
+ <reference ref="25394885"/>
+ </array>
+ <reference key="parent" ref="352565696"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">452</int>
+ <reference key="object" ref="104560874"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="493334896"/>
+ </array>
+ <reference key="parent" ref="1058080016"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">453</int>
+ <reference key="object" ref="25394885"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="376526475"/>
+ </array>
+ <reference key="parent" ref="1058080016"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">407</int>
+ <reference key="object" ref="206151473"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="103723724"/>
+ </array>
+ <reference key="parent" ref="644721648"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">408</int>
+ <reference key="object" ref="103723724"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="279154427"/>
+ <reference ref="927927578"/>
+ <reference ref="1042890665"/>
+ <reference ref="682296781"/>
+ <reference ref="80389755"/>
+ <reference ref="179085848"/>
+ </array>
+ <reference key="parent" ref="206151473"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">409</int>
+ <reference key="object" ref="279154427"/>
+ <reference key="parent" ref="103723724"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">410</int>
+ <reference key="object" ref="927927578"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="625781673"/>
+ </array>
+ <reference key="parent" ref="103723724"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">411</int>
+ <reference key="object" ref="1042890665"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="113061213"/>
+ </array>
+ <reference key="parent" ref="103723724"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">416</int>
+ <reference key="object" ref="682296781"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="1014225370"/>
+ </array>
+ <reference key="parent" ref="103723724"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">420</int>
+ <reference key="object" ref="80389755"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="357183005"/>
+ </array>
+ <reference key="parent" ref="103723724"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">421</int>
+ <reference key="object" ref="179085848"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="319211686"/>
+ </array>
+ <reference key="parent" ref="103723724"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">29</int>
+ <reference key="object" ref="985818309"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="677671214"/>
+ <reference ref="718640928"/>
+ <reference ref="141310426"/>
+ <reference ref="250164583"/>
+ <reference ref="471057131"/>
+ </array>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">MainMenu</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">19</int>
+ <reference key="object" ref="677671214"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="1036944217"/>
+ </array>
+ <reference key="parent" ref="985818309"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">24</int>
+ <reference key="object" ref="1036944217"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="709479120"/>
+ <reference ref="176418040"/>
+ <reference ref="829519296"/>
+ <reference ref="833041214"/>
+ </array>
+ <reference key="parent" ref="677671214"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">5</int>
+ <reference key="object" ref="709479120"/>
+ <reference key="parent" ref="1036944217"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">23</int>
+ <reference key="object" ref="176418040"/>
+ <reference key="parent" ref="1036944217"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">92</int>
+ <reference key="object" ref="829519296"/>
+ <reference key="parent" ref="1036944217"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">239</int>
+ <reference key="object" ref="833041214"/>
+ <reference key="parent" ref="1036944217"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">56</int>
+ <reference key="object" ref="718640928"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="334835152"/>
+ </array>
+ <reference key="parent" ref="985818309"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">57</int>
+ <reference key="object" ref="334835152"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="824448059"/>
+ <reference ref="441187593"/>
+ <reference ref="75425932"/>
+ <reference ref="924050144"/>
+ <reference ref="1061266757"/>
+ <reference ref="516492413"/>
+ <reference ref="740657299"/>
+ <reference ref="640088582"/>
+ <reference ref="1035629316"/>
+ <reference ref="103269932"/>
+ <reference ref="164663327"/>
+ </array>
+ <reference key="parent" ref="718640928"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">58</int>
+ <reference key="object" ref="824448059"/>
+ <reference key="parent" ref="334835152"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">129</int>
+ <reference key="object" ref="441187593"/>
+ <reference key="parent" ref="334835152"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">131</int>
+ <reference key="object" ref="75425932"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="718887502"/>
+ </array>
+ <reference key="parent" ref="334835152"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">130</int>
+ <reference key="object" ref="718887502"/>
+ <reference key="parent" ref="75425932"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">134</int>
+ <reference key="object" ref="924050144"/>
+ <reference key="parent" ref="334835152"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">136</int>
+ <reference key="object" ref="1061266757"/>
+ <reference key="parent" ref="334835152"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">143</int>
+ <reference key="object" ref="516492413"/>
+ <reference key="parent" ref="334835152"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">144</int>
+ <reference key="object" ref="740657299"/>
+ <reference key="parent" ref="334835152"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">145</int>
+ <reference key="object" ref="640088582"/>
+ <reference key="parent" ref="334835152"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">149</int>
+ <reference key="object" ref="1035629316"/>
+ <reference key="parent" ref="334835152"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">150</int>
+ <reference key="object" ref="103269932"/>
+ <reference key="parent" ref="334835152"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">236</int>
+ <reference key="object" ref="164663327"/>
+ <reference key="parent" ref="334835152"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">83</int>
+ <reference key="object" ref="141310426"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="946423102"/>
+ </array>
+ <reference key="parent" ref="985818309"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">81</int>
+ <reference key="object" ref="946423102"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="739670817"/>
+ <reference ref="962434548"/>
+ <reference ref="1038134261"/>
+ <reference ref="932001322"/>
+ <reference ref="280140765"/>
+ <reference ref="460995318"/>
+ <reference ref="131606599"/>
+ <reference ref="1052462246"/>
+ <reference ref="395391345"/>
+ <reference ref="1038775041"/>
+ <reference ref="272198838"/>
+ </array>
+ <reference key="parent" ref="141310426"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">72</int>
+ <reference key="object" ref="739670817"/>
+ <reference key="parent" ref="946423102"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">73</int>
+ <reference key="object" ref="962434548"/>
+ <reference key="parent" ref="946423102"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">74</int>
+ <reference key="object" ref="1038134261"/>
+ <reference key="parent" ref="946423102"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">75</int>
+ <reference key="object" ref="932001322"/>
+ <reference key="parent" ref="946423102"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">77</int>
+ <reference key="object" ref="280140765"/>
+ <reference key="parent" ref="946423102"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">78</int>
+ <reference key="object" ref="460995318"/>
+ <reference key="parent" ref="946423102"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">79</int>
+ <reference key="object" ref="131606599"/>
+ <reference key="parent" ref="946423102"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">80</int>
+ <reference key="object" ref="1052462246"/>
+ <reference key="parent" ref="946423102"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">82</int>
+ <reference key="object" ref="395391345"/>
+ <reference key="parent" ref="946423102"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">112</int>
+ <reference key="object" ref="1038775041"/>
+ <reference key="parent" ref="946423102"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">124</int>
+ <reference key="object" ref="272198838"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="606750118"/>
+ </array>
+ <reference key="parent" ref="946423102"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">125</int>
+ <reference key="object" ref="606750118"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="430142160"/>
+ </array>
+ <reference key="parent" ref="272198838"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">126</int>
+ <reference key="object" ref="430142160"/>
+ <reference key="parent" ref="606750118"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">103</int>
+ <reference key="object" ref="250164583"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="1058608410"/>
+ </array>
+ <reference key="parent" ref="985818309"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">106</int>
+ <reference key="object" ref="1058608410"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="563664873"/>
+ </array>
+ <reference key="parent" ref="250164583"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">111</int>
+ <reference key="object" ref="563664873"/>
+ <reference key="parent" ref="1058608410"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">217</int>
+ <reference key="object" ref="471057131"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="883281215"/>
+ </array>
+ <reference key="parent" ref="985818309"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">205</int>
+ <reference key="object" ref="883281215"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="190362399"/>
+ <reference ref="848176626"/>
+ <reference ref="89134411"/>
+ <reference ref="27756945"/>
+ <reference ref="944061161"/>
+ <reference ref="1030974022"/>
+ <reference ref="609227008"/>
+ <reference ref="236999817"/>
+ <reference ref="872585626"/>
+ <reference ref="64556550"/>
+ <reference ref="450567093"/>
+ <reference ref="613523294"/>
+ <reference ref="586425156"/>
+ </array>
+ <reference key="parent" ref="471057131"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">197</int>
+ <reference key="object" ref="190362399"/>
+ <reference key="parent" ref="883281215"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">198</int>
+ <reference key="object" ref="848176626"/>
+ <reference key="parent" ref="883281215"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">199</int>
+ <reference key="object" ref="89134411"/>
+ <reference key="parent" ref="883281215"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">202</int>
+ <reference key="object" ref="27756945"/>
+ <reference key="parent" ref="883281215"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">203</int>
+ <reference key="object" ref="944061161"/>
+ <reference key="parent" ref="883281215"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">206</int>
+ <reference key="object" ref="1030974022"/>
+ <reference key="parent" ref="883281215"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">207</int>
+ <reference key="object" ref="609227008"/>
+ <reference key="parent" ref="883281215"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">211</int>
+ <reference key="object" ref="236999817"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="317192418"/>
+ </array>
+ <reference key="parent" ref="883281215"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">212</int>
+ <reference key="object" ref="317192418"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="63041679"/>
+ <reference ref="1070789972"/>
+ </array>
+ <reference key="parent" ref="236999817"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">195</int>
+ <reference key="object" ref="63041679"/>
+ <reference key="parent" ref="317192418"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">196</int>
+ <reference key="object" ref="1070789972"/>
+ <reference key="parent" ref="317192418"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">214</int>
+ <reference key="object" ref="872585626"/>
+ <reference key="parent" ref="883281215"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">215</int>
+ <reference key="object" ref="64556550"/>
+ <reference key="parent" ref="883281215"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">216</int>
+ <reference key="object" ref="450567093"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="759043215"/>
+ </array>
+ <reference key="parent" ref="883281215"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">200</int>
+ <reference key="object" ref="759043215"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="556128115"/>
+ <reference ref="753598553"/>
+ <reference ref="644053629"/>
+ </array>
+ <reference key="parent" ref="450567093"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">201</int>
+ <reference key="object" ref="556128115"/>
+ <reference key="parent" ref="759043215"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">204</int>
+ <reference key="object" ref="753598553"/>
+ <reference key="parent" ref="759043215"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">219</int>
+ <reference key="object" ref="644053629"/>
+ <reference key="parent" ref="759043215"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">218</int>
+ <reference key="object" ref="613523294"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="1515871"/>
+ </array>
+ <reference key="parent" ref="883281215"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">220</int>
+ <reference key="object" ref="1515871"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="792228336"/>
+ <reference ref="739763715"/>
+ <reference ref="779751270"/>
+ <reference ref="835718921"/>
+ <reference ref="533142018"/>
+ </array>
+ <reference key="parent" ref="613523294"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">208</int>
+ <reference key="object" ref="792228336"/>
+ <reference key="parent" ref="1515871"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">209</int>
+ <reference key="object" ref="739763715"/>
+ <reference key="parent" ref="1515871"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">210</int>
+ <reference key="object" ref="779751270"/>
+ <reference key="parent" ref="1515871"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">213</int>
+ <reference key="object" ref="835718921"/>
+ <reference key="parent" ref="1515871"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">221</int>
+ <reference key="object" ref="533142018"/>
+ <reference key="parent" ref="1515871"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">246</int>
+ <reference key="object" ref="586425156"/>
+ <reference key="parent" ref="883281215"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">261</int>
+ <reference key="object" ref="883305570"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">DeviceTestController</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">262</int>
+ <reference key="object" ref="99488775"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">Mice</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">314</int>
+ <reference key="object" ref="72508071"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">MouseButtons</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">322</int>
+ <reference key="object" ref="1034941619"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">BoolFormatter</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">344</int>
+ <reference key="object" ref="630057591"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">MousePaneController</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">359</int>
+ <reference key="object" ref="752502322"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">JoystickPaneController</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">368</int>
+ <reference key="object" ref="891320766"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">Joysticks</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">382</int>
+ <reference key="object" ref="761638104"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">JoystickButtons</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">406</int>
+ <reference key="object" ref="441492835"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">AppleRemotePaneController</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">423</int>
+ <reference key="object" ref="98452829"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">KeyboardPaneController</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">432</int>
+ <reference key="object" ref="438538984"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">Keyboards</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">455</int>
+ <reference key="object" ref="306908374"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">KeyboardEvents</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">462</int>
+ <reference key="object" ref="361458923"/>
+ <reference key="parent" ref="604537169"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">463</int>
+ <reference key="object" ref="656700384"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="794327235"/>
+ </array>
+ <reference key="parent" ref="470251532"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">464</int>
+ <reference key="object" ref="895842563"/>
+ <reference key="parent" ref="30575616"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">465</int>
+ <reference key="object" ref="646237192"/>
+ <reference key="parent" ref="28013203"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">466</int>
+ <reference key="object" ref="688209869"/>
+ <reference key="parent" ref="152294097"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">467</int>
+ <reference key="object" ref="191024010"/>
+ <reference key="parent" ref="507655026"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">468</int>
+ <reference key="object" ref="678112624"/>
+ <reference key="parent" ref="1035429346"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">469</int>
+ <reference key="object" ref="760716940"/>
+ <reference key="parent" ref="299566195"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">470</int>
+ <reference key="object" ref="960206382"/>
+ <reference key="parent" ref="803418548"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">471</int>
+ <reference key="object" ref="874323760"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="70472645"/>
+ </array>
+ <reference key="parent" ref="1023428307"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">472</int>
+ <reference key="object" ref="721914736"/>
+ <reference key="parent" ref="186449852"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">473</int>
+ <reference key="object" ref="1051972028"/>
+ <reference key="parent" ref="445056641"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">474</int>
+ <reference key="object" ref="777783325"/>
+ <reference key="parent" ref="848268071"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">475</int>
+ <reference key="object" ref="873471934"/>
+ <reference key="parent" ref="548001438"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">476</int>
+ <reference key="object" ref="213114820"/>
+ <reference key="parent" ref="198193797"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">477</int>
+ <reference key="object" ref="465679605"/>
+ <reference key="parent" ref="867143968"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">478</int>
+ <reference key="object" ref="14328985"/>
+ <reference key="parent" ref="114543662"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">479</int>
+ <reference key="object" ref="537133846"/>
+ <reference key="parent" ref="679224553"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">480</int>
+ <reference key="object" ref="124405559"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="17814120"/>
+ </array>
+ <reference key="parent" ref="801273994"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">481</int>
+ <reference key="object" ref="635585675"/>
+ <reference key="parent" ref="821770352"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">482</int>
+ <reference key="object" ref="271966601"/>
+ <reference key="parent" ref="846710279"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">483</int>
+ <reference key="object" ref="600387788"/>
+ <reference key="parent" ref="936527210"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">484</int>
+ <reference key="object" ref="625781673"/>
+ <reference key="parent" ref="927927578"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">485</int>
+ <reference key="object" ref="113061213"/>
+ <reference key="parent" ref="1042890665"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">486</int>
+ <reference key="object" ref="1014225370"/>
+ <reference key="parent" ref="682296781"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">487</int>
+ <reference key="object" ref="357183005"/>
+ <reference key="parent" ref="80389755"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">488</int>
+ <reference key="object" ref="319211686"/>
+ <reference key="parent" ref="179085848"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">489</int>
+ <reference key="object" ref="826160026"/>
+ <reference key="parent" ref="214598876"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">490</int>
+ <reference key="object" ref="907171440"/>
+ <reference key="parent" ref="925696421"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">491</int>
+ <reference key="object" ref="493334896"/>
+ <reference key="parent" ref="104560874"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">492</int>
+ <reference key="object" ref="376526475"/>
+ <reference key="parent" ref="25394885"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">362</int>
+ <reference key="object" ref="794327235"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="642014613"/>
+ <reference ref="424623477"/>
+ <reference ref="563627306"/>
+ </array>
+ <reference key="parent" ref="656700384"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">365</int>
+ <reference key="object" ref="642014613"/>
+ <reference key="parent" ref="794327235"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">364</int>
+ <reference key="object" ref="424623477"/>
+ <reference key="parent" ref="794327235"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">363</int>
+ <reference key="object" ref="563627306"/>
+ <reference key="parent" ref="794327235"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">257</int>
+ <reference key="object" ref="70472645"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="821687636"/>
+ <reference ref="554006839"/>
+ <reference ref="781805482"/>
+ </array>
+ <reference key="parent" ref="874323760"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">260</int>
+ <reference key="object" ref="821687636"/>
+ <reference key="parent" ref="70472645"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">259</int>
+ <reference key="object" ref="554006839"/>
+ <reference key="parent" ref="70472645"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">258</int>
+ <reference key="object" ref="781805482"/>
+ <reference key="parent" ref="70472645"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">425</int>
+ <reference key="object" ref="17814120"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="882835994"/>
+ <reference ref="296793368"/>
+ <reference ref="157934231"/>
+ </array>
+ <reference key="parent" ref="124405559"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">428</int>
+ <reference key="object" ref="882835994"/>
+ <reference key="parent" ref="17814120"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">427</int>
+ <reference key="object" ref="296793368"/>
+ <reference key="parent" ref="17814120"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">426</int>
+ <reference key="object" ref="157934231"/>
+ <reference key="parent" ref="17814120"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">493</int>
+ <reference key="object" ref="128836592"/>
+ <reference key="parent" ref="416538861"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">494</int>
+ <reference key="object" ref="644754426"/>
+ <reference key="parent" ref="416538861"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">495</int>
+ <reference key="object" ref="548447063"/>
+ <reference key="parent" ref="416538861"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">496</int>
+ <reference key="object" ref="722307718"/>
+ <reference key="parent" ref="1019553122"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">497</int>
+ <reference key="object" ref="772621236"/>
+ <reference key="parent" ref="1019553122"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">498</int>
+ <reference key="object" ref="803957232"/>
+ <reference key="parent" ref="1019553122"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">499</int>
+ <reference key="object" ref="626352804"/>
+ <reference key="parent" ref="352565696"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">500</int>
+ <reference key="object" ref="899917373"/>
+ <reference key="parent" ref="352565696"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">-3</int>
+ <reference key="object" ref="426702588"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">Application</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">381</int>
+ <reference key="object" ref="1024145421"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">272</int>
+ <reference key="object" ref="408097814"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">449</int>
+ <reference key="object" ref="897756721"/>
+ <reference key="parent" ref="0"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">501</int>
+ <reference key="object" ref="131495452"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">AppleMikeyPaneController</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">502</int>
+ <reference key="object" ref="414111609"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">mikeys</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">503</int>
+ <reference key="object" ref="189836260"/>
+ <reference key="parent" ref="0"/>
+ <string key="objectName">mikeyEvents</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">506</int>
+ <reference key="object" ref="341515874"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="348322794"/>
+ </array>
+ <reference key="parent" ref="644721648"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">507</int>
+ <reference key="object" ref="348322794"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="198711655"/>
+ <reference ref="533537148"/>
+ <reference ref="417902156"/>
+ <reference ref="648226226"/>
+ <reference ref="775775215"/>
+ <reference ref="969348819"/>
+ </array>
+ <reference key="parent" ref="341515874"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">513</int>
+ <reference key="object" ref="198711655"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="646203599"/>
+ </array>
+ <reference key="parent" ref="348322794"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">512</int>
+ <reference key="object" ref="533537148"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="1028846042"/>
+ </array>
+ <reference key="parent" ref="348322794"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">509</int>
+ <reference key="object" ref="648226226"/>
+ <reference key="parent" ref="348322794"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">508</int>
+ <reference key="object" ref="969348819"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="6762116"/>
+ <reference ref="388049267"/>
+ <reference ref="524946031"/>
+ </array>
+ <reference key="parent" ref="348322794"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">524</int>
+ <reference key="object" ref="6762116"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="1010687613"/>
+ <reference ref="762433403"/>
+ </array>
+ <reference key="parent" ref="969348819"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">523</int>
+ <reference key="object" ref="388049267"/>
+ <reference key="parent" ref="969348819"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">522</int>
+ <reference key="object" ref="524946031"/>
+ <reference key="parent" ref="969348819"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">526</int>
+ <reference key="object" ref="1010687613"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="373004376"/>
+ </array>
+ <reference key="parent" ref="6762116"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">525</int>
+ <reference key="object" ref="762433403"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="258874923"/>
+ </array>
+ <reference key="parent" ref="6762116"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">528</int>
+ <reference key="object" ref="258874923"/>
+ <reference key="parent" ref="762433403"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">527</int>
+ <reference key="object" ref="373004376"/>
+ <reference key="parent" ref="1010687613"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">519</int>
+ <reference key="object" ref="1028846042"/>
+ <reference key="parent" ref="533537148"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">514</int>
+ <reference key="object" ref="646203599"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="1033926023"/>
+ </array>
+ <reference key="parent" ref="198711655"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">515</int>
+ <reference key="object" ref="1033926023"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="799967634"/>
+ <reference ref="209592817"/>
+ <reference ref="1019206975"/>
+ </array>
+ <reference key="parent" ref="646203599"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">518</int>
+ <reference key="object" ref="799967634"/>
+ <reference key="parent" ref="1033926023"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">517</int>
+ <reference key="object" ref="209592817"/>
+ <reference key="parent" ref="1033926023"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">516</int>
+ <reference key="object" ref="1019206975"/>
+ <reference key="parent" ref="1033926023"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">510</int>
+ <reference key="object" ref="417902156"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="839783436"/>
+ </array>
+ <reference key="parent" ref="348322794"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">521</int>
+ <reference key="object" ref="839783436"/>
+ <reference key="parent" ref="417902156"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">511</int>
+ <reference key="object" ref="775775215"/>
+ <array class="NSMutableArray" key="children">
+ <reference ref="60166265"/>
+ </array>
+ <reference key="parent" ref="348322794"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">520</int>
+ <reference key="object" ref="60166265"/>
+ <reference key="parent" ref="775775215"/>
+ </object>
+ </array>
+ </object>
+ <dictionary class="NSMutableDictionary" key="flattenedProperties">
+ <string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="-3.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="103.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="106.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="111.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="112.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="124.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="125.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="126.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="129.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="130.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="131.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="134.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="136.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="143.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="144.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="145.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="149.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="150.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="19.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="195.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="196.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="197.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="198.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="199.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="2.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="200.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="201.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="202.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="203.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="204.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="205.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="206.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="207.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="208.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="209.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="21.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="210.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="211.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="212.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="213.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="214.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="215.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="216.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="217.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="218.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="219.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="220.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="221.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="23.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="236.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="239.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="24.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="246.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="248.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="249.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="250.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="251.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="252.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="253.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="254.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="255.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="256.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="257.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="258.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="259.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="260.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="261.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="262.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="265.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="266.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="270.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="271.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="272.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="273.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="274.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="281.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="288.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="29.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="294.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="310.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="311.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="312.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="313.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="314.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="321.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="322.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="344.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="359.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="360.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="361.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="362.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="363.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="364.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="365.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="366.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="367.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="368.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="376.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="377.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="378.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="379.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="380.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="381.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="382.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="387.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="398.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="399.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="402.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="403.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="406.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="407.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="408.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="409.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="410.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="411.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="416.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="420.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="421.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="423.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="424.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="425.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="426.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="427.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="428.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="429.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="430.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="431.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="432.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="448.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="449.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="450.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="451.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="452.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="453.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="455.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="462.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="463.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="464.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="465.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="466.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="467.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="468.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="469.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="470.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="471.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="472.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="473.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="474.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="475.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="476.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="477.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="478.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="479.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="480.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="481.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="482.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="483.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="484.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="485.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="486.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="487.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="488.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="489.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="490.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="491.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="492.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="493.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="494.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="495.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="496.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="497.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="498.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="499.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="5.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="500.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="501.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="502.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="503.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="506.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="507.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="508.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="509.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="510.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="511.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="512.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="513.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="514.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="515.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="516.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="517.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="518.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="519.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="520.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="521.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="522.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="523.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="524.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="525.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="526.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="527.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="528.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="56.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="57.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="58.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="72.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="73.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="74.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="75.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="77.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="78.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="79.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="80.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="81.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="82.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="83.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string key="92.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
+ </dictionary>
+ <dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
+ <nil key="activeLocalization"/>
+ <dictionary class="NSMutableDictionary" key="localizations"/>
+ <nil key="sourceID"/>
+ <int key="maxID">544</int>
+ </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes">
+ <array class="NSMutableArray" key="referencedPartialClassDescriptions">
+ <object class="IBPartialClassDescription">
+ <string key="className">AppleMikeyPaneController</string>
+ <string key="superclassName">NSObject</string>
+ <dictionary class="NSMutableDictionary" key="outlets">
+ <string key="mMikeysController">NSArrayController</string>
+ <string key="mMikeysEventsController">NSArrayController</string>
+ </dictionary>
+ <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <object class="IBToOneOutletInfo" key="mMikeysController">
+ <string key="name">mMikeysController</string>
+ <string key="candidateClassName">NSArrayController</string>
+ </object>
+ <object class="IBToOneOutletInfo" key="mMikeysEventsController">
+ <string key="name">mMikeysEventsController</string>
+ <string key="candidateClassName">NSArrayController</string>
+ </object>
+ </dictionary>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/AppleMikeyPaneController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">AppleRemotePaneController</string>
+ <string key="superclassName">NSObject</string>
+ <object class="NSMutableDictionary" key="actions">
+ <string key="NS.key.0">toggleListening:</string>
+ <string key="NS.object.0">id</string>
+ </object>
+ <object class="NSMutableDictionary" key="actionInfosByName">
+ <string key="NS.key.0">toggleListening:</string>
+ <object class="IBActionInfo" key="NS.object.0">
+ <string key="name">toggleListening:</string>
+ <string key="candidateClassName">id</string>
+ </object>
+ </object>
+ <dictionary class="NSMutableDictionary" key="outlets">
+ <string key="mFeedbackText">NSTextField</string>
+ <string key="mFeedbackView">RemoteFeedbackView</string>
+ <string key="mStartStopButton">NSButton</string>
+ </dictionary>
+ <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <object class="IBToOneOutletInfo" key="mFeedbackText">
+ <string key="name">mFeedbackText</string>
+ <string key="candidateClassName">NSTextField</string>
+ </object>
+ <object class="IBToOneOutletInfo" key="mFeedbackView">
+ <string key="name">mFeedbackView</string>
+ <string key="candidateClassName">RemoteFeedbackView</string>
+ </object>
+ <object class="IBToOneOutletInfo" key="mStartStopButton">
+ <string key="name">mStartStopButton</string>
+ <string key="candidateClassName">NSButton</string>
+ </object>
+ </dictionary>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/AppleRemotePaneController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">BoolFormatter</string>
+ <string key="superclassName">NSFormatter</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/BoolFormatter.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">DeviceTestController</string>
+ <string key="superclassName">NSObject</string>
+ <dictionary class="NSMutableDictionary" key="outlets">
+ <string key="mMousePaneController">MousePaneController</string>
+ <string key="mWindow">NSWindow</string>
+ </dictionary>
+ <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <object class="IBToOneOutletInfo" key="mMousePaneController">
+ <string key="name">mMousePaneController</string>
+ <string key="candidateClassName">MousePaneController</string>
+ </object>
+ <object class="IBToOneOutletInfo" key="mWindow">
+ <string key="name">mWindow</string>
+ <string key="candidateClassName">NSWindow</string>
+ </object>
+ </dictionary>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/DeviceTestController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">JoystickPaneController</string>
+ <string key="superclassName">NSObject</string>
+ <object class="NSMutableDictionary" key="outlets">
+ <string key="NS.key.0">mJoysticksController</string>
+ <string key="NS.object.0">NSArrayController</string>
+ </object>
+ <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <string key="NS.key.0">mJoysticksController</string>
+ <object class="IBToOneOutletInfo" key="NS.object.0">
+ <string key="name">mJoysticksController</string>
+ <string key="candidateClassName">NSArrayController</string>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/JoystickPaneController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">KeyboardPaneController</string>
+ <string key="superclassName">NSObject</string>
+ <dictionary class="NSMutableDictionary" key="outlets">
+ <string key="mKeyboardEventsController">NSArrayController</string>
+ <string key="mKeyboardsController">NSArrayController</string>
+ </dictionary>
+ <dictionary class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <object class="IBToOneOutletInfo" key="mKeyboardEventsController">
+ <string key="name">mKeyboardEventsController</string>
+ <string key="candidateClassName">NSArrayController</string>
+ </object>
+ <object class="IBToOneOutletInfo" key="mKeyboardsController">
+ <string key="name">mKeyboardsController</string>
+ <string key="candidateClassName">NSArrayController</string>
+ </object>
+ </dictionary>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/KeyboardPaneController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">MousePaneController</string>
+ <string key="superclassName">NSObject</string>
+ <object class="NSMutableDictionary" key="outlets">
+ <string key="NS.key.0">mMiceController</string>
+ <string key="NS.object.0">NSArrayController</string>
+ </object>
+ <object class="NSMutableDictionary" key="toOneOutletInfosByName">
+ <string key="NS.key.0">mMiceController</string>
+ <object class="IBToOneOutletInfo" key="NS.object.0">
+ <string key="name">mMiceController</string>
+ <string key="candidateClassName">NSArrayController</string>
+ </object>
+ </object>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/MousePaneController.h</string>
+ </object>
+ </object>
+ <object class="IBPartialClassDescription">
+ <string key="className">RemoteFeedbackView</string>
+ <string key="superclassName">NSView</string>
+ <object class="IBClassDescriptionSource" key="sourceIdentifier">
+ <string key="majorKey">IBProjectSource</string>
+ <string key="minorKey">./Classes/RemoteFeedbackView.h</string>
+ </object>
+ </object>
+ </array>
+ </object>
+ <int key="IBDocument.localizationMode">0</int>
+ <string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
+ <object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">
+ <string key="NS.key.0">com.apple.InterfaceBuilder.CocoaPlugin.macosx</string>
+ <integer value="1070" key="NS.object.0"/>
+ </object>
+ <bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
+ <int key="IBDocument.defaultPropertyAccessControl">3</int>
+ <dictionary class="NSMutableDictionary" key="IBDocument.LastKnownImageSizes">
+ <string key="NSMenuCheckmark">{11, 11}</string>
+ <string key="NSMenuMixedState">{10, 3}</string>
+ </dictionary>
+ </data>
+</archive>
diff --git a/device_test/English.lproj/MainMenu.nib/keyedobjects.nib b/device_test/English.lproj/MainMenu.nib/keyedobjects.nib
new file mode 100644
index 0000000..8158386
--- /dev/null
+++ b/device_test/English.lproj/MainMenu.nib/keyedobjects.nib
Binary files differ
diff --git a/device_test/Info.plist b/device_test/Info.plist
new file mode 100644
index 0000000..db90f92
--- /dev/null
+++ b/device_test/Info.plist
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>org.dribin.dave.ddhidlib.HIDDeviceTest</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>${CURRENT_PROJECT_VERSION}</string>
+ <key>CFBundleShortVersionString</key>
+ <string>${CURRENT_MARKETING_VERSION}</string>
+ <key>NSMainNibFile</key>
+ <string>MainMenu</string>
+ <key>NSPrincipalClass</key>
+ <string>NSApplication</string>
+</dict>
+</plist>
diff --git a/device_test/JoystickPaneController.h b/device_test/JoystickPaneController.h
new file mode 100644
index 0000000..38015d0
--- /dev/null
+++ b/device_test/JoystickPaneController.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import <Cocoa/Cocoa.h>
+#import "DDHidLib.h"
+
+
+@interface JoystickPaneController : NSObject
+{
+ IBOutlet NSArrayController * mJoysticksController;
+
+ NSArray * mJoysticks;
+ NSMutableArray * mJoystickButtons;
+ int mXAxis;
+ int mYAxis;
+ unsigned mJoystickIndex;
+
+ // Don't retain these
+ DDHidJoystick * mCurrentJoystick;
+}
+
+- (NSArray *) joysticks;
+
+- (NSArray *) joystickButtons;
+
+- (unsigned) joystickIndex;
+- (void) setJoystickIndex: (unsigned) theJoystickIndex;
+
+- (int) xAxis;
+- (int) yAxis;
+
+- (void) ddhidJoystick: (DDHidJoystick *) joystick
+ stick: (unsigned) stick
+ xChanged: (int) value;
+
+- (void) ddhidJoystick: (DDHidJoystick *) joystick
+ stick: (unsigned) stick
+ yChanged: (int) value;
+
+- (void) ddhidJoystick: (DDHidJoystick *) joystick
+ stick: (unsigned) stick
+ otherAxis: (unsigned) otherAxis
+ valueChanged: (int) value;
+
+- (void) ddhidJoystick: (DDHidJoystick *) joystick
+ buttonDown: (unsigned) buttonNumber;
+
+- (void) ddhidJoystick: (DDHidJoystick *) joystick
+ buttonUp: (unsigned) buttonNumber;
+
+@end
diff --git a/device_test/JoystickPaneController.m b/device_test/JoystickPaneController.m
new file mode 100644
index 0000000..52dd949
--- /dev/null
+++ b/device_test/JoystickPaneController.m
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import "JoystickPaneController.h"
+#import "DDHidJoystick.h"
+#import "ButtonState.h"
+
+@interface JoystickPaneController (Private)
+
+- (void) setJoysticks: (NSArray *) theJoysticks;
+
+@end
+
+@implementation JoystickPaneController
+
+- (void) awakeFromNib;
+{
+ NSArray * joysticks = [DDHidJoystick allJoysticks];
+
+ mJoystickButtons = [[NSMutableArray alloc] init];
+ [joysticks makeObjectsPerformSelector: @selector(setDelegate:)
+ withObject: self];
+ [self setJoysticks: joysticks];
+ if ([mJoysticks count] > 0)
+ [self setJoystickIndex: 0];
+ else
+ [self setJoystickIndex: NSNotFound];
+}
+
+//===========================================================
+// joysticks
+//===========================================================
+- (NSArray *) joysticks
+{
+ return mJoysticks;
+}
+
+- (NSArray *) joystickButtons;
+{
+ return mJoystickButtons;
+}
+
+//===========================================================
+// joystickIndex
+//===========================================================
+- (unsigned) joystickIndex
+{
+ return mJoystickIndex;
+}
+
+- (void) setJoystickIndex: (unsigned) theJoystickIndex
+{
+ if (mCurrentJoystick != nil)
+ {
+ [mCurrentJoystick stopListening];
+ mCurrentJoystick = nil;
+ }
+ mJoystickIndex = theJoystickIndex;
+ [mJoysticksController setSelectionIndex: mJoystickIndex];
+ if (mJoystickIndex != NSNotFound)
+ {
+ mCurrentJoystick = [mJoysticks objectAtIndex: mJoystickIndex];
+ [mCurrentJoystick startListening];
+
+ [self willChangeValueForKey: @"joystickButtons"];
+ [mJoystickButtons removeAllObjects];
+ NSArray * buttons = [mCurrentJoystick buttonElements];
+ NSEnumerator * e = [buttons objectEnumerator];
+ DDHidElement * element;
+ while (element = [e nextObject])
+ {
+ ButtonState * state = [[ButtonState alloc] initWithName: [[element usage] usageName]];
+ [state autorelease];
+ [mJoystickButtons addObject: state];
+ }
+ [self didChangeValueForKey: @"joystickButtons"];
+ }
+}
+
+- (int) xAxis;
+{
+ return mXAxis;
+}
+
+- (int) yAxis;
+{
+ return mYAxis;
+}
+
+- (void) ddhidJoystick: (DDHidJoystick *) joystick
+ stick: (unsigned) stick
+ xChanged: (int) value;
+{
+ [self willChangeValueForKey: @"xAxis"];
+ mXAxis = value;
+ [self didChangeValueForKey: @"xAxis"];
+}
+
+- (void) ddhidJoystick: (DDHidJoystick *) joystick
+ stick: (unsigned) stick
+ yChanged: (int) value;
+{
+ [self willChangeValueForKey: @"yAxis"];
+ mYAxis = value;
+ [self didChangeValueForKey: @"yAxis"];
+}
+
+- (void) ddhidJoystick: (DDHidJoystick *) joystick
+ stick: (unsigned) stick
+ otherAxis: (unsigned) otherAxis
+ valueChanged: (int) value;
+{
+ // Somehow display values here
+ NSLog(@"Stick: %d, other axis: %d, changed: %d", stick, otherAxis, value);
+}
+
+- (void) ddhidJoystick: (DDHidJoystick *) joystick
+ stick: (unsigned) stick
+ povNumber: (unsigned) povNumber
+ valueChanged: (int) value;
+{
+ // Somehow display values here
+ NSLog(@"Stick: %d, POV number: %d, changed: %d", stick, povNumber, value);
+}
+
+- (void) ddhidJoystick: (DDHidJoystick *) joystick
+ buttonDown: (unsigned) buttonNumber;
+{
+ ButtonState * state = [mJoystickButtons objectAtIndex: buttonNumber];
+ [state setPressed: YES];
+}
+
+- (void) ddhidJoystick: (DDHidJoystick *) joystick
+ buttonUp: (unsigned) buttonNumber;
+{
+ ButtonState * state = [mJoystickButtons objectAtIndex: buttonNumber];
+ [state setPressed: NO];
+}
+
+@end
+
+@implementation JoystickPaneController (Private)
+
+- (void) setJoysticks: (NSArray *) theJoysticks
+{
+ if (mJoysticks != theJoysticks)
+ {
+ [mJoysticks release];
+ mJoysticks = [theJoysticks retain];
+ }
+}
+
+@end
diff --git a/device_test/KeyboardPaneController.h b/device_test/KeyboardPaneController.h
new file mode 100644
index 0000000..b42db30
--- /dev/null
+++ b/device_test/KeyboardPaneController.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+
+@class DDHidKeyboard;
+
+@interface KeyboardPaneController : NSObject
+{
+ IBOutlet NSArrayController * mKeyboardsController;
+ IBOutlet NSArrayController * mKeyboardEventsController;
+
+ NSArray * mKeyboards;
+ unsigned mKeyboardIndex;
+ NSMutableArray * mEvents;
+
+ // Don't retain these
+ DDHidKeyboard * mCurrentKeyboard;
+}
+
+- (NSArray *) keyboards;
+- (void) setKeyboards: (NSArray *) theKeyboards;
+
+- (unsigned) keyboardIndex;
+- (void) setKeyboardIndex: (unsigned) theKeyboardIndex;
+
+- (NSMutableArray *) events;
+- (void) setEvents: (NSMutableArray *) theEvents;
+- (void) addEvent: (id)theEvent;
+- (void) removeEvent: (id)theEvent;
+
+@end
+
+@interface KeyboardPaneController (DDHidKeyboardDelegate)
+
+- (void) ddhidKeyboard: (DDHidKeyboard *) keyboard
+ keyDown: (unsigned) usageId;
+
+- (void) ddhidKeyboard: (DDHidKeyboard *) keyboard
+ keyUp: (unsigned) usageId;
+
+@end
diff --git a/device_test/KeyboardPaneController.m b/device_test/KeyboardPaneController.m
new file mode 100644
index 0000000..1f8730e
--- /dev/null
+++ b/device_test/KeyboardPaneController.m
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import "KeyboardPaneController.h"
+#import "DDHidLib.h"
+#include <IOKit/hid/IOHIDUsageTables.h>
+
+@interface KeyboardPaneController (Private)
+
+- (void) addEvent: (NSString *) event usageId: (unsigned) usageId;
+
+@end
+
+@implementation KeyboardPaneController
+
+- (id) init;
+{
+ self = [super init];
+ if (self == nil)
+ return nil;
+
+ mEvents = [[NSMutableArray alloc] init];
+
+ return self;
+}
+
+- (void) awakeFromNib;
+{
+ NSArray * keyboards = [DDHidKeyboard allKeyboards];
+
+ [keyboards makeObjectsPerformSelector: @selector(setDelegate:)
+ withObject: self];
+ [self setKeyboards: keyboards];
+
+ if ([keyboards count] > 0)
+ [self setKeyboardIndex: 0];
+ else
+ [self setKeyboardIndex: NSNotFound];
+}
+
+//===========================================================
+// dealloc
+//===========================================================
+- (void) dealloc
+{
+ [mKeyboards release];
+ [mEvents release];
+
+ mKeyboards = nil;
+ mEvents = nil;
+ [super dealloc];
+}
+
+//===========================================================
+// keyboards
+//===========================================================
+- (NSArray *) keyboards
+{
+ return mKeyboards;
+}
+
+- (void) setKeyboards: (NSArray *) theKeyboards
+{
+ if (mKeyboards != theKeyboards)
+ {
+ [mKeyboards release];
+ mKeyboards = [theKeyboards retain];
+ }
+}
+//===========================================================
+// keyboardIndex
+//===========================================================
+- (unsigned) keyboardIndex
+{
+ return mKeyboardIndex;
+}
+
+- (void) setKeyboardIndex: (unsigned) theKeyboardIndex
+{
+ if (mCurrentKeyboard != nil)
+ {
+ [mCurrentKeyboard stopListening];
+ mCurrentKeyboard = nil;
+ }
+ mKeyboardIndex = theKeyboardIndex;
+ [mKeyboardsController setSelectionIndex: mKeyboardIndex];
+ [self willChangeValueForKey: @"events"];
+ [mEvents removeAllObjects];
+ [self didChangeValueForKey: @"events"];
+ if (mKeyboardIndex != NSNotFound)
+ {
+ mCurrentKeyboard = [mKeyboards objectAtIndex: mKeyboardIndex];
+ [mCurrentKeyboard startListening];
+ }
+}
+
+//===========================================================
+// events
+//===========================================================
+- (NSMutableArray *) events
+{
+ return mEvents;
+}
+
+- (void) setEvents: (NSMutableArray *) theEvents
+{
+ if (mEvents != theEvents)
+ {
+ [mEvents release];
+ mEvents = [theEvents retain];
+ }
+}
+- (void) addEvent: (id)theEvent
+{
+ [[self events] addObject: theEvent];
+}
+- (void) removeEvent: (id)theEvent
+{
+ [[self events] removeObject: theEvent];
+}
+
+
+@end
+
+@implementation KeyboardPaneController (DDHidKeyboardDelegate)
+
+- (void) ddhidKeyboard: (DDHidKeyboard *) keyboard
+ keyDown: (unsigned) usageId;
+{
+ [self addEvent: @"Key Down" usageId: usageId];
+}
+
+- (void) ddhidKeyboard: (DDHidKeyboard *) keyboard
+ keyUp: (unsigned) usageId;
+{
+ [self addEvent: @"Key Up" usageId: usageId];
+}
+
+@end
+
+@implementation KeyboardPaneController (Private)
+
+- (void) addEvent: (NSString *) event usageId: (unsigned) usageId;
+{
+ DDHidUsageTables * usageTables = [DDHidUsageTables standardUsageTables];
+ NSString * description = [NSString stringWithFormat: @"%@ (0x%04X)",
+ [usageTables descriptionForUsagePage: kHIDPage_KeyboardOrKeypad
+ usage: usageId],
+ usageId];
+
+ NSMutableDictionary * row = [mKeyboardEventsController newObject];
+ [row setObject: event forKey: @"event"];
+ [row setObject: description forKey: @"description"];
+ [mKeyboardEventsController addObject: row];
+}
+
+@end
+
diff --git a/device_test/MousePaneController.h b/device_test/MousePaneController.h
new file mode 100644
index 0000000..031aae1
--- /dev/null
+++ b/device_test/MousePaneController.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+@class DDHidQueue;
+@class DDHidMouse;
+
+@interface MousePaneController : NSObject
+{
+ IBOutlet NSArrayController * mMiceController;
+ NSArray * mMice;
+ DDHidMouse * mCurrentMouse;
+
+ unsigned mMouseIndex;
+ int mMouseX;
+ int mMouseY;
+ int mMouseWheel;
+ NSMutableArray * mMouseButtons;
+}
+
+- (BOOL) no;
+
+- (NSArray *) mice;
+- (void) setMice: (NSArray *) newMice;
+
+- (NSArray *) mouseButtons;
+
+- (unsigned) mouseIndex;
+- (void) setMouseIndex: (unsigned) theMouseIndex;
+
+- (int) maxValue;
+
+- (int) mouseX;
+
+- (int) mouseY;
+
+- (int) mouseWheel;
+
+- (void) ddhidMouse: (DDHidMouse *) mouse xChanged: (SInt32) deltaX;
+- (void) ddhidMouse: (DDHidMouse *) mouse yChanged: (SInt32) deltaY;
+- (void) ddhidMouse: (DDHidMouse *) mouse wheelChanged: (SInt32) deltaWheel;
+
+- (void) ddhidMouse: (DDHidMouse *) mouse buttonDown: (unsigned) buttonNumber;
+- (void) ddhidMouse: (DDHidMouse *) mouse buttonUp: (unsigned) buttonNumber;
+
+@end
diff --git a/device_test/MousePaneController.m b/device_test/MousePaneController.m
new file mode 100644
index 0000000..74f1590
--- /dev/null
+++ b/device_test/MousePaneController.m
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import "MousePaneController.h"
+#import "DDHidLib.h"
+#import "ButtonState.h"
+
+
+@interface MousePaneController (Private)
+
+- (void) setMouseX: (int) mouseX;
+- (void) setMouseY: (int) mouseY;
+- (void) setMouseWheel: (int) mouseWheel;
+
+@end
+
+@implementation MousePaneController
+
+static int sMaxValue = 2500;
+
+static int applyDelta(int current, int delta)
+{
+ int newValue = (current + delta) % sMaxValue;
+ if (newValue < 0)
+ newValue = sMaxValue + newValue;
+ return newValue;
+}
+
+- (void) awakeFromNib;
+{
+ mCurrentMouse = 0;
+ mMouseButtons = [[NSMutableArray alloc] init];
+
+ NSArray * mice = [DDHidMouse allMice];
+ [mice makeObjectsPerformSelector: @selector(setDelegate:)
+ withObject: self];
+ [self setMice: mice];
+ [self setMouseIndex: 0];
+}
+
+//===========================================================
+// mice
+//===========================================================
+- (NSArray *) mice
+{
+ return mMice;
+}
+
+- (void) setMice: (NSArray *) theMice
+{
+ if (mMice != theMice)
+ {
+ [mMice release];
+ mMice = [theMice retain];
+ }
+}
+
+- (NSArray *) mouseButtons;
+{
+ return mMouseButtons;
+}
+
+- (BOOL) no;
+{
+ return NO;
+}
+
+//===========================================================
+// - mouseIndex
+//===========================================================
+- (unsigned) mouseIndex
+{
+ return mMouseIndex;
+}
+
+//===========================================================
+// - setMouseIndex:
+//===========================================================
+- (void) setMouseIndex: (unsigned) theMouseIndex
+{
+ if (mCurrentMouse != nil)
+ {
+ [mCurrentMouse stopListening];
+ mCurrentMouse = nil;
+ }
+ mMouseIndex = theMouseIndex;
+ [mMiceController setSelectionIndex: mMouseIndex];
+ if (mMouseIndex != NSNotFound)
+ {
+ mCurrentMouse = [mMice objectAtIndex: mMouseIndex];
+ [mCurrentMouse startListening];
+ [self setMouseX: sMaxValue/2];
+ [self setMouseY: sMaxValue/2];
+ [self setMouseWheel: sMaxValue/2];
+
+ [self willChangeValueForKey: @"mouseButtons"];
+ [mMouseButtons removeAllObjects];
+ NSArray * buttons = [mCurrentMouse buttonElements];
+ NSEnumerator * e = [buttons objectEnumerator];
+ DDHidElement * element;
+ while (element = [e nextObject])
+ {
+ ButtonState * state = [[ButtonState alloc] initWithName: [[element usage] usageName]];
+ [state autorelease];
+ [mMouseButtons addObject: state];
+ }
+ [self didChangeValueForKey: @"mouseButtons"];
+ }
+}
+
+- (int) maxValue;
+{
+ return sMaxValue;
+}
+
+//===========================================================
+// - mouseX
+//===========================================================
+- (int) mouseX
+{
+ return mMouseX;
+}
+
+//===========================================================
+// - mouseY
+//===========================================================
+- (int) mouseY
+{
+ return mMouseY;
+}
+
+//===========================================================
+// - mouseWheel
+//===========================================================
+- (int) mouseWheel
+{
+ return mMouseWheel;
+}
+
+- (void) ddhidMouse: (DDHidMouse *) mouse xChanged: (SInt32) deltaX;
+{
+ [self setMouseX: applyDelta(mMouseX, deltaX)];
+}
+
+- (void) ddhidMouse: (DDHidMouse *) mouse yChanged: (SInt32) deltaY;
+{
+ [self setMouseY: applyDelta(mMouseY, deltaY)];
+}
+
+- (void) ddhidMouse: (DDHidMouse *) mouse wheelChanged: (SInt32) deltaWheel;
+{
+ // Some wheels only output -1 or +1, some output a more analog value.
+ // Normalize wheel to -1%/+1% movement.
+ deltaWheel = (deltaWheel/abs(deltaWheel))*(sMaxValue/100);
+ [self setMouseWheel: applyDelta(mMouseWheel, deltaWheel)];
+}
+
+- (void) ddhidMouse: (DDHidMouse *) mouse buttonDown: (unsigned) buttonNumber;
+{
+ ButtonState * state = [mMouseButtons objectAtIndex: buttonNumber];
+ [state setPressed: YES];
+}
+
+- (void) ddhidMouse: (DDHidMouse *) mouse buttonUp: (unsigned) buttonNumber;
+{
+ ButtonState * state = [mMouseButtons objectAtIndex: buttonNumber];
+ [state setPressed: NO];
+}
+
+@end
+
+@implementation MousePaneController (Private)
+
+- (void) setMouseX: (int) mouseX;
+{
+ mMouseX = mouseX;
+}
+
+- (void) setMouseY: (int) mouseY;
+{
+ mMouseY = mouseY;
+}
+
+- (void) setMouseWheel: (int) mouseWheel;
+{
+ mMouseWheel = mouseWheel;
+}
+
+@end
+
diff --git a/device_test/RemoteFeedbackView.h b/device_test/RemoteFeedbackView.h
new file mode 100644
index 0000000..767e5d6
--- /dev/null
+++ b/device_test/RemoteFeedbackView.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+// Based on Martin Kahr's Apple Remote wrapper
+// http://www.martinkahr.com/source-code/
+
+#import <Cocoa/Cocoa.h>
+#import "DDHidAppleRemote.h"
+
+@interface RemoteFeedbackView : NSView
+{
+ NSImage* remoteImage;
+ DDHidAppleRemoteEventIdentifier lastButtonIdentifier;
+ BOOL drawn;
+ BOOL clearAfterDraw;
+}
+
+- (void) ddhidAppleRemoteButton: (DDHidAppleRemoteEventIdentifier)buttonIdentifier
+ pressedDown: (BOOL) pressedDown;
+
+@end
diff --git a/device_test/RemoteFeedbackView.m b/device_test/RemoteFeedbackView.m
new file mode 100644
index 0000000..acfdf3c
--- /dev/null
+++ b/device_test/RemoteFeedbackView.m
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+// Based on Martin Kahr's Apple Remote wrapper
+// http://www.martinkahr.com/source-code/
+
+#import "RemoteFeedbackView.h"
+
+@implementation RemoteFeedbackView
+
+- (id)initWithFrame:(NSRect)frameRect
+{
+ if ((self = [super initWithFrame:frameRect]) != nil) {
+ remoteImage = [[NSImage imageNamed:@"AppleRemote"] retain];
+ lastButtonIdentifier = -1;
+ }
+ return self;
+}
+
+- (void) dealloc {
+
+ [remoteImage release];
+ [super dealloc];
+}
+
+- (void) clearAfterRedraw: (id) sender
+{
+ clearAfterDraw = NO;
+ [self ddhidAppleRemoteButton: lastButtonIdentifier pressedDown: NO];
+}
+
+- (void) ddhidAppleRemoteButton: (DDHidAppleRemoteEventIdentifier)buttonIdentifier
+ pressedDown: (BOOL) pressedDown;
+{
+
+ clearAfterDraw = NO;
+
+ if (pressedDown) {
+ lastButtonIdentifier = buttonIdentifier;
+ } else {
+ if (drawn)
+ lastButtonIdentifier = -1;
+ else {
+ lastButtonIdentifier = buttonIdentifier;
+ clearAfterDraw = YES;
+ }
+ }
+
+ drawn = NO;
+ [self setNeedsDisplay:YES];
+}
+
+- (void)drawRect:(NSRect)rect
+{
+ drawn = YES;
+ NSRect imageRect;
+ NSRect drawingRect;
+ imageRect.origin = NSZeroPoint;
+ imageRect.size = [remoteImage size];
+
+ int x = ([self bounds].size.width - [remoteImage size].width)/2;
+ int y = ([self bounds].size.height - [remoteImage size].height)/2;
+
+ drawingRect.origin = NSMakePoint(x, y);
+ drawingRect.size = imageRect.size;
+
+ [remoteImage drawInRect: drawingRect
+ fromRect: imageRect
+ operation: NSCompositeSourceOver
+ fraction: 1.0];
+
+
+ if (lastButtonIdentifier == -1) {
+ return;
+ }
+
+ DDHidAppleRemoteEventIdentifier buttonToSelect = lastButtonIdentifier;
+
+ NSPoint buttonPos;
+ float opacity = 0.5;
+
+ switch(buttonToSelect) {
+ case kDDHidRemoteButtonVolume_Plus:
+ buttonPos.x = 53;
+ buttonPos.y = 240;
+ break;
+ case kDDHidRemoteButtonVolume_Minus:
+ buttonPos.x = 53;
+ buttonPos.y = 180;
+ break;
+ case kDDHidRemoteButtonMenu_Hold:
+ opacity = 0.8;
+ case kDDHidRemoteButtonMenu:
+ buttonPos.x = 53;
+ buttonPos.y = 137;
+ clearAfterDraw = YES;
+ break;
+ case kDDHidRemoteButtonPlay_Sleep:
+ opacity = 0.8;
+ case kDDHidRemoteButtonPlay:
+ buttonPos.x = 53;
+ buttonPos.y = 210;
+ clearAfterDraw = YES;
+ break;
+ case kDDHidRemoteButtonRight_Hold:
+ opacity = 0.8;
+ buttonPos.x = 83;
+ buttonPos.y = 210;
+ break;
+ case kDDHidRemoteButtonRight:
+ buttonPos.x = 83;
+ buttonPos.y = 210;
+ clearAfterDraw = YES;
+ break;
+ case kDDHidRemoteButtonLeft_Hold:
+ opacity = 0.8;
+ buttonPos.x = 23;
+ buttonPos.y = 210;
+ break;
+ case kDDHidRemoteButtonLeft:
+ buttonPos.x = 23;
+ buttonPos.y = 210;
+ clearAfterDraw = YES;
+ break;
+ default:
+ break;
+ }
+
+ float width = 20.0;
+ float height= 20.0;
+ NSRect r = NSMakeRect(buttonPos.x + x - (width/2), buttonPos.y + y - (height/2), width, height);
+ NSBezierPath* bp = [NSBezierPath bezierPathWithOvalInRect:r];
+
+ [[NSColor colorWithCalibratedRed:1.0 green:0.0 blue:0.0 alpha:opacity] set];
+ [bp fill];
+ if (clearAfterDraw) {
+ [self performSelector:@selector(clearAfterRedraw:) withObject:self afterDelay:0.1];
+ }
+}
+
+@end
diff --git a/device_test/main.m b/device_test/main.m
new file mode 100644
index 0000000..f05b99f
--- /dev/null
+++ b/device_test/main.m
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+int main(int argc, char *argv[])
+{
+ return NSApplicationMain(argc, (const char **) argv);
+}
diff --git a/header.c b/header.c
new file mode 100644
index 0000000..ddd2f75
--- /dev/null
+++ b/header.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
diff --git a/lib/DDHidAppleMikey.h b/lib/DDHidAppleMikey.h
new file mode 100644
index 0000000..c6bea0d
--- /dev/null
+++ b/lib/DDHidAppleMikey.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import <Cocoa/Cocoa.h>
+#import "DDHidDevice.h"
+
+@class DDHidElement;
+@class DDHidQueue;
+
+@interface DDHidAppleMikey : DDHidDevice
+{
+ NSMutableArray * mPressElements;
+
+ id mDelegate;
+}
+
++ (NSArray *) allMikeys;
+
+- (id) initWithDevice: (io_object_t) device error: (NSError **) error_;
+
+#pragma mark -
+#pragma mark Elements
+
+- (NSArray *) pressElements;
+
+- (unsigned) numberOfKeys;
+
+- (void) addElementsToQueue: (DDHidQueue *) queue;
+
+#pragma mark -
+#pragma mark Asynchronous Notification
+
+- (void) setDelegate: (id) delegate;
+
+- (void) addElementsToDefaultQueue;
+
+@end
+
+@interface NSObject (DDHidAppleMikeyDelegate)
+
+- (void) ddhidAppleMikey: (DDHidAppleMikey *) mikey
+ press: (unsigned) usageId
+ upOrDown:(BOOL)upOrDown;
+
+@end
diff --git a/lib/DDHidAppleMikey.m b/lib/DDHidAppleMikey.m
new file mode 100644
index 0000000..b0da05f
--- /dev/null
+++ b/lib/DDHidAppleMikey.m
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import "DDHidAppleMikey.h"
+#import "DDHidElement.h"
+#import "DDHidUsage.h"
+#import "DDHidQueue.h"
+#import "DDHidEvent.h"
+#include <IOKit/hid/IOHIDUsageTables.h>
+
+@interface DDHidAppleMikey (DDHidAppleMikeyDelegate)
+
+- (void) ddhidAppleMikey: (DDHidAppleMikey *) mikey
+ press: (unsigned) usageId
+ upOrDown:(BOOL)upOrDown;
+
+@end
+
+@interface DDHidAppleMikey (Private)
+
+- (void) initPressElements: (NSArray *) elements;
+- (void) ddhidQueueHasEvents: (DDHidQueue *) hidQueue;
+
+@end
+
+@implementation DDHidAppleMikey
+
++ (NSArray *) allMikeys;
+{
+ //add mikey
+ CFMutableDictionaryRef hidMatchDictionary =
+ IOServiceMatching(kIOHIDDeviceKey);
+ id a2 = [self allDevicesMatchingCFDictionary: hidMatchDictionary
+ withClass: self
+ skipZeroLocations: NO];
+ a2 = [a2 filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"productName == \"Apple Mikey HID Driver\""]];
+
+ return a2;
+}
+
+- (id) initWithDevice: (io_object_t) device error: (NSError **) error_;
+{
+ self = [super initWithDevice: device error: error_];
+ if (self == nil)
+ return nil;
+
+ mPressElements = [[NSMutableArray alloc] init];
+ [self initPressElements: [self elements]];
+
+ return self;
+}
+
+//===========================================================
+// dealloc
+//===========================================================
+- (void) dealloc
+{
+ [mPressElements release];
+
+ mPressElements = nil;
+ [super dealloc];
+}
+
+#pragma mark -
+#pragma mark Elements
+
+- (NSArray *) pressElements;
+{
+ return mPressElements;
+}
+
+- (unsigned) numberOfKeys;
+{
+ return [mPressElements count];
+}
+
+- (void) addElementsToQueue: (DDHidQueue *) queue;
+{
+ [queue addElements: mPressElements];
+}
+
+#pragma mark -
+#pragma mark Asynchronous Notification
+
+- (void) setDelegate: (id) delegate;
+{
+ mDelegate = delegate;
+}
+
+- (void) addElementsToDefaultQueue;
+{
+ [self addElementsToQueue: mDefaultQueue];
+}
+
+@end
+
+@implementation DDHidAppleMikey (DDHidAppleMikeyDelegate)
+
+- (void) ddhidAppleMikey:(DDHidAppleMikey *)mikey press:(unsigned int)usageId upOrDown:(BOOL)upOrDown
+{
+ if ([mDelegate respondsToSelector: _cmd])
+ [mDelegate ddhidAppleMikey: mikey press: usageId upOrDown:(BOOL)upOrDown];
+}
+
+@end
+
+@implementation DDHidAppleMikey (Private)
+
+- (void) initPressElements: (NSArray *) elements;
+{
+ NSEnumerator * e = [elements objectEnumerator];
+ DDHidElement * element;
+ while (element = [e nextObject])
+ {
+// unsigned usagePage = [[element usage] usagePage];
+// unsigned usageId = [[element usage] usageId];
+// if (usagePage == kHIDPage_KeyboardOrKeypad)
+// {
+// if ((usageId >= 0x04) && (usageId <= 0xA4) ||
+// (usageId >= 0xE0) && (usageId <= 0xE7))
+ {
+ [mPressElements addObject: element];
+ }
+// }
+ NSArray * subElements = [element elements];
+ if (subElements != nil)
+ [self initPressElements: subElements];
+ }
+}
+
+- (void) ddhidQueueHasEvents: (DDHidQueue *) hidQueue;
+{
+ DDHidEvent * event;
+ while (event = [hidQueue nextEvent])
+ {
+ DDHidElement * element = [self elementForCookie: [event elementCookie]];
+ unsigned usageId = [[element usage] usageId];
+ SInt32 value = [event value];
+ [self ddhidAppleMikey:self press:usageId upOrDown:value==1];
+ }
+}
+
+@end
diff --git a/lib/DDHidAppleRemote.h b/lib/DDHidAppleRemote.h
new file mode 100644
index 0000000..f6bc8ef
--- /dev/null
+++ b/lib/DDHidAppleRemote.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+#import "DDHidDevice.h"
+
+@class DDHidElement;
+
+enum DDHidAppleRemoteEventIdentifier
+{
+ kDDHidRemoteButtonVolume_Plus=0,
+ kDDHidRemoteButtonVolume_Minus,
+ kDDHidRemoteButtonMenu,
+ kDDHidRemoteButtonPlay,
+ kDDHidRemoteButtonRight,
+ kDDHidRemoteButtonLeft,
+ kDDHidRemoteButtonRight_Hold,
+ kDDHidRemoteButtonLeft_Hold,
+ kDDHidRemoteButtonMenu_Hold,
+ kDDHidRemoteButtonPlay_Sleep,
+ kDDHidRemoteControl_Switched,
+ kDDHidRemoteControl_Paired,
+};
+typedef enum DDHidAppleRemoteEventIdentifier DDHidAppleRemoteEventIdentifier;
+
+@interface DDHidAppleRemote : DDHidDevice
+{
+ NSMutableDictionary * mCookieToButtonMapping;
+ NSArray * mButtonElements;
+ DDHidElement * mIdElement;
+ int mRemoteId;
+
+ id mDelegate;
+}
+
++ (NSArray *) allRemotes;
+
++ (DDHidAppleRemote *) firstRemote;
+
+- (id) initWithDevice: (io_object_t) device error: (NSError **) error_;
+
+#pragma mark -
+#pragma mark Asynchronous Notification
+
+- (void) setDelegate: (id) delegate;
+
+- (void) addElementsToDefaultQueue;
+
+#pragma mark -
+#pragma mark Properties
+
+- (int) remoteId;
+- (void) setRemoteId: (int) theRemoteId;
+
+@end
+
+@interface NSObject (DDHidAppleRemoteDelegate)
+
+- (void) ddhidAppleRemoteButton: (DDHidAppleRemoteEventIdentifier) buttonIdentifier
+ pressedDown: (BOOL) pressedDown;
+
+@end
diff --git a/lib/DDHidAppleRemote.m b/lib/DDHidAppleRemote.m
new file mode 100644
index 0000000..e8b31b2
--- /dev/null
+++ b/lib/DDHidAppleRemote.m
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+// Based on Martin Kahr's Apple Remote wrapper
+// http://www.martinkahr.com/source-code/
+
+#import "DDHidAppleRemote.h"
+#import "DDHidElement.h"
+#import "DDHidUsage.h"
+#import "DDHidQueue.h"
+#import "DDHidEvent.h"
+#import "NSDictionary+DDHidExtras.h"
+
+@interface DDHidAppleRemote (Private)
+
+- (void) initRemoteElements: (NSArray *) elements;
+
+- (void) ddhidQueueHasEvents: (DDHidQueue *) hidQueue;
+
+- (void) handleEventWithCookieString: (NSString*) cookieString
+ sumOfValues: (SInt32) sumOfValues;
+
+@end
+
+@implementation DDHidAppleRemote
+
++ (NSArray *) allRemotes;
+{
+ CFMutableDictionaryRef hidMatchDictionary =
+ IOServiceMatching("AppleIRController");
+
+ return
+ [DDHidDevice allDevicesMatchingCFDictionary: hidMatchDictionary
+ withClass: self
+ skipZeroLocations: YES];
+}
+
++ (DDHidAppleRemote *) firstRemote;
+{
+ NSArray * allRemotes = [self allRemotes];
+ if ([allRemotes count] > 0)
+ return [allRemotes objectAtIndex: 0];
+ else
+ return nil;
+}
+
+- (id) initWithDevice: (io_object_t) device error: (NSError **) error_;
+{
+ self = [super initWithDevice: device error: error_];
+ if (self == nil)
+ return nil;
+
+ mCookieToButtonMapping = [[NSMutableDictionary alloc] init];
+
+ [mCookieToButtonMapping ddhid_setInt: kDDHidRemoteButtonVolume_Plus
+ forKey: @"14_12_11_6_5_"];
+ [mCookieToButtonMapping ddhid_setInt: kDDHidRemoteButtonVolume_Plus
+ forKey: @"31_29_28_19_18_"];
+ [mCookieToButtonMapping ddhid_setInt: kDDHidRemoteButtonVolume_Minus
+ forKey: @"14_13_11_6_5_"];
+ [mCookieToButtonMapping ddhid_setInt: kDDHidRemoteButtonVolume_Minus
+ forKey: @"31_30_28_19_18_"];
+ [mCookieToButtonMapping ddhid_setInt: kDDHidRemoteButtonMenu
+ forKey: @"14_7_6_5_14_7_6_5_"];
+ [mCookieToButtonMapping ddhid_setInt: kDDHidRemoteButtonMenu
+ forKey: @"31_20_19_18_31_20_19_18_"];
+ [mCookieToButtonMapping ddhid_setInt: kDDHidRemoteButtonPlay
+ forKey: @"14_8_6_5_14_8_6_5_"];
+ [mCookieToButtonMapping ddhid_setInt: kDDHidRemoteButtonPlay
+ forKey: @"31_21_19_18_31_21_19_18_"];
+ [mCookieToButtonMapping ddhid_setInt: kDDHidRemoteButtonRight
+ forKey: @"14_9_6_5_14_9_6_5_"];
+ [mCookieToButtonMapping ddhid_setInt: kDDHidRemoteButtonRight
+ forKey: @"31_22_19_18_31_22_19_18_"];
+ [mCookieToButtonMapping ddhid_setInt: kDDHidRemoteButtonLeft
+ forKey: @"14_10_6_5_14_10_6_5_"];
+ [mCookieToButtonMapping ddhid_setInt: kDDHidRemoteButtonLeft
+ forKey: @"31_23_19_18_31_23_19_18_"];
+ [mCookieToButtonMapping ddhid_setInt: kDDHidRemoteButtonRight_Hold
+ forKey: @"14_6_5_4_2_"];
+ [mCookieToButtonMapping ddhid_setInt: kDDHidRemoteButtonRight_Hold
+ forKey: @"31_19_18_4_2_"];
+ [mCookieToButtonMapping ddhid_setInt: kDDHidRemoteButtonLeft_Hold
+ forKey: @"14_6_5_3_2_"];
+ [mCookieToButtonMapping ddhid_setInt: kDDHidRemoteButtonLeft_Hold
+ forKey: @"31_19_18_3_2_"];
+ [mCookieToButtonMapping ddhid_setInt: kDDHidRemoteButtonMenu_Hold
+ forKey: @"14_6_5_14_6_5_"];
+ [mCookieToButtonMapping ddhid_setInt: kDDHidRemoteButtonMenu_Hold
+ forKey: @"31_19_18_31_19_18_"];
+ [mCookieToButtonMapping ddhid_setInt: kDDHidRemoteButtonPlay_Sleep
+ forKey: @"18_14_6_5_18_14_6_5_"];
+ [mCookieToButtonMapping ddhid_setInt: kDDHidRemoteButtonPlay_Sleep
+ forKey: @"35_31_19_18_35_31_19_18_"];
+ [mCookieToButtonMapping ddhid_setInt: kDDHidRemoteControl_Switched
+ forKey: @"19_"];
+ //[mCookieToButtonMapping ddhid_setInt: kDDHidRemoteControl_Switched
+ // forKey: @"??_"]; // unknown for 10.5
+ [mCookieToButtonMapping ddhid_setInt: kDDHidRemoteControl_Paired
+ forKey: @"15_14_6_5_15_14_6_5_"];
+ [mCookieToButtonMapping ddhid_setInt: kDDHidRemoteControl_Paired
+ forKey: @"32_31_19_18_32_31_19_18_"];
+
+ [self initRemoteElements: [self elements]];
+
+
+ return self;
+}
+
+//===========================================================
+// dealloc
+//===========================================================
+- (void) dealloc
+{
+ [mCookieToButtonMapping release];
+ [mButtonElements release];
+ [mIdElement release];
+
+ mCookieToButtonMapping = nil;
+ mButtonElements = nil;
+ mIdElement = nil;
+ [super dealloc];
+}
+
+#pragma mark -
+#pragma mark Asynchronous Notification
+
+- (void) setDelegate: (id) delegate;
+{
+ mDelegate = delegate;
+}
+
+- (void) addElementsToDefaultQueue;
+{
+ [mDefaultQueue addElements: mButtonElements];
+}
+
+#pragma mark -
+#pragma mark Properties
+
+//===========================================================
+// remoteId
+//===========================================================
+- (int) remoteId
+{
+ return mRemoteId;
+}
+
+- (void) setRemoteId: (int) theRemoteId
+{
+ mRemoteId = theRemoteId;
+}
+
+@end
+
+@implementation DDHidAppleRemote (Private)
+
+- (void) initRemoteElements: (NSArray *) elements;
+{
+ NSAssert([elements count] == 1, @"Assume only 1 top level remote element");
+ DDHidElement * consumerControlsElement = [elements objectAtIndex: 0];
+ mButtonElements = [[consumerControlsElement elements] retain];
+ DDHidElement * element;
+ NSEnumerator * e = [mButtonElements objectEnumerator];
+ while (element = [e nextObject])
+ {
+ if ([[element usage] isEqualToUsagePage: 0x0006
+ usageId: 0x0022])
+ {
+ mIdElement = [element retain];
+ }
+ }
+}
+
+- (void) ddhidQueueHasEvents: (DDHidQueue *) hidQueue;
+{
+ NSMutableString * cookieString = [NSMutableString string];
+ SInt32 sumOfValues = 0;
+
+ DDHidEvent * event;
+ while (event = [hidQueue nextEvent])
+ {
+ if ([event elementCookie] == [mIdElement cookie])
+ {
+ [self setRemoteId: [event value]];
+ }
+ else
+ {
+ sumOfValues += [event value];
+ [cookieString appendString:
+ [NSString stringWithFormat: @"%u_", [event elementCookieAsUnsigned]]];
+ }
+ }
+ [self handleEventWithCookieString: cookieString sumOfValues: sumOfValues];
+}
+
+- (void) handleEventWithCookieString: (NSString*) cookieString
+ sumOfValues: (SInt32) sumOfValues;
+{
+ NSNumber* buttonId = [mCookieToButtonMapping objectForKey: cookieString];
+ if (buttonId != nil)
+ {
+ if ([mDelegate respondsToSelector: @selector(ddhidAppleRemoteButton:pressedDown:)])
+ {
+ [mDelegate ddhidAppleRemoteButton: [buttonId intValue]
+ pressedDown: (sumOfValues>0)];
+ }
+ }
+ else
+ NSLog(@"Unknown button for cookiestring %@", cookieString);
+
+}
+
+@end
+
diff --git a/lib/DDHidDevice.h b/lib/DDHidDevice.h
new file mode 100644
index 0000000..40b9fdb
--- /dev/null
+++ b/lib/DDHidDevice.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import <Cocoa/Cocoa.h>
+#include <IOKit/IOKitLib.h>
+#include <IOKit/IOCFPlugIn.h>
+#include <IOKit/hid/IOHIDLib.h>
+#include <IOKit/hid/IOHIDKeys.h>
+
+@class DDHidUsage;
+@class DDHidElement;
+@class DDHidQueue;
+
+@interface DDHidDevice : NSObject
+{
+ io_object_t mHidDevice;
+ IOHIDDeviceInterface122** mDeviceInterface;
+
+ NSMutableDictionary * mProperties;
+ DDHidUsage * mPrimaryUsage;
+ NSMutableArray * mUsages;
+ NSArray * mElements;
+ NSMutableDictionary * mElementsByCookie;
+ BOOL mListenInExclusiveMode;
+ DDHidQueue * mDefaultQueue;
+ int mTag;
+ int mLogicalDeviceNumber;
+}
+
+- (id) initWithDevice: (io_object_t) device error: (NSError **) error;
+- (id) initLogicalWithDevice: (io_object_t) device
+ logicalDeviceNumber: (int) logicalDeviceNumber
+ error: (NSError **) error;
+- (int) logicalDeviceCount;
+
+#pragma mark -
+#pragma mark Finding Devices
+
++ (NSArray *) allDevices;
+
++ (NSArray *) allDevicesMatchingUsagePage: (unsigned) usagePage
+ usageId: (unsigned) usageId
+ withClass: (Class) hidClass
+ skipZeroLocations: (BOOL) emptyLocation;
+
++ (NSArray *) allDevicesMatchingCFDictionary: (CFDictionaryRef) matchDictionary
+ withClass: (Class) hidClass
+ skipZeroLocations: (BOOL) emptyLocation;
+
+#pragma mark -
+#pragma mark I/O Kit Objects
+
+- (io_object_t) ioDevice;
+- (IOHIDDeviceInterface122**) deviceInterface;
+
+#pragma mark -
+#pragma mark Operations
+
+- (void) open;
+- (void) openWithOptions: (UInt32) options;
+- (void) close;
+- (DDHidQueue *) createQueueWithSize: (unsigned) size;
+- (long) getElementValue: (DDHidElement *) element;
+
+#pragma mark -
+#pragma mark Asynchronous Notification
+
+- (BOOL) listenInExclusiveMode;
+- (void) setListenInExclusiveMode: (BOOL) flag;
+
+- (void) startListening;
+
+- (void) stopListening;
+
+- (BOOL) isListening;
+
+#pragma mark -
+#pragma mark Properties
+
+- (NSDictionary *) properties;
+
+- (NSArray *) elements;
+- (DDHidElement *) elementForCookie: (IOHIDElementCookie) cookie;
+
+- (NSString *) productName;
+- (NSString *) manufacturer;
+- (NSString *) serialNumber;
+- (NSString *) transport;
+- (long) vendorId;
+- (long) productId;
+- (long) version;
+- (long) locationId;
+- (long) usagePage;
+- (long) usage;
+- (DDHidUsage *) primaryUsage;
+- (NSArray *) usages;
+
+- (NSComparisonResult) compareByLocationId: (DDHidDevice *) device;
+
+- (int) tag;
+- (void) setTag: (int) theTag;
+
+@end
+
+@interface DDHidDevice (Protected)
+
+- (unsigned) sizeOfDefaultQueue;
+- (void) addElementsToDefaultQueue;
+
+@end
diff --git a/lib/DDHidDevice.m b/lib/DDHidDevice.m
new file mode 100644
index 0000000..8000185
--- /dev/null
+++ b/lib/DDHidDevice.m
@@ -0,0 +1,585 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import "DDHidDevice.h"
+#import "DDHidUsage.h"
+#import "DDHidElement.h"
+#import "DDHidQueue.h"
+#import "NSDictionary+DDHidExtras.h"
+#import "NSXReturnThrowError.h"
+
+#include <IOKit/hid/IOHIDUsageTables.h>
+
+@interface DDHidDevice (Private)
+
++ (void) addDevice: (io_object_t) hidDevice
+ withClass: (Class) hidClass
+ skipZeroLocations: (BOOL) skipZeroLocations
+ toDeviceList: (NSMutableArray *) devices;
+
+- (BOOL) initPropertiesWithError: (NSError **) error_;
+- (BOOL) createDeviceInterfaceWithError: (NSError **) error_;
+
+@end
+
+@implementation DDHidDevice
+
+- (id) initWithDevice: (io_object_t) device error: (NSError **) error;
+{
+ return [self initLogicalWithDevice: device
+ logicalDeviceNumber: 0
+ error: error];
+}
+
+- (id) initLogicalWithDevice: (io_object_t) device
+ logicalDeviceNumber: (int) logicalDeviceNumber
+ error: (NSError **) error;
+{
+ self = [super init];
+ if (self == nil)
+ return nil;
+
+ mHidDevice = device;
+ IOObjectRetain(mHidDevice);
+
+ if (![self initPropertiesWithError: error])
+ {
+ [self release];
+ return nil;
+ }
+
+ if (![self createDeviceInterfaceWithError: error])
+ {
+ [self release];
+ return nil;
+ }
+
+ mLogicalDeviceNumber = logicalDeviceNumber;
+ mListenInExclusiveMode = NO;
+ mDefaultQueue = nil;
+ mTag = 0;
+
+ return self;
+}
+
+//===========================================================
+// dealloc
+//===========================================================
+- (void) dealloc
+{
+ [mDefaultQueue release];
+ if (mDeviceInterface != NULL)
+ {
+ (*mDeviceInterface)->close(mDeviceInterface);
+ (*mDeviceInterface)->Release(mDeviceInterface);
+ }
+ [mElementsByCookie release];
+ [mElements release];
+ [mUsages release];
+ [mPrimaryUsage release];
+ [mProperties release];
+ IOObjectRelease(mHidDevice);
+
+ mProperties = nil;
+ mDeviceInterface = NULL;
+ [super dealloc];
+}
+
+#pragma mark -
+#pragma mark Finding Devices
+
++ (NSArray *) allDevices;
+{
+ // Set up a matching dictionary to search the I/O Registry by class
+ // name for all HID class devices
+ CFMutableDictionaryRef hidMatchDictionary =
+ IOServiceMatching(kIOHIDDeviceKey);
+ return [self allDevicesMatchingCFDictionary: hidMatchDictionary
+ withClass: [DDHidDevice class]
+ skipZeroLocations: NO];
+}
+
++ (NSArray *) allDevicesMatchingUsagePage: (unsigned) usagePage
+ usageId: (unsigned) usageId
+ withClass: (Class) hidClass
+ skipZeroLocations: (BOOL) skipZeroLocations;
+{
+ // Set up a matching dictionary to search the I/O Registry by class
+ // name for all HID class devices
+ CFMutableDictionaryRef hidMatchDictionary =
+ IOServiceMatching(kIOHIDDeviceKey);
+ NSMutableDictionary * objcMatchDictionary =
+ (NSMutableDictionary *) hidMatchDictionary;
+ [objcMatchDictionary ddhid_setObject: [NSNumber numberWithUnsignedInt: usagePage]
+ forString: kIOHIDDeviceUsagePageKey];
+ [objcMatchDictionary ddhid_setObject: [NSNumber numberWithUnsignedInt: usageId]
+ forString: kIOHIDDeviceUsageKey];
+ return [self allDevicesMatchingCFDictionary: hidMatchDictionary
+ withClass: hidClass
+ skipZeroLocations: skipZeroLocations];
+}
+
++ (NSArray *) allDevicesMatchingCFDictionary: (CFDictionaryRef) matchDictionary
+ withClass: (Class) hidClass
+ skipZeroLocations: (BOOL) skipZeroLocations;
+{
+ // Now search I/O Registry for matching devices.
+ io_iterator_t hidObjectIterator = MACH_PORT_NULL;
+ NSMutableArray * devices = [NSMutableArray array];
+ @try
+ {
+ NSXThrowError(IOServiceGetMatchingServices(kIOMasterPortDefault,
+ matchDictionary,
+ &hidObjectIterator));
+
+ if (hidObjectIterator == 0)
+ return [NSArray array];
+
+ io_object_t hidDevice;
+ while (hidDevice = IOIteratorNext(hidObjectIterator))
+ {
+ [self addDevice: hidDevice
+ withClass: hidClass
+ skipZeroLocations: skipZeroLocations
+ toDeviceList: devices];
+ }
+
+ // This makes sure the array return is consistent from run to run,
+ // assuming no new devices were added.
+ [devices sortUsingSelector: @selector(compareByLocationId:)];
+ }
+ @finally
+ {
+ if (hidObjectIterator != MACH_PORT_NULL)
+ IOObjectRelease(hidObjectIterator);
+ }
+
+ return devices;
+}
+
+- (int) logicalDeviceCount;
+{
+ return 1;
+}
+
+#pragma mark -
+#pragma mark I/O Kit Objects
+
+- (io_object_t) ioDevice;
+{
+ return mHidDevice;
+}
+
+- (IOHIDDeviceInterface122**) deviceInterface;
+{
+ return mDeviceInterface;
+}
+
+#pragma mark -
+#pragma mark Operations
+
+- (void) open;
+{
+ [self openWithOptions: kIOHIDOptionsTypeNone];
+}
+
+- (void) openWithOptions: (UInt32) options;
+{
+ NSXThrowError((*mDeviceInterface)->open(mDeviceInterface, options));
+}
+
+- (void) close;
+{
+ NSXThrowError((*mDeviceInterface)->close(mDeviceInterface));
+}
+
+- (DDHidQueue *) createQueueWithSize: (unsigned) size;
+{
+ IOHIDQueueInterface ** queue =
+ (*mDeviceInterface)->allocQueue(mDeviceInterface);
+ if (queue == NULL)
+ return nil;
+ return [[[DDHidQueue alloc] initWithHIDQueue: queue
+ size: size] autorelease];
+}
+
+- (long) getElementValue: (DDHidElement *) element;
+{
+ IOHIDEventStruct event;
+ NSXThrowError((*mDeviceInterface)->getElementValue(mDeviceInterface,
+ [element cookie],
+ &event));
+ return event.value;
+}
+
+#pragma mark -
+#pragma mark Asynchronous Notification
+
+//===========================================================
+// listenInExclusiveMode
+//===========================================================
+- (BOOL) listenInExclusiveMode
+{
+ return mListenInExclusiveMode;
+}
+
+- (void) setListenInExclusiveMode: (BOOL) flag
+{
+ mListenInExclusiveMode = flag;
+}
+
+- (void) startListening;
+{
+ if ([self isListening])
+ return;
+
+ UInt32 options = kIOHIDOptionsTypeNone;
+ if (mListenInExclusiveMode)
+ options = kIOHIDOptionsTypeSeizeDevice;
+ [self openWithOptions: options];
+ mDefaultQueue = [[self createQueueWithSize: [self sizeOfDefaultQueue]] retain];
+ [mDefaultQueue setDelegate: self];
+ [self addElementsToDefaultQueue];
+ [mDefaultQueue startOnCurrentRunLoop];
+}
+
+- (void) stopListening;
+{
+ if (![self isListening])
+ return;
+
+ [mDefaultQueue stop];
+ [mDefaultQueue release];
+ mDefaultQueue = nil;
+ [self close];
+}
+
+- (BOOL) isListening;
+{
+ return (mDefaultQueue != nil);
+}
+
+#pragma mark -
+#pragma mark Properties
+
+- (NSDictionary *) properties;
+{
+ return mProperties;
+}
+
+//===========================================================
+// - productName
+//===========================================================
+- (NSString *) productName
+{
+ NSString * productName = [mProperties ddhid_stringForString: kIOHIDProductKey];
+ if ([self logicalDeviceCount] > 1)
+ {
+ productName = [productName stringByAppendingString:
+ [NSString stringWithFormat:@" #%d", mLogicalDeviceNumber + 1]];
+ }
+ return productName;
+}
+
+//===========================================================
+// - manufacturer
+//===========================================================
+- (NSString *) manufacturer
+{
+ return [mProperties ddhid_stringForString: kIOHIDManufacturerKey];
+}
+
+//===========================================================
+// - serialNumber
+//===========================================================
+- (NSString *) serialNumber
+{
+ return [mProperties ddhid_stringForString: kIOHIDSerialNumberKey];
+}
+
+//===========================================================
+// - transport
+//===========================================================
+- (NSString *) transport
+{
+ return [mProperties ddhid_stringForString: kIOHIDTransportKey];
+}
+
+//===========================================================
+// - vendorId
+//===========================================================
+- (long) vendorId
+{
+ return [mProperties ddhid_longForString: kIOHIDVendorIDKey];
+}
+
+//===========================================================
+// - productId
+//===========================================================
+- (long) productId
+{
+ return [mProperties ddhid_longForString: kIOHIDProductIDKey];
+}
+
+//===========================================================
+// - version
+//===========================================================
+- (long) version
+{
+ return [mProperties ddhid_longForString: kIOHIDVersionNumberKey];
+}
+
+//===========================================================
+// - locationId
+//===========================================================
+- (long) locationId
+{
+ return [mProperties ddhid_longForString: kIOHIDLocationIDKey];
+}
+
+//===========================================================
+// - usagePage
+//===========================================================
+- (long) usagePage
+{
+ return [mProperties ddhid_longForString: kIOHIDPrimaryUsagePageKey];
+}
+
+//===========================================================
+// - usage
+//===========================================================
+- (long) usage
+{
+ return [mProperties ddhid_longForString: kIOHIDPrimaryUsageKey];
+}
+
+- (NSArray *) elements;
+{
+ return mElements;
+}
+
+- (DDHidElement *) elementForCookie: (IOHIDElementCookie) cookie;
+{
+ NSNumber * n = [NSNumber numberWithUnsignedInt: (unsigned) cookie];
+ return [mElementsByCookie objectForKey: n];
+}
+
+- (DDHidUsage *) primaryUsage;
+{
+ return mPrimaryUsage;
+}
+
+- (NSArray *) usages;
+{
+ return mUsages;
+}
+
+- (NSComparisonResult) compareByLocationId: (DDHidDevice *) device;
+{
+ long myLocationId = [self locationId];
+ long otherLocationId = [device locationId];
+ if (myLocationId < otherLocationId)
+ return NSOrderedAscending;
+ else if (myLocationId > otherLocationId)
+ return NSOrderedDescending;
+ else
+ return NSOrderedSame;
+}
+
+//===========================================================
+// tag
+//===========================================================
+- (int) tag
+{
+ return mTag;
+}
+
+- (void) setTag: (int) theTag
+{
+ mTag = theTag;
+}
+
+@end
+
+@implementation DDHidDevice (Protected)
+
+- (unsigned) sizeOfDefaultQueue;
+{
+ return 10;
+}
+
+- (void) addElementsToDefaultQueue;
+{
+ [mDefaultQueue addElements: [self elements] recursively: YES];
+}
+
+@end
+
+@implementation DDHidDevice (Private)
+
++ (void) addDevice: (io_object_t) hidDevice
+ withClass: (Class) hidClass
+ skipZeroLocations: (BOOL) skipZeroLocations
+ toDeviceList: (NSMutableArray *) devices;
+{
+ @try
+ {
+ NSError * error = nil;
+ DDHidDevice * device = [[hidClass alloc] initWithDevice: hidDevice
+ error: &error];
+ if (device == nil)
+ {
+ NSXRaiseError(error);
+ }
+ [device autorelease];
+
+ if (([device locationId] == 0) && skipZeroLocations)
+ return;
+
+ [devices addObject: device];
+
+ // Add remainnig logical devices
+ int i;
+ for (i = 1; i < [device logicalDeviceCount]; i++)
+ {
+ device = [[hidClass alloc] initLogicalWithDevice: hidDevice
+ logicalDeviceNumber: i
+ error: &error];
+
+ if (device == nil)
+ {
+ NSXRaiseError(error);
+ }
+ [device autorelease];
+
+ [devices addObject: device];
+ }
+ }
+ @finally
+ {
+ IOObjectRelease(hidDevice);
+ }
+}
+
+- (void) indexElements: (NSArray *) elements;
+{
+ NSEnumerator * e = [elements objectEnumerator];
+ DDHidElement * element;
+ while (element = [e nextObject])
+ {
+ NSNumber * n = [NSNumber numberWithUnsignedInt: [element cookieAsUnsigned]];
+ [mElementsByCookie setObject: element
+ forKey: n];
+ NSArray * children = [element elements];
+ if (children != nil)
+ [self indexElements: children];
+ }
+}
+
+- (BOOL) initPropertiesWithError: (NSError **) error_;
+{
+ NSError * error = nil;
+ BOOL result = NO;
+
+ CFMutableDictionaryRef properties;
+ NSXReturnError(IORegistryEntryCreateCFProperties(mHidDevice, &properties,
+ kCFAllocatorDefault, kNilOptions));
+ if (error)
+ goto done;
+
+ mProperties = (NSMutableDictionary *) properties;
+ NSArray * elementProperties = [mProperties ddhid_objectForString: kIOHIDElementKey];
+ mElements = [DDHidElement elementsWithPropertiesArray: elementProperties];
+ [mElements retain];
+
+ unsigned usagePage = [mProperties ddhid_unsignedIntForString: kIOHIDPrimaryUsagePageKey];
+ unsigned usageId = [mProperties ddhid_unsignedIntForString: kIOHIDPrimaryUsageKey];
+
+ mPrimaryUsage = [[DDHidUsage alloc] initWithUsagePage: usagePage
+ usageId: usageId];
+ mUsages = [[NSMutableArray alloc] init];
+
+ NSArray * usagePairs = [mProperties ddhid_objectForString: kIOHIDDeviceUsagePairsKey];
+ NSEnumerator * e = [usagePairs objectEnumerator];
+ NSDictionary * usagePair;
+ while (usagePair = [e nextObject])
+ {
+ usagePage = [usagePair ddhid_unsignedIntForString: kIOHIDDeviceUsagePageKey];
+ usageId = [usagePair ddhid_unsignedIntForString: kIOHIDDeviceUsageKey];
+ DDHidUsage * usage = [DDHidUsage usageWithUsagePage: usagePage
+ usageId: usageId];
+ [mUsages addObject: usage];
+ }
+
+ mElementsByCookie = [[NSMutableDictionary alloc] init];
+ [self indexElements: mElements];
+ result = YES;
+
+done:
+ if (error_)
+ *error_ = error;
+ return result;
+}
+
+- (BOOL) createDeviceInterfaceWithError: (NSError **) error_;
+{
+ io_name_t className;
+ IOCFPlugInInterface ** plugInInterface = NULL;
+ SInt32 score = 0;
+ NSError * error = nil;
+ BOOL result = NO;
+
+ mDeviceInterface = NULL;
+
+ NSXReturnError(IOObjectGetClass(mHidDevice, className));
+ if (error)
+ goto done;
+
+ NSXReturnError(IOCreatePlugInInterfaceForService(mHidDevice,
+ kIOHIDDeviceUserClientTypeID,
+ kIOCFPlugInInterfaceID,
+ &plugInInterface,
+ &score));
+ if (error)
+ goto done;
+
+ //Call a method of the intermediate plug-in to create the device interface
+ NSXReturnError((*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), (LPVOID) &mDeviceInterface));
+ if (error)
+ goto done;
+
+ result = YES;
+
+done:
+ if (plugInInterface != NULL)
+ {
+ (*plugInInterface)->Release(plugInInterface);
+ }
+ if (error_)
+ *error_ = error;
+ return result;
+}
+
+@end
+
diff --git a/lib/DDHidElement.h b/lib/DDHidElement.h
new file mode 100644
index 0000000..4e9577c
--- /dev/null
+++ b/lib/DDHidElement.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import <Cocoa/Cocoa.h>
+#include <IOKit/hid/IOHIDKeys.h>
+
+@class DDHidUsage;
+
+@interface DDHidElement : NSObject
+{
+ NSDictionary * mProperties;
+ DDHidUsage * mUsage;
+ NSArray * mElements;
+}
+
++ (NSArray *) elementsWithPropertiesArray: (NSArray *) propertiesArray;
+
++ (DDHidElement *) elementWithProperties: (NSDictionary *) properties;
+
+- (id) initWithProperties: (NSDictionary *) properties;
+
+- (NSDictionary *) properties;
+
+- (NSString *) stringForKey: (NSString *) key;
+
+- (NSString *) description;
+
+- (IOHIDElementCookie) cookie;
+- (unsigned) cookieAsUnsigned;
+
+- (NSArray *) elements;
+- (DDHidUsage *) usage;
+- (NSString *) name;
+- (BOOL) hasNullState;
+- (BOOL) hasPreferredState;
+- (BOOL) isArray;
+- (BOOL) isRelative;
+- (BOOL) isWrapping;
+- (long) maxValue;
+- (long) minValue;
+
+- (NSComparisonResult) compareByUsage: (DDHidElement *) device;
+
+@end
diff --git a/lib/DDHidElement.m b/lib/DDHidElement.m
new file mode 100644
index 0000000..5a00095
--- /dev/null
+++ b/lib/DDHidElement.m
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import "DDHidElement.h"
+#import "DDHidUsage.h"
+#import "NSDictionary+DDHidExtras.h"
+#include <IOKit/hid/IOHIDKeys.h>
+
+@implementation DDHidElement
+
++ (NSArray *) elementsWithPropertiesArray: (NSArray *) propertiesArray;
+{
+ NSMutableArray * elements = [NSMutableArray array];
+
+ NSDictionary * properties;
+ NSEnumerator * e = [propertiesArray objectEnumerator];
+ while (properties = [e nextObject])
+ {
+ DDHidElement * element = [DDHidElement elementWithProperties: properties];
+ [elements addObject: element];
+ }
+
+ return elements;
+}
+
++ (DDHidElement *) elementWithProperties: (NSDictionary *) properties;
+{
+ DDHidElement * element = [[DDHidElement alloc] initWithProperties: properties];
+ return [element autorelease];
+}
+
+- (id) initWithProperties: (NSDictionary *) properties;
+{
+ self = [super init];
+ if (self == nil)
+ return nil;
+
+ mProperties = [properties retain];
+ unsigned usagePage = [mProperties ddhid_unsignedIntForString: kIOHIDElementUsagePageKey];
+ unsigned usageId = [mProperties ddhid_unsignedIntForString: kIOHIDElementUsageKey];
+ mUsage = [[DDHidUsage alloc] initWithUsagePage: usagePage
+ usageId: usageId];
+
+ NSArray * elementsProperties =
+ [mProperties ddhid_objectForString: kIOHIDElementKey];
+ mElements = [[DDHidElement elementsWithPropertiesArray: elementsProperties]
+ retain];
+
+ return self;
+}
+
+//===========================================================
+// dealloc
+//===========================================================
+- (void) dealloc
+{
+ [mProperties release];
+ [mUsage release];
+ [mElements release];
+
+ mProperties = nil;
+ mUsage = nil;
+ mElements = nil;
+ [super dealloc];
+}
+
+- (NSDictionary *) properties;
+{
+ return mProperties;
+}
+
+- (NSString *) stringForKey: (NSString *) key;
+{
+ return [mProperties objectForKey: key];
+}
+
+- (NSString *) description;
+{
+ return [[self usage] usageNameWithIds];
+}
+
+- (IOHIDElementCookie) cookie;
+{
+ return (IOHIDElementCookie)
+ [mProperties ddhid_unsignedIntForString: kIOHIDElementCookieKey];
+}
+
+- (unsigned) cookieAsUnsigned;
+{
+ return [mProperties ddhid_unsignedIntForString: kIOHIDElementCookieKey];
+}
+
+- (DDHidUsage *) usage;
+{
+ return mUsage;
+}
+
+- (NSArray *) elements;
+{
+ return mElements;
+}
+
+- (NSString *) name;
+{
+ return [mProperties ddhid_objectForString: kIOHIDElementNameKey];
+}
+
+- (BOOL) hasNullState;
+{
+ return [mProperties ddhid_boolForString: kIOHIDElementHasNullStateKey];
+}
+
+- (BOOL) hasPreferredState;
+{
+ return [mProperties ddhid_boolForString: kIOHIDElementHasNullStateKey];
+}
+
+- (BOOL) isArray;
+{
+ return [mProperties ddhid_boolForString: kIOHIDElementIsArrayKey];
+}
+
+- (BOOL) isRelative;
+{
+ return [mProperties ddhid_boolForString: kIOHIDElementIsRelativeKey];
+}
+
+- (BOOL) isWrapping;
+{
+ return [mProperties ddhid_boolForString: kIOHIDElementIsWrappingKey];
+}
+
+- (long) maxValue;
+{
+ return [mProperties ddhid_longForString: kIOHIDElementMaxKey];
+}
+
+- (long) minValue;
+{
+ return [mProperties ddhid_longForString: kIOHIDElementMinKey];
+}
+
+- (NSComparisonResult) compareByUsage: (DDHidElement *) device;
+{
+ unsigned myUsagePage = [[self usage] usagePage];
+ unsigned myUsageId = [[self usage] usageId];
+
+ unsigned otherUsagePage = [[device usage] usagePage];
+ unsigned otherUsageId = [[device usage] usageId];
+
+ if (myUsagePage < otherUsagePage)
+ return NSOrderedAscending;
+ else if (myUsagePage > otherUsagePage)
+ return NSOrderedDescending;
+
+ if (myUsageId < otherUsageId)
+ return NSOrderedAscending;
+ else if (myUsageId > otherUsageId)
+ return NSOrderedDescending;
+
+ return NSOrderedSame;
+}
+
+@end
diff --git a/lib/DDHidEvent.h b/lib/DDHidEvent.h
new file mode 100644
index 0000000..0861cfd
--- /dev/null
+++ b/lib/DDHidEvent.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import <Cocoa/Cocoa.h>
+#include <IOKit/hid/IOHIDLib.h>
+
+@interface DDHidEvent : NSObject
+{
+ IOHIDEventStruct mEvent;
+}
+
++ (DDHidEvent *) eventWithIOHIDEvent: (IOHIDEventStruct *) event;
+
+- (id) initWithIOHIDEvent: (IOHIDEventStruct *) event;
+
+- (IOHIDElementType) type;
+- (IOHIDElementCookie) elementCookie;
+- (unsigned) elementCookieAsUnsigned;
+- (SInt32) value;
+- (AbsoluteTime) timestamp;
+- (UInt32) longValueSize;
+- (void *) longValue;
+
+@end
diff --git a/lib/DDHidEvent.m b/lib/DDHidEvent.m
new file mode 100644
index 0000000..8b2ab5f
--- /dev/null
+++ b/lib/DDHidEvent.m
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import "DDHidEvent.h"
+
+
+@implementation DDHidEvent
+
++ (DDHidEvent *) eventWithIOHIDEvent: (IOHIDEventStruct *) event;
+{
+ return [[[self alloc] initWithIOHIDEvent: event] autorelease];
+}
+
+- (id) initWithIOHIDEvent: (IOHIDEventStruct *) event;
+{
+ self = [super init];
+ if (self == nil)
+ return nil;
+
+ mEvent = *event;
+
+ return self;
+}
+
+- (IOHIDElementType) type;
+{
+ return mEvent.type;
+}
+
+- (IOHIDElementCookie) elementCookie;
+{
+ return mEvent.elementCookie;
+}
+
+- (unsigned) elementCookieAsUnsigned;
+{
+ return (unsigned) mEvent.elementCookie;
+}
+
+- (SInt32) value;
+{
+ return mEvent.value;
+}
+
+- (AbsoluteTime) timestamp;
+{
+ return mEvent.timestamp;
+}
+
+- (UInt32) longValueSize;
+{
+ return mEvent.longValueSize;
+}
+
+- (void *) longValue;
+{
+ return mEvent.longValue;
+}
+
+@end
diff --git a/lib/DDHidJoystick.h b/lib/DDHidJoystick.h
new file mode 100644
index 0000000..ebf20cc
--- /dev/null
+++ b/lib/DDHidJoystick.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import <Cocoa/Cocoa.h>
+#import "DDHidDevice.h"
+
+@class DDHidElement;
+@class DDHidQueue;
+
+@interface DDHidJoystickStick : NSObject
+{
+ DDHidElement * mXAxisElement;
+ DDHidElement * mYAxisElement;
+ NSMutableArray * mStickElements;
+ // Point of view elements (i.e. hat switches)
+ NSMutableArray * mPovElements;
+}
+
+- (DDHidElement *) xAxisElement;
+
+- (DDHidElement *) yAxisElement;
+
+#pragma mark -
+#pragma mark StickElements - indexed accessors
+
+- (unsigned int) countOfStickElements;
+- (DDHidElement *) objectInStickElementsAtIndex: (unsigned int)index;
+
+#pragma mark -
+#pragma mark PovElements - indexed accessors
+
+- (unsigned int) countOfPovElements;
+- (DDHidElement *) objectInPovElementsAtIndex: (unsigned int)index;
+
+- (NSArray *) allElements;
+
+- (BOOL) addElement: (DDHidElement *) element;
+
+@end
+
+@interface DDHidJoystick : DDHidDevice
+{
+ NSMutableArray * mSticks;
+ NSMutableArray * mButtonElements;
+ NSMutableArray * mLogicalDeviceElements;
+
+ id mDelegate;
+}
+
++ (NSArray *) allJoysticks;
+
+- (id) initLogicalWithDevice: (io_object_t) device
+ logicalDeviceNumber: (int) logicalDeviceNumber
+ error: (NSError **) error;
+
+- (int) logicalDeviceCount;
+
+#pragma mark -
+#pragma mark Joystick Elements
+
+- (unsigned) numberOfButtons;
+
+- (NSArray *) buttonElements;
+
+#pragma mark -
+#pragma mark Sticks - indexed accessors
+
+- (unsigned int) countOfSticks;
+- (DDHidJoystickStick *) objectInSticksAtIndex: (unsigned int)index;
+
+- (void) addElementsToQueue: (DDHidQueue *) queue;
+
+#pragma mark -
+#pragma mark Asynchronous Notification
+
+- (void) setDelegate: (id) delegate;
+
+- (void) addElementsToDefaultQueue;
+
+@end
+
+#define DDHID_JOYSTICK_VALUE_MIN -65536
+#define DDHID_JOYSTICK_VALUE_MAX 65536
+
+@interface NSObject (DDHidJoystickDelegate)
+
+- (void) ddhidJoystick: (DDHidJoystick *) joystick
+ stick: (unsigned) stick
+ xChanged: (int) value;
+
+- (void) ddhidJoystick: (DDHidJoystick *) joystick
+ stick: (unsigned) stick
+ yChanged: (int) value;
+
+- (void) ddhidJoystick: (DDHidJoystick *) joystick
+ stick: (unsigned) stick
+ otherAxis: (unsigned) otherAxis
+ valueChanged: (int) value;
+
+- (void) ddhidJoystick: (DDHidJoystick *) joystick
+ stick: (unsigned) stick
+ povNumber: (unsigned) povNumber
+ valueChanged: (int) value;
+
+- (void) ddhidJoystick: (DDHidJoystick *) joystick
+ buttonDown: (unsigned) buttonNumber;
+
+- (void) ddhidJoystick: (DDHidJoystick *) joystick
+ buttonUp: (unsigned) buttonNumber;
+
+@end
diff --git a/lib/DDHidJoystick.m b/lib/DDHidJoystick.m
new file mode 100644
index 0000000..601f9b3
--- /dev/null
+++ b/lib/DDHidJoystick.m
@@ -0,0 +1,654 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import "DDHidLib.h"
+#include <IOKit/hid/IOHIDUsageTables.h>
+
+@interface DDHidJoystick (DDHidJoystickDelegate)
+
+- (void) ddhidJoystick: (DDHidJoystick *) joystick
+ stick: (unsigned) stick
+ xChanged: (int) value;
+
+- (void) ddhidJoystick: (DDHidJoystick *) joystick
+ stick: (unsigned) stick
+ yChanged: (int) value;
+
+- (void) ddhidJoystick: (DDHidJoystick *) joystick
+ stick: (unsigned) stick
+ otherAxis: (unsigned) otherAxis
+ valueChanged: (int) value;
+
+- (void) ddhidJoystick: (DDHidJoystick *) joystick
+ stick: (unsigned) stick
+ povNumber: (unsigned) povNumber
+ valueChanged: (int) value;
+
+- (void) ddhidJoystick: (DDHidJoystick *) joystick
+ buttonDown: (unsigned) buttonNumber;
+
+- (void) ddhidJoystick: (DDHidJoystick *) joystick
+ buttonUp: (unsigned) buttonNumber;
+
+@end
+
+@interface DDHidJoystick (Private)
+
+- (void) initLogicalDeviceElements;
+- (void) initJoystickElements: (NSArray *) elements;
+- (void) addStick: (NSArray *) stickElements;
+- (void) ddhidQueueHasEvents: (DDHidQueue *) hidQueue;
+
+- (int) normalizeValue: (int) value
+ forElement: (DDHidElement *) element;
+
+- (int) povValue: (int) value
+ forElement: (DDHidElement *) element;
+
+- (BOOL) findStick: (unsigned *) stick
+ element: (DDHidElement **) elementOut
+ withXAxisCookie: (IOHIDElementCookie) cookie;
+
+- (BOOL) findStick: (unsigned *) stick
+ element: (DDHidElement **) elementOut
+ withYAxisCookie: (IOHIDElementCookie) cookie;
+
+- (BOOL) findStick: (unsigned *) stickOut
+ otherAxis: (unsigned *) axisOut
+ element: (DDHidElement **) elementOut
+ withCookie: (IOHIDElementCookie) cookie;
+
+- (BOOL) findStick: (unsigned *) stickOut
+ povNumber: (unsigned *) povNumber
+ element: (DDHidElement **) elementOut
+ withCookie: (IOHIDElementCookie) cookie;
+
+@end
+
+@implementation DDHidJoystick
+
++ (NSArray *) allJoysticks;
+{
+ NSArray * joysticks =
+ [DDHidDevice allDevicesMatchingUsagePage: kHIDPage_GenericDesktop
+ usageId: kHIDUsage_GD_Joystick
+ withClass: self
+ skipZeroLocations: YES];
+ NSArray * gamepads =
+ [DDHidDevice allDevicesMatchingUsagePage: kHIDPage_GenericDesktop
+ usageId: kHIDUsage_GD_GamePad
+ withClass: self
+ skipZeroLocations: YES];
+
+ NSMutableArray * allJoysticks = [NSMutableArray arrayWithArray: joysticks];
+ [allJoysticks addObjectsFromArray: gamepads];
+ [allJoysticks sortUsingSelector: @selector(compareByLocationId:)];
+ return allJoysticks;
+}
+
+- (id) initLogicalWithDevice: (io_object_t) device
+ logicalDeviceNumber: (int) logicalDeviceNumber
+ error: (NSError **) error;
+{
+ self = [super initLogicalWithDevice: device
+ logicalDeviceNumber: logicalDeviceNumber
+ error: error];
+ if (self == nil)
+ return nil;
+
+ mButtonElements = [[NSMutableArray alloc] init];
+ mSticks = [[NSMutableArray alloc] init];
+ mLogicalDeviceElements = [[NSMutableArray alloc] init];
+
+ [self initLogicalDeviceElements];
+ int logicalDeviceCount = [mLogicalDeviceElements count];
+ if (logicalDeviceCount == 0)
+ {
+ [self release];
+ return nil;
+ }
+
+ mLogicalDeviceNumber = logicalDeviceNumber;
+ if (mLogicalDeviceNumber >= logicalDeviceCount)
+ mLogicalDeviceNumber = logicalDeviceCount - 1;
+
+ [self initJoystickElements:
+ [mLogicalDeviceElements objectAtIndex: mLogicalDeviceNumber]];
+ [mButtonElements sortUsingSelector: @selector(compareByUsage:)];
+ mDelegate = nil;
+
+ return self;
+}
+
+//===========================================================
+// dealloc
+//===========================================================
+- (void) dealloc
+{
+ [mLogicalDeviceElements release];
+ [mSticks release];
+ [mButtonElements release];
+
+ mLogicalDeviceElements = nil;
+ mSticks = nil;
+ mButtonElements = nil;
+ [super dealloc];
+}
+
+- (int) logicalDeviceCount;
+{
+ return [mLogicalDeviceElements count];
+}
+
+#pragma mark -
+#pragma mark Joystick Elements
+
+//===========================================================
+// - buttonElements
+//===========================================================
+- (NSArray *) buttonElements;
+{
+ return mButtonElements;
+}
+
+- (unsigned) numberOfButtons;
+{
+ return [mButtonElements count];
+}
+
+#pragma mark -
+#pragma mark Sticks - indexed accessors
+
+- (unsigned int) countOfSticks
+{
+ return [mSticks count];
+}
+
+- (DDHidJoystickStick *) objectInSticksAtIndex: (unsigned int)index
+{
+ return [mSticks objectAtIndex: index];
+}
+
+- (void) addElementsToQueue: (DDHidQueue *) queue;
+{
+ NSEnumerator * e = [mSticks objectEnumerator];
+ DDHidJoystickStick * stick;
+ while (stick = [e nextObject])
+ {
+ [queue addElements: [stick allElements]];
+ }
+
+ [queue addElements: mButtonElements];
+}
+
+
+#pragma mark -
+#pragma mark Asynchronous Notification
+
+- (void) setDelegate: (id) delegate;
+{
+ mDelegate = delegate;
+}
+
+- (void) addElementsToDefaultQueue;
+{
+ [self addElementsToQueue: mDefaultQueue];
+}
+
+@end
+
+@implementation DDHidJoystick (Private)
+
+- (void) initLogicalDeviceElements;
+{
+ NSArray * topLevelElements = [self elements];
+ if ([topLevelElements count] == 0)
+ {
+ [mLogicalDeviceElements addObject: topLevelElements];
+ return;
+ }
+
+ NSEnumerator * e = [topLevelElements objectEnumerator];
+ DDHidElement * element;
+ while (element = [e nextObject])
+ {
+ unsigned usagePage = [[element usage] usagePage];
+ unsigned usageId = [[element usage] usageId];
+ if (usagePage == kHIDPage_GenericDesktop &&
+ (usageId == kHIDUsage_GD_Joystick || usageId == kHIDUsage_GD_GamePad))
+ {
+ [mLogicalDeviceElements addObject: [NSArray arrayWithObject: element]];
+ }
+ }
+}
+
+- (void) initJoystickElements: (NSArray *) elements;
+{
+ NSEnumerator * e = [elements objectEnumerator];
+ DDHidElement * element;
+ DDHidJoystickStick * currentStick = [[[DDHidJoystickStick alloc] init] autorelease];
+ BOOL stickHasElements = NO;
+
+ while (element = [e nextObject])
+ {
+ unsigned usagePage = [[element usage] usagePage];
+ unsigned usageId = [[element usage] usageId];
+ NSArray * subElements = [element elements];
+
+ if ([subElements count] > 0)
+ {
+ [self initJoystickElements: subElements];
+ }
+ else if ((usagePage == kHIDPage_GenericDesktop) &&
+ (usageId == kHIDUsage_GD_Pointer))
+ {
+ [self addStick: subElements];
+ }
+ else if ([currentStick addElement: element])
+ {
+ stickHasElements = YES;
+ }
+ else if ((usagePage == kHIDPage_Button) &&
+ (usageId > 0))
+ {
+ [mButtonElements addObject: element];
+ }
+ }
+ if (stickHasElements)
+ {
+ [mSticks addObject: currentStick];
+ }
+}
+
+- (void) addStick: (NSArray *) elements;
+{
+ NSEnumerator * e = [elements objectEnumerator];
+ DDHidElement * element;
+ while (element = [e nextObject])
+ {
+ NSLog(@"Stick element: %@", [[element usage] usageName]);
+ }
+}
+
+- (void) ddhidQueueHasEvents: (DDHidQueue *) hidQueue;
+{
+ DDHidEvent * event;
+ while (event = [hidQueue nextEvent])
+ {
+ IOHIDElementCookie cookie = [event elementCookie];
+ SInt32 value = [event value];
+ DDHidElement * element;
+ unsigned stick;
+ unsigned otherAxis;
+ unsigned povNumber;
+ if ([self findStick: &stick element: &element withXAxisCookie: cookie])
+ {
+ int normalizedValue = [self normalizeValue: value forElement: element];
+ [self ddhidJoystick: self stick: stick xChanged: normalizedValue];
+ }
+ else if ([self findStick: &stick element: &element withYAxisCookie: cookie])
+ {
+ int normalizedValue = [self normalizeValue: value forElement: element];
+ [self ddhidJoystick: self stick: stick yChanged: normalizedValue];
+ }
+ else if ([self findStick: &stick otherAxis: &otherAxis element: &element
+ withCookie: cookie])
+ {
+ int normalizedValue = [self normalizeValue: value forElement: element];
+ [self ddhidJoystick: self stick: stick
+ otherAxis: otherAxis valueChanged: normalizedValue];
+ }
+ else if ([self findStick: &stick povNumber: &povNumber element: &element
+ withCookie: cookie])
+ {
+ int povValue = [self povValue: value forElement: element];
+ [self ddhidJoystick: self stick: stick
+ povNumber: povNumber valueChanged: povValue];
+ }
+ else
+ {
+ unsigned i = 0;
+ for (i = 0; i < [[self buttonElements] count]; i++)
+ {
+ if (cookie == [[[self buttonElements] objectAtIndex: i] cookie])
+ break;
+ }
+
+ if (value == 1)
+ {
+ [self ddhidJoystick: self buttonDown: i];
+ }
+ else if (value == 0)
+ {
+ [self ddhidJoystick: self buttonUp: i];
+ }
+ else
+ {
+ DDHidElement * element = [self elementForCookie: [event elementCookie]];
+ NSLog(@"Element: %@, value: %d", [[element usage] usageName], [event value]);
+ }
+ }
+ }
+}
+
+- (int) normalizeValue: (int) value
+ forElement: (DDHidElement *) element;
+{
+ int normalizedUnits = DDHID_JOYSTICK_VALUE_MAX - DDHID_JOYSTICK_VALUE_MIN;
+ int elementUnits = [element maxValue] - [element minValue];
+
+ int normalizedValue = (((int64_t)(value - [element minValue]) * normalizedUnits) /
+ elementUnits) + DDHID_JOYSTICK_VALUE_MIN;
+ return normalizedValue;
+}
+
+- (int) povValue: (int) value
+ forElement: (DDHidElement *) element;
+{
+ long max = [element maxValue];
+ long min = [element minValue];
+
+ // If the value is outside the min/max range, it's probably in a
+ // centered/NULL state.
+ if ((value < min) || (value > max))
+ {
+ return -1;
+ }
+
+ // Do like DirectInput and express the hatswitch value in hundredths of a
+ // degree, clockwise from north.
+ return 36000 / (max - min + 1) * (value - min);
+}
+
+- (BOOL) findStick: (unsigned *) stick
+ element: (DDHidElement **) elementOut
+ withXAxisCookie: (IOHIDElementCookie) cookie;
+{
+ unsigned i;
+ for (i = 0; i < [mSticks count]; i++)
+ {
+ DDHidElement * element = [[mSticks objectAtIndex: i] xAxisElement];
+ if ((element != nil) && ([element cookie] == cookie))
+ {
+ *stick = i;
+ *elementOut = element;
+ return YES;
+ }
+ }
+ return NO;
+}
+
+- (BOOL) findStick: (unsigned *) stick
+ element: (DDHidElement **) elementOut
+ withYAxisCookie: (IOHIDElementCookie) cookie;
+{
+ unsigned i;
+ for (i = 0; i < [mSticks count]; i++)
+ {
+ DDHidElement * element = [[mSticks objectAtIndex: i] yAxisElement];
+ if ((element != nil) && ([element cookie] == cookie))
+ {
+ *stick = i;
+ *elementOut = element;
+ return YES;
+ }
+ }
+ return NO;
+}
+
+- (BOOL) findStick: (unsigned *) stickOut
+ otherAxis: (unsigned *) axisOut
+ element: (DDHidElement **) elementOut
+ withCookie: (IOHIDElementCookie) cookie;
+{
+ unsigned i;
+ for (i = 0; i < [mSticks count]; i++)
+ {
+ DDHidJoystickStick * stick = [mSticks objectAtIndex: i];
+ unsigned j;
+ for (j = 0; j < [stick countOfStickElements]; j++)
+ {
+ DDHidElement * element = [stick objectInStickElementsAtIndex: j];
+ if ((element != nil) && ([element cookie] == cookie))
+ {
+ *stickOut = i;
+ *axisOut = j;
+ *elementOut = element;
+ return YES;
+ }
+ }
+ }
+ return NO;
+}
+
+- (BOOL) findStick: (unsigned *) stickOut
+ povNumber: (unsigned *) povNumber
+ element: (DDHidElement **) elementOut
+ withCookie: (IOHIDElementCookie) cookie;
+{
+ unsigned i;
+ for (i = 0; i < [mSticks count]; i++)
+ {
+ DDHidJoystickStick * stick = [mSticks objectAtIndex: i];
+ unsigned j;
+ for (j = 0; j < [stick countOfPovElements]; j++)
+ {
+ DDHidElement * element = [stick objectInPovElementsAtIndex: j];
+ if ((element != nil) && ([element cookie] == cookie))
+ {
+ *stickOut = i;
+ *povNumber = j;
+ *elementOut = element;
+ return YES;
+ }
+ }
+ }
+ return NO;
+}
+
+@end
+
+@implementation DDHidJoystick (DDHidJoystickDelegate)
+
+- (void) ddhidJoystick: (DDHidJoystick *) joystick
+ stick: (unsigned) stick
+ xChanged: (int) value;
+{
+ if ([mDelegate respondsToSelector: _cmd])
+ [mDelegate ddhidJoystick: joystick stick: stick xChanged: value];
+}
+
+- (void) ddhidJoystick: (DDHidJoystick *) joystick
+ stick: (unsigned) stick
+ yChanged: (int) value;
+{
+ if ([mDelegate respondsToSelector: _cmd])
+ [mDelegate ddhidJoystick: joystick stick: stick yChanged: value];
+}
+
+- (void) ddhidJoystick: (DDHidJoystick *) joystick
+ stick: (unsigned) stick
+ otherAxis: (unsigned) otherAxis
+ valueChanged: (int) value;
+{
+ if ([mDelegate respondsToSelector: _cmd])
+ [mDelegate ddhidJoystick: joystick stick: stick otherAxis: otherAxis
+ valueChanged: value];
+}
+
+- (void) ddhidJoystick: (DDHidJoystick *) joystick
+ stick: (unsigned) stick
+ povNumber: (unsigned) povNumber
+ valueChanged: (int) value;
+{
+ if ([mDelegate respondsToSelector: _cmd])
+ [mDelegate ddhidJoystick: joystick stick: stick povNumber: povNumber
+ valueChanged: value];
+}
+
+- (void) ddhidJoystick: (DDHidJoystick *) joystick
+ buttonDown: (unsigned) buttonNumber;
+{
+ if ([mDelegate respondsToSelector: _cmd])
+ [mDelegate ddhidJoystick: joystick buttonDown: buttonNumber];
+}
+
+- (void) ddhidJoystick: (DDHidJoystick *) joystick
+ buttonUp: (unsigned) buttonNumber;
+{
+ if ([mDelegate respondsToSelector: _cmd])
+ [mDelegate ddhidJoystick: joystick buttonUp: buttonNumber];
+}
+
+@end
+
+@implementation DDHidJoystickStick
+
+- (id) init
+{
+ self = [super init];
+ if (self == nil)
+ return nil;
+
+ mXAxisElement = nil;
+ mYAxisElement = nil;
+ mStickElements = [[NSMutableArray alloc] init];
+ mPovElements = [[NSMutableArray alloc] init];
+
+ return self;
+}
+
+//===========================================================
+// dealloc
+//===========================================================
+- (void) dealloc
+{
+ [mXAxisElement release];
+ [mYAxisElement release];
+ [mStickElements release];
+ [mPovElements release];
+
+ mXAxisElement = nil;
+ mYAxisElement = nil;
+ mStickElements = nil;
+ mPovElements = nil;
+ [super dealloc];
+}
+
+- (BOOL) addElement: (DDHidElement *) element;
+{
+ DDHidUsage * usage = [element usage];
+ if ([usage usagePage] != kHIDPage_GenericDesktop)
+ return NO;
+
+ BOOL elementAdded = YES;
+ switch ([usage usageId])
+ {
+ case kHIDUsage_GD_X:
+ if (mXAxisElement == nil)
+ mXAxisElement = [element retain];
+ else
+ [mStickElements addObject: element];
+ break;
+
+ case kHIDUsage_GD_Y:
+ if (mYAxisElement == nil)
+ mYAxisElement = [element retain];
+ else
+ [mStickElements addObject: element];
+ break;
+
+ case kHIDUsage_GD_Z:
+ case kHIDUsage_GD_Rx:
+ case kHIDUsage_GD_Ry:
+ case kHIDUsage_GD_Rz:
+ [mStickElements addObject: element];
+ break;
+
+ case kHIDUsage_GD_Hatswitch:
+ [mPovElements addObject: element];
+ break;
+
+ default:
+ elementAdded = NO;
+
+ }
+
+ return elementAdded;
+}
+
+- (NSArray *) allElements;
+{
+ NSMutableArray * elements = [NSMutableArray array];
+ if (mXAxisElement != nil)
+ [elements addObject: mXAxisElement];
+ if (mYAxisElement != nil)
+ [elements addObject: mYAxisElement];
+ [elements addObjectsFromArray: mStickElements];
+ [elements addObjectsFromArray: mPovElements];
+ return elements;
+}
+
+- (DDHidElement *) xAxisElement;
+{
+ return mXAxisElement;
+}
+
+- (DDHidElement *) yAxisElement;
+{
+ return mYAxisElement;
+}
+
+#pragma mark -
+#pragma mark mStickElements - indexed accessors
+
+- (unsigned int) countOfStickElements
+{
+ return [mStickElements count];
+}
+
+- (DDHidElement *) objectInStickElementsAtIndex: (unsigned int)index
+{
+ return [mStickElements objectAtIndex: index];
+}
+
+#pragma mark -
+#pragma mark PovElements - indexed accessors
+
+- (unsigned int) countOfPovElements;
+{
+ return [mPovElements count];
+}
+
+- (DDHidElement *) objectInPovElementsAtIndex: (unsigned int)index;
+{
+ return [mPovElements objectAtIndex: index];
+}
+
+- (NSString *) description;
+{
+ return [mStickElements description];
+}
+
+@end
diff --git a/lib/DDHidKeyboard.h b/lib/DDHidKeyboard.h
new file mode 100644
index 0000000..fd9200d
--- /dev/null
+++ b/lib/DDHidKeyboard.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import <Cocoa/Cocoa.h>
+#import "DDHidDevice.h"
+
+@class DDHidElement;
+@class DDHidQueue;
+
+@interface DDHidKeyboard : DDHidDevice
+{
+ NSMutableArray * mKeyElements;
+
+ id mDelegate;
+}
+
++ (NSArray *) allKeyboards;
+
+- (id) initWithDevice: (io_object_t) device error: (NSError **) error_;
+
+#pragma mark -
+#pragma mark Keyboards Elements
+
+- (NSArray *) keyElements;
+
+- (unsigned) numberOfKeys;
+
+- (void) addElementsToQueue: (DDHidQueue *) queue;
+
+#pragma mark -
+#pragma mark Asynchronous Notification
+
+- (void) setDelegate: (id) delegate;
+
+- (void) addElementsToDefaultQueue;
+
+@end
+
+@interface NSObject (DDHidKeyboardDelegate)
+
+- (void) ddhidKeyboard: (DDHidKeyboard *) keyboard
+ keyDown: (unsigned) usageId;
+
+- (void) ddhidKeyboard: (DDHidKeyboard *) keyboard
+ keyUp: (unsigned) usageId;
+
+@end
diff --git a/lib/DDHidKeyboard.m b/lib/DDHidKeyboard.m
new file mode 100644
index 0000000..7e37264
--- /dev/null
+++ b/lib/DDHidKeyboard.m
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import "DDHidKeyboard.h"
+#import "DDHidElement.h"
+#import "DDHidUsage.h"
+#import "DDHidQueue.h"
+#import "DDHidEvent.h"
+#include <IOKit/hid/IOHIDUsageTables.h>
+
+@interface DDHidKeyboard (DDHidKeyboardDelegate)
+
+- (void) ddhidKeyboard: (DDHidKeyboard *) keyboard
+ keyDown: (unsigned) usageId;
+
+- (void) ddhidKeyboard: (DDHidKeyboard *) keyboard
+ keyUp: (unsigned) usageId;
+
+@end
+
+@interface DDHidKeyboard (Private)
+
+- (void) initKeyboardElements: (NSArray *) elements;
+- (void) ddhidQueueHasEvents: (DDHidQueue *) hidQueue;
+
+@end
+
+@implementation DDHidKeyboard
+
++ (NSArray *) allKeyboards;
+{
+ return
+ [DDHidDevice allDevicesMatchingUsagePage: kHIDPage_GenericDesktop
+ usageId: kHIDUsage_GD_Keyboard
+ withClass: self
+ skipZeroLocations: YES];
+}
+
+- (id) initWithDevice: (io_object_t) device error: (NSError **) error_;
+{
+ self = [super initWithDevice: device error: error_];
+ if (self == nil)
+ return nil;
+
+ mKeyElements = [[NSMutableArray alloc] init];
+ [self initKeyboardElements: [self elements]];
+
+ return self;
+}
+
+//===========================================================
+// dealloc
+//===========================================================
+- (void) dealloc
+{
+ [mKeyElements release];
+
+ mKeyElements = nil;
+ [super dealloc];
+}
+
+#pragma mark -
+#pragma mark Keyboards Elements
+
+- (NSArray *) keyElements;
+{
+ return mKeyElements;
+}
+
+- (unsigned) numberOfKeys;
+{
+ return [mKeyElements count];
+}
+
+- (void) addElementsToQueue: (DDHidQueue *) queue;
+{
+ [queue addElements: mKeyElements];
+}
+
+#pragma mark -
+#pragma mark Asynchronous Notification
+
+- (void) setDelegate: (id) delegate;
+{
+ mDelegate = delegate;
+}
+
+- (void) addElementsToDefaultQueue;
+{
+ [self addElementsToQueue: mDefaultQueue];
+}
+
+@end
+
+@implementation DDHidKeyboard (DDHidKeyboardDelegate)
+
+- (void) ddhidKeyboard: (DDHidKeyboard *) keyboard
+ keyDown: (unsigned) usageId;
+{
+ if ([mDelegate respondsToSelector: _cmd])
+ [mDelegate ddhidKeyboard: keyboard keyDown: usageId];
+}
+
+- (void) ddhidKeyboard: (DDHidKeyboard *) keyboard
+ keyUp: (unsigned) usageId;
+{
+ if ([mDelegate respondsToSelector: _cmd])
+ [mDelegate ddhidKeyboard: keyboard keyUp: usageId];
+}
+
+@end
+
+@implementation DDHidKeyboard (Private)
+
+- (void) initKeyboardElements: (NSArray *) elements;
+{
+ NSEnumerator * e = [elements objectEnumerator];
+ DDHidElement * element;
+ while (element = [e nextObject])
+ {
+ unsigned usagePage = [[element usage] usagePage];
+ unsigned usageId = [[element usage] usageId];
+ if (usagePage == kHIDPage_KeyboardOrKeypad)
+ {
+ if ((usageId >= 0x04) && (usageId <= 0xA4) ||
+ (usageId >= 0xE0) && (usageId <= 0xE7))
+ {
+ [mKeyElements addObject: element];
+ }
+ }
+ NSArray * subElements = [element elements];
+ if (subElements != nil)
+ [self initKeyboardElements: subElements];
+ }
+}
+
+- (void) ddhidQueueHasEvents: (DDHidQueue *) hidQueue;
+{
+ DDHidEvent * event;
+ while (event = [hidQueue nextEvent])
+ {
+ DDHidElement * element = [self elementForCookie: [event elementCookie]];
+ unsigned usageId = [[element usage] usageId];
+ SInt32 value = [event value];
+ if (value == 1)
+ [self ddhidKeyboard: self keyDown: usageId];
+ else
+ [self ddhidKeyboard: self keyUp: usageId];
+ }
+}
+
+@end
diff --git a/lib/DDHidKeyboardBarcodeScanner.h b/lib/DDHidKeyboardBarcodeScanner.h
new file mode 100644
index 0000000..8504343
--- /dev/null
+++ b/lib/DDHidKeyboardBarcodeScanner.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2007 Dave Dribin, Lucas Newman
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import <Cocoa/Cocoa.h>
+#import "DDHidDevice.h"
+
+@class DDHidElement;
+@class DDHidQueue;
+
+@interface DDHidKeyboardBarcodeScanner : DDHidDevice
+{
+ NSMutableArray * mKeyElements;
+
+ NSMutableString * mAccumulatedDigits;
+ NSTimer *mBarcodeInputTimer;
+ BOOL mIsLikelyKeyboardBarcodeScanner;
+
+ id mDelegate;
+}
+
++ (NSArray *) allPossibleKeyboardBarcodeScanners;
+
+- (id) initWithDevice: (io_object_t) device error: (NSError **) error_;
+
+#pragma mark -
+#pragma mark Keyboard Elements
+
+- (NSArray *) keyElements;
+
+- (unsigned) numberOfKeys;
+
+- (void) addElementsToQueue: (DDHidQueue *) queue;
+
+#pragma mark -
+#pragma mark Asynchronous Notification
+
+- (void) setDelegate: (id) delegate;
+
+- (void) addElementsToDefaultQueue;
+
+#pragma mark -
+#pragma mark Properties
+
+- (BOOL) isLikelyKeyboardBarcodeScanner;
+
+@end
+
+@interface NSObject (DDHidKeyboardBarcodeScannerDelegate)
+
+- (void) ddhidKeyboardBarcodeScanner: (DDHidKeyboardBarcodeScanner *) keyboardBarcodeScanner
+ gotBarcode: (NSString *) barcode;
+
+@end
diff --git a/lib/DDHidKeyboardBarcodeScanner.m b/lib/DDHidKeyboardBarcodeScanner.m
new file mode 100644
index 0000000..8705cf3
--- /dev/null
+++ b/lib/DDHidKeyboardBarcodeScanner.m
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2007 Dave Dribin, Lucas Newman
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import "DDHidKeyboardBarcodeScanner.h"
+#import "DDHidElement.h"
+#import "DDHidUsage.h"
+#import "DDHidQueue.h"
+#import "DDHidEvent.h"
+#include <IOKit/hid/IOHIDUsageTables.h>
+
+@interface DDHidKeyboardBarcodeScanner (DDHidKeyboardBarcodeDelegate)
+
+- (void) ddhidKeyboardBarcodeScanner: (DDHidKeyboardBarcodeScanner *) keyboardBarcodeScanner
+ gotBarcode: (NSString *) barcode;
+
+@end
+
+@interface DDHidKeyboardBarcodeScanner (Private)
+
+- (void) initKeyboardElements: (NSArray *) elements;
+- (void) ddhidQueueHasEvents: (DDHidQueue *) hidQueue;
+- (void) processBarcodeDigit: (unsigned) usageId;
+- (void) clearAccumulatedInput;
+- (void) invalidateBarcodeInputTimer;
+
+@end
+
+@implementation DDHidKeyboardBarcodeScanner
+
++ (NSArray *) allPossibleKeyboardBarcodeScanners;
+{
+ return [DDHidDevice allDevicesMatchingUsagePage: kHIDPage_GenericDesktop
+ usageId: kHIDUsage_GD_Keyboard
+ withClass: self
+ skipZeroLocations: YES];
+}
+
+- (id) initWithDevice: (io_object_t) device error: (NSError **) error_;
+{
+ self = [super initWithDevice: device error: error_];
+ if (self == nil)
+ return nil;
+
+ mKeyElements = [[NSMutableArray alloc] init];
+ mAccumulatedDigits = [[NSMutableString alloc] init];
+ mBarcodeInputTimer = nil;
+
+ if ([[self productName] rangeOfString:@"Apple"].location != NSNotFound || [[self productName] rangeOfString:@"Internal"].location != NSNotFound)
+ mIsLikelyKeyboardBarcodeScanner = NO;
+ else
+ mIsLikelyKeyboardBarcodeScanner = YES; // if we see invalid barcodes, we can change our mind
+
+ [self initKeyboardElements: [self elements]];
+
+ return self;
+}
+
+//===========================================================
+// dealloc
+//===========================================================
+- (void) dealloc
+{
+ [self invalidateBarcodeInputTimer];
+ [mKeyElements release];
+ [mAccumulatedDigits release];
+
+ mKeyElements = nil;
+ mAccumulatedDigits = nil;
+ [super dealloc];
+}
+
+#pragma mark -
+#pragma mark Keyboard Elements
+
+- (NSArray *) keyElements;
+{
+ return mKeyElements;
+}
+
+- (unsigned) numberOfKeys;
+{
+ return [mKeyElements count];
+}
+
+- (void) addElementsToQueue: (DDHidQueue *) queue;
+{
+ [queue addElements: mKeyElements];
+}
+
+#pragma mark -
+#pragma mark Asynchronous Notification
+
+- (void) setDelegate: (id) delegate;
+{
+ mDelegate = delegate;
+}
+
+- (void) addElementsToDefaultQueue;
+{
+ [self addElementsToQueue: mDefaultQueue];
+}
+
+#pragma mark -
+#pragma mark Properties
+
+- (BOOL) isLikelyKeyboardBarcodeScanner;
+{
+ return mIsLikelyKeyboardBarcodeScanner;
+}
+
+@end
+
+@implementation DDHidKeyboardBarcodeScanner (DDHidKeyboardDelegate)
+
+- (void) ddhidKeyboardBarcodeScanner: (DDHidKeyboardBarcodeScanner *) keyboardBarcodeScanner
+ gotBarcode: (NSString *) barcode;
+{
+ if ([mDelegate respondsToSelector: _cmd])
+ [mDelegate ddhidKeyboardBarcodeScanner: keyboardBarcodeScanner gotBarcode: barcode];
+}
+
+@end
+
+@implementation DDHidKeyboardBarcodeScanner (Private)
+
+- (void) initKeyboardElements: (NSArray *) elements;
+{
+ NSEnumerator * e = [elements objectEnumerator];
+ DDHidElement * element;
+ while ((element = [e nextObject]))
+ {
+ unsigned usagePage = [[element usage] usagePage];
+ unsigned usageId = [[element usage] usageId];
+ if (usagePage == kHIDPage_KeyboardOrKeypad)
+ {
+ if ((usageId >= kHIDUsage_KeyboardA) && (usageId <= kHIDUsage_Keyboard0))
+ {
+ [mKeyElements addObject: element];
+ }
+ }
+ NSArray * subElements = [element elements];
+ if (subElements != nil)
+ [self initKeyboardElements: subElements];
+ }
+}
+
+- (void) ddhidQueueHasEvents: (DDHidQueue *) hidQueue;
+{
+ DDHidEvent * event;
+ while ((event = [hidQueue nextEvent]))
+ {
+ DDHidElement * element = [self elementForCookie: [event elementCookie]];
+ unsigned usageId = [[element usage] usageId];
+ SInt32 value = [event value];
+ if (value == 1) // key down
+ [self processBarcodeDigit: usageId];
+ }
+}
+
+#define UPC_A_BARCODE_LENGTH (12)
+#define BARCODE_INPUT_TIMEOUT (0.5)
+
+- (void) processBarcodeDigit: (unsigned) usageId;
+{
+ if (usageId <= kHIDUsage_KeyboardZ || usageId >= kHIDUsage_KeyboardCapsLock) { // an alphabetic key was pressed => probably not a barcode scanner
+ [self willChangeValueForKey:@"isLikelyKeyboardBarcodeScanner"];
+ mIsLikelyKeyboardBarcodeScanner = NO;
+ [self didChangeValueForKey:@"isLikelyKeyboardBarcodeScanner"];
+
+ [self clearAccumulatedInput];
+ return;
+ }
+
+ if (!mBarcodeInputTimer) // schedule a timer to make sure we get the rest of the digits in a timely manner
+ mBarcodeInputTimer = [[NSTimer scheduledTimerWithTimeInterval:BARCODE_INPUT_TIMEOUT target:self selector:@selector(fireBarcodeInputTimeout:) userInfo:nil repeats:NO] retain];
+
+ [mAccumulatedDigits appendString:[NSString stringWithFormat:@"%d", (usageId + 1) % 10]];
+}
+
+- (void) fireBarcodeInputTimeout: (NSTimer *) timer;
+{
+ if ([mAccumulatedDigits length] >= UPC_A_BARCODE_LENGTH)
+ [self ddhidKeyboardBarcodeScanner: self gotBarcode: [[mAccumulatedDigits copy] autorelease]];
+ [self clearAccumulatedInput];
+}
+
+- (void) clearAccumulatedInput;
+{
+ [mAccumulatedDigits deleteCharactersInRange:NSMakeRange(0, [mAccumulatedDigits length])];
+
+ [self invalidateBarcodeInputTimer];
+}
+
+- (void) invalidateBarcodeInputTimer;
+{
+ [mBarcodeInputTimer invalidate];
+ [mBarcodeInputTimer release];
+ mBarcodeInputTimer = nil;
+}
+
+@end
diff --git a/lib/DDHidLib.h b/lib/DDHidLib.h
new file mode 100644
index 0000000..20d8681
--- /dev/null
+++ b/lib/DDHidLib.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import "DDHidDevice.h"
+#import "DDHidElement.h"
+#import "DDHidUsage.h"
+#import "DDHidQueue.h"
+#import "DDHidEvent.h"
+#import "DDHidUsageTables.h"
+#import "DDHidMouse.h"
+#import "DDHidJoystick.h"
+#import "DDHidKeyboard.h"
+#import "DDHidAppleRemote.h"
+#import "DDHidAppleMikey.h"
+#import "DDHidKeyboardBarcodeScanner.h"
diff --git a/lib/DDHidMouse.h b/lib/DDHidMouse.h
new file mode 100644
index 0000000..d396aba
--- /dev/null
+++ b/lib/DDHidMouse.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import <Cocoa/Cocoa.h>
+#import "DDHidDevice.h"
+
+@class DDHidElement;
+@class DDHidQueue;
+
+@interface DDHidMouse : DDHidDevice
+{
+ DDHidElement * mXElement;
+ DDHidElement * mYElement;
+ DDHidElement * mWheelElement;
+ NSMutableArray * mButtonElements;
+
+ id mDelegate;
+}
+
++ (NSArray *) allMice;
+
+- (id) initWithDevice: (io_object_t) device error: (NSError **) error_;
+
+#pragma mark -
+#pragma mark Mouse Elements
+
+- (DDHidElement *) xElement;
+
+- (DDHidElement *) yElement;
+
+- (DDHidElement *) wheelElement;
+
+- (NSArray *) buttonElements;
+
+- (unsigned) numberOfButtons;
+
+- (void) addElementsToQueue: (DDHidQueue *) queue;
+
+#pragma mark -
+#pragma mark Asynchronous Notification
+
+- (void) setDelegate: (id) delegate;
+
+- (void) addElementsToDefaultQueue;
+
+@end
+
+@interface NSObject (DDHidMouseDelegate)
+
+- (void) ddhidMouse: (DDHidMouse *) mouse xChanged: (SInt32) deltaX;
+- (void) ddhidMouse: (DDHidMouse *) mouse yChanged: (SInt32) deltaY;
+- (void) ddhidMouse: (DDHidMouse *) mouse wheelChanged: (SInt32) deltaWheel;
+- (void) ddhidMouse: (DDHidMouse *) mouse buttonDown: (unsigned) buttonNumber;
+- (void) ddhidMouse: (DDHidMouse *) mouse buttonUp: (unsigned) buttonNumber;
+
+@end
+
diff --git a/lib/DDHidMouse.m b/lib/DDHidMouse.m
new file mode 100644
index 0000000..7eeb5b3
--- /dev/null
+++ b/lib/DDHidMouse.m
@@ -0,0 +1,279 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import "DDHidMouse.h"
+#import "DDHidUsage.h"
+#import "DDHidElement.h"
+#import "DDHidQueue.h"
+#import "DDHidEvent.h"
+#include <IOKit/hid/IOHIDUsageTables.h>
+
+
+// Implement our own delegate methods
+
+@interface DDHidMouse (DDHidMouseDelegate)
+
+- (void) ddhidMouse: (DDHidMouse *) mouse xChanged: (SInt32) deltaX;
+- (void) ddhidMouse: (DDHidMouse *) mouse yChanged: (SInt32) deltaY;
+- (void) ddhidMouse: (DDHidMouse *) mouse wheelChanged: (SInt32) deltaWheel;
+- (void) ddhidMouse: (DDHidMouse *) mouse buttonDown: (unsigned) buttonNumber;
+- (void) ddhidMouse: (DDHidMouse *) mouse buttonUp: (unsigned) buttonNumber;
+
+@end
+
+@interface DDHidMouse (Private)
+
+- (void) initMouseElements: (NSArray *) elements;
+- (void) ddhidQueueHasEvents: (DDHidQueue *) hidQueue;
+
+@end
+
+@implementation DDHidMouse
+
++ (NSArray *) allMice;
+{
+ return
+ [DDHidDevice allDevicesMatchingUsagePage: kHIDPage_GenericDesktop
+ usageId: kHIDUsage_GD_Mouse
+ withClass: self
+ skipZeroLocations: YES];
+}
+
+- (id) initWithDevice: (io_object_t) device error: (NSError **) error_;
+{
+ self = [super initWithDevice: device error: error_];
+ if (self == nil)
+ return nil;
+
+ mXElement = mYElement = mWheelElement = nil;
+ mButtonElements = [[NSMutableArray alloc] init];
+ [self initMouseElements: [self elements]];
+
+ return self;
+}
+
+//===========================================================
+// dealloc
+//===========================================================
+- (void) dealloc
+{
+ [mXElement release];
+ [mYElement release];
+ [mWheelElement release];
+ [mButtonElements release];
+
+ mXElement = nil;
+ mYElement = nil;
+ mWheelElement = nil;
+ mButtonElements = nil;
+ [super dealloc];
+}
+
+#pragma mark -
+#pragma mark Mouse Elements
+
+//===========================================================
+// - xElement
+//===========================================================
+- (DDHidElement *) xElement
+{
+ return mXElement;
+}
+
+//===========================================================
+// - yElement
+//===========================================================
+- (DDHidElement *) yElement
+{
+ return mYElement;
+}
+
+- (DDHidElement *) wheelElement;
+{
+ return mWheelElement;
+}
+
+//===========================================================
+// - buttonElements
+//===========================================================
+- (NSArray *) buttonElements;
+{
+ return mButtonElements;
+}
+
+- (unsigned) numberOfButtons;
+{
+ return [mButtonElements count];
+}
+
+- (void) addElementsToQueue: (DDHidQueue *) queue;
+{
+ [queue addElement: mXElement];
+ [queue addElement: mYElement];
+ [queue addElement: mWheelElement];
+ [queue addElements: mButtonElements];
+}
+
+
+#pragma mark -
+#pragma mark Asynchronous Notification
+
+- (void) setDelegate: (id) delegate;
+{
+ mDelegate = delegate;
+}
+
+- (void) addElementsToDefaultQueue;
+{
+ [self addElementsToQueue: mDefaultQueue];
+}
+
+@end
+
+@implementation DDHidMouse (DDHidMouseDelegate)
+
+- (void) ddhidMouse: (DDHidMouse *) mouse xChanged: (SInt32) deltaX;
+{
+ if ([mDelegate respondsToSelector: _cmd])
+ [mDelegate ddhidMouse: mouse xChanged: deltaX];
+}
+
+- (void) ddhidMouse: (DDHidMouse *) mouse yChanged: (SInt32) deltaY;
+{
+ if ([mDelegate respondsToSelector: _cmd])
+ [mDelegate ddhidMouse: mouse yChanged: deltaY];
+}
+
+- (void) ddhidMouse: (DDHidMouse *) mouse wheelChanged: (SInt32) deltaWheel;
+{
+ if ([mDelegate respondsToSelector: _cmd])
+ [mDelegate ddhidMouse: mouse wheelChanged: deltaWheel];
+}
+
+- (void) ddhidMouse: (DDHidMouse *) mouse buttonDown: (unsigned) buttonNumber;
+{
+ if ([mDelegate respondsToSelector: _cmd])
+ [mDelegate ddhidMouse: mouse buttonDown: buttonNumber];
+}
+
+- (void) ddhidMouse: (DDHidMouse *) mouse buttonUp: (unsigned) buttonNumber;
+{
+ if ([mDelegate respondsToSelector: _cmd])
+ [mDelegate ddhidMouse: mouse buttonUp: buttonNumber];
+}
+
+@end
+
+@implementation DDHidMouse (Private)
+
+- (void) initMouseElements: (NSArray *) elements;
+{
+ NSEnumerator * e = [elements objectEnumerator];
+ DDHidElement * element;
+ while (element = [e nextObject])
+ {
+ unsigned usagePage = [[element usage] usagePage];
+ unsigned usageId = [[element usage] usageId];
+ if ((usagePage == kHIDPage_GenericDesktop) &&
+ (usageId == kHIDUsage_GD_X))
+ {
+ mXElement = [element retain];
+ }
+ else if ((usagePage == kHIDPage_GenericDesktop) &&
+ (usageId == kHIDUsage_GD_Y))
+ {
+ mYElement = [element retain];
+ }
+ else if ((usagePage == kHIDPage_GenericDesktop) &&
+ (usageId == kHIDUsage_GD_Wheel))
+ {
+ mWheelElement = [element retain];
+ }
+ else if ((usagePage == kHIDPage_Button) &&
+ (usageId > 0))
+ {
+ [mButtonElements addObject: element];
+ }
+ NSArray * subElements = [element elements];
+ if (subElements != nil)
+ [self initMouseElements: subElements];
+ }
+}
+
+- (void) ddhidQueueHasEvents: (DDHidQueue *) hidQueue;
+{
+ DDHidEvent * event;
+ while (event = [hidQueue nextEvent])
+ {
+ IOHIDElementCookie cookie = [event elementCookie];
+ SInt32 value = [event value];
+ if (cookie == [[self xElement] cookie])
+ {
+ if (value != 0)
+ {
+ [self ddhidMouse: self xChanged: value];
+ }
+ }
+ else if (cookie == [[self yElement] cookie])
+ {
+ if (value != 0)
+ {
+ [self ddhidMouse: self yChanged: value];
+ }
+ }
+ else if (cookie == [[self wheelElement] cookie])
+ {
+ if (value != 0)
+ {
+ [self ddhidMouse: self wheelChanged: value];
+ }
+ }
+ else
+ {
+ unsigned i = 0;
+ for (i = 0; i < [[self buttonElements] count]; i++)
+ {
+ if (cookie == [[[self buttonElements] objectAtIndex: i] cookie])
+ break;
+ }
+
+ if (value == 1)
+ {
+ [self ddhidMouse: self buttonDown: i];
+ }
+ else if (value == 0)
+ {
+ [self ddhidMouse: self buttonUp: i];
+ }
+ else
+ {
+ DDHidElement * element = [self elementForCookie: [event elementCookie]];
+ NSLog(@"Element: %@, value: %d", [[element usage] usageName], [event value]);
+ }
+ }
+ }
+}
+
+@end
+
diff --git a/lib/DDHidQueue.h b/lib/DDHidQueue.h
new file mode 100644
index 0000000..315d003
--- /dev/null
+++ b/lib/DDHidQueue.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import <Cocoa/Cocoa.h>
+#include <IOKit/hid/IOHIDLib.h>
+
+@class DDHidElement;
+@class DDHidEvent;
+
+@interface DDHidQueue : NSObject
+{
+ IOHIDQueueInterface ** mQueue;
+ NSRunLoop * mRunLoop;
+ BOOL mStarted;
+
+ id mDelegate;
+ CFRunLoopSourceRef mEventSource;
+}
+
+- (id) initWithHIDQueue: (IOHIDQueueInterface **) queue
+ size: (unsigned) size;
+
+- (void) addElement: (DDHidElement *) element;
+
+- (void) addElements: (NSArray *) elements;
+
+- (void) addElements: (NSArray *) elements recursively: (BOOL) recursively;
+
+- (void) setDelegate: (id) delegate;
+
+- (void) startOnCurrentRunLoop;
+
+- (void) startOnRunLoop: (NSRunLoop *) runLoop;
+
+- (void) stop;
+
+- (BOOL) isStarted;
+
+- (BOOL) getNextEvent: (IOHIDEventStruct *) event;
+
+- (DDHidEvent *) nextEvent;
+
+@end
+
+@interface NSObject (DDHidQueueDelegate)
+
+- (void) ddhidQueueHasEvents: (DDHidQueue *) hidQueue;
+
+@end
diff --git a/lib/DDHidQueue.m b/lib/DDHidQueue.m
new file mode 100644
index 0000000..8f44698
--- /dev/null
+++ b/lib/DDHidQueue.m
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import "DDHidQueue.h"
+#import "DDHidElement.h"
+#import "DDHIdEvent.h"
+#import "NSXReturnThrowError.h"
+
+static void queueCallbackFunction(void* target, IOReturn result, void* refcon,
+ void* sender);
+
+@interface DDHidQueue (Private)
+
+- (void) handleQueueCallback;
+
+@end
+
+@implementation DDHidQueue
+
+- (id) initWithHIDQueue: (IOHIDQueueInterface **) queue
+ size: (unsigned) size;
+{
+ self = [super init];
+ if (self == nil)
+ return nil;
+
+ mQueue = queue;
+ IOReturn result = (*mQueue)->create(mQueue, 0, size);
+ if (result != kIOReturnSuccess)
+ {
+ [self release];
+ return nil;
+ }
+
+ return self;
+}
+
+- (void) dealloc;
+{
+ [self stop];
+ (*mQueue)->dispose(mQueue);
+ (*mQueue)->Release(mQueue);
+ [super dealloc];
+}
+
+- (void) addElement: (DDHidElement *) element;
+{
+ IOHIDElementCookie cookie = [element cookie];
+ (*mQueue)->addElement(mQueue, cookie, 0);
+}
+
+- (void) addElements: (NSArray *) elements;
+{
+ return [self addElements: elements recursively: NO];
+}
+
+- (void) addElements: (NSArray *) elements recursively: (BOOL) recursively;
+{
+ NSEnumerator * e = [elements objectEnumerator];
+ DDHidElement * element;
+ while (element = [e nextObject])
+ {
+ [self addElement: element];
+ if (recursively)
+ [self addElements: [element elements]];
+ }
+}
+
+- (void) setDelegate: (id) delegate;
+{
+ mDelegate = delegate;
+}
+
+- (void) startOnCurrentRunLoop;
+{
+ [self startOnRunLoop: [NSRunLoop currentRunLoop]];
+}
+
+- (void) startOnRunLoop: (NSRunLoop *) runLoop;
+{
+ if (mStarted)
+ return;
+
+ mRunLoop = [runLoop retain];
+
+ NSXThrowError((*mQueue)->createAsyncEventSource(mQueue, &mEventSource));
+ NSXThrowError((*mQueue)->setEventCallout(mQueue, queueCallbackFunction, self, NULL));
+ CFRunLoopAddSource([mRunLoop getCFRunLoop], mEventSource,
+ kCFRunLoopDefaultMode);
+ (*mQueue)->start(mQueue);
+ mStarted = YES;
+}
+
+- (void) stop;
+{
+ if (!mStarted)
+ return;
+
+ CFRunLoopRemoveSource([mRunLoop getCFRunLoop], mEventSource, kCFRunLoopDefaultMode);
+ (*mQueue)->stop(mQueue);
+ [mRunLoop release];
+ mRunLoop = nil;
+ mStarted = NO;
+}
+
+- (BOOL) isStarted;
+{
+ return mStarted;
+}
+
+- (BOOL) getNextEvent: (IOHIDEventStruct *) event;
+{
+ AbsoluteTime zeroTime = {0, 0};
+ IOReturn result = (*mQueue)->getNextEvent(mQueue, event, zeroTime, 0);
+ return (result == kIOReturnSuccess);
+}
+
+- (DDHidEvent *) nextEvent;
+{
+ AbsoluteTime zeroTime = {0, 0};
+ IOHIDEventStruct event;
+ IOReturn result = (*mQueue)->getNextEvent(mQueue, &event, zeroTime, 0);
+ if (result != kIOReturnSuccess)
+ return nil;
+ else
+ return [DDHidEvent eventWithIOHIDEvent: &event];
+}
+
+@end
+
+@implementation DDHidQueue (Private)
+
+- (void) handleQueueCallback;
+{
+ if ([mDelegate respondsToSelector: @selector(ddhidQueueHasEvents:)])
+ {
+ [mDelegate ddhidQueueHasEvents: self];
+ }
+}
+
+@end
+
+static void queueCallbackFunction(void* target, IOReturn result, void* refcon,
+ void* sender)
+{
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+ DDHidQueue * queue = (DDHidQueue *) target;
+ [queue handleQueueCallback];
+ [pool release];
+
+}
diff --git a/lib/DDHidStandardUsages.plist b/lib/DDHidStandardUsages.plist
new file mode 100644
index 0000000..84eb663
--- /dev/null
+++ b/lib/DDHidStandardUsages.plist
@@ -0,0 +1,2327 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+ <dict>
+ <key>1</key>
+ <dict>
+ <key>description</key>
+ <string>Generic Desktop</string>
+ <key>ranges</key>
+ <dict>
+ </dict>
+ <key>usages</key>
+ <dict>
+ <key>0</key>
+ <string>Undefined</string>
+ <key>1</key>
+ <string>Pointer</string>
+ <key>2</key>
+ <string>Mouse</string>
+ <key>3</key>
+ <string>Reserved</string>
+ <key>4</key>
+ <string>Joystick</string>
+ <key>5</key>
+ <string>Game Pad</string>
+ <key>6</key>
+ <string>Keyboard</string>
+ <key>7</key>
+ <string>Keypad</string>
+ <key>8</key>
+ <string>Multi-axis Controller</string>
+ <key>48</key>
+ <string>X</string>
+ <key>49</key>
+ <string>Y</string>
+ <key>50</key>
+ <string>Z</string>
+ <key>51</key>
+ <string>Rx</string>
+ <key>52</key>
+ <string>Ry</string>
+ <key>53</key>
+ <string>Rz</string>
+ <key>54</key>
+ <string>Slider</string>
+ <key>55</key>
+ <string>Dial</string>
+ <key>56</key>
+ <string>Wheel</string>
+ <key>57</key>
+ <string>Hat Switch</string>
+ <key>58</key>
+ <string>Counted Buffer</string>
+ <key>59</key>
+ <string>Byte Count</string>
+ <key>60</key>
+ <string>Motion Wakeup</string>
+ <key>64</key>
+ <string>Vx</string>
+ <key>65</key>
+ <string>Vy</string>
+ <key>66</key>
+ <string>Vz</string>
+ <key>67</key>
+ <string>Vbrx</string>
+ <key>68</key>
+ <string>Vbry</string>
+ <key>69</key>
+ <string>Vbrx</string>
+ <key>70</key>
+ <string>Vno</string>
+ <key>128</key>
+ <string>System Control</string>
+ <key>129</key>
+ <string>System Power Down</string>
+ <key>130</key>
+ <string>System Sleep</string>
+ <key>131</key>
+ <string>System Wake Up</string>
+ <key>132</key>
+ <string>System Context Menu</string>
+ <key>133</key>
+ <string>System Main Menu</string>
+ <key>134</key>
+ <string>System App Menu</string>
+ <key>135</key>
+ <string>System Menu Help</string>
+ <key>136</key>
+ <string>System Menu Exit</string>
+ <key>137</key>
+ <string>System Menu Select</string>
+ <key>138</key>
+ <string>System Menu Right</string>
+ <key>139</key>
+ <string>System Menu Left</string>
+ <key>140</key>
+ <string>System Menu Up</string>
+ <key>141</key>
+ <string>System Menu Down</string>
+ <key>144</key>
+ <string>D-pad Up</string>
+ <key>145</key>
+ <string>D-pad Down</string>
+ <key>146</key>
+ <string>D-pad Right</string>
+ <key>147</key>
+ <string>D-pad Left</string>
+ </dict>
+ </dict>
+ <key>2</key>
+ <dict>
+ <key>description</key>
+ <string>Simulation Controls</string>
+ <key>ranges</key>
+ <dict>
+ </dict>
+ <key>usages</key>
+ <dict>
+ <key>0</key>
+ <string>Undefined</string>
+ <key>1</key>
+ <string>Flight Simulation Device</string>
+ <key>2</key>
+ <string>Automobile Simulation Device</string>
+ <key>3</key>
+ <string>Tank Simulation Device</string>
+ <key>4</key>
+ <string>Spaceship Simulation Device</string>
+ <key>5</key>
+ <string>Submarine Simulation Device</string>
+ <key>6</key>
+ <string>Sailing Simulation Device</string>
+ <key>7</key>
+ <string>Motorcycle Simulation Device</string>
+ <key>8</key>
+ <string>Sports Simulation Device</string>
+ <key>9</key>
+ <string>Airplane Simulation Device</string>
+ <key>10</key>
+ <string>Helicopter Simulation Device</string>
+ <key>11</key>
+ <string>Magic Carpet Simulation Device</string>
+ <key>12</key>
+ <string>Bicycle</string>
+ <key>32</key>
+ <string>Flight Control Stick</string>
+ <key>33</key>
+ <string>Flight Stick</string>
+ <key>34</key>
+ <string>Cyclic Control</string>
+ <key>35</key>
+ <string>Cyclic Trim</string>
+ <key>36</key>
+ <string>Flight Yoke</string>
+ <key>37</key>
+ <string>Track Control</string>
+ <key>38</key>
+ <string>Driving Control</string>
+ <key>176</key>
+ <string>Aileron</string>
+ <key>177</key>
+ <string>Aileron Trim</string>
+ <key>178</key>
+ <string>Anti-Torque Control</string>
+ <key>179</key>
+ <string>Auto-pilot Enable</string>
+ <key>180</key>
+ <string>Chaff Release</string>
+ <key>181</key>
+ <string>Collective Control</string>
+ <key>182</key>
+ <string>Dive Brake</string>
+ <key>183</key>
+ <string>Electronic Counter Measures</string>
+ <key>184</key>
+ <string>Elevator</string>
+ <key>185</key>
+ <string>Elevator Trim</string>
+ <key>186</key>
+ <string>Rudder</string>
+ <key>187</key>
+ <string>Throttle</string>
+ <key>188</key>
+ <string>Flight Communication</string>
+ <key>189</key>
+ <string>Flare Release</string>
+ <key>190</key>
+ <string>Landing Gear</string>
+ <key>191</key>
+ <string>Toe Brake</string>
+ <key>192</key>
+ <string>Trigger</string>
+ <key>193</key>
+ <string>Weapons Arm</string>
+ <key>194</key>
+ <string>Weapons Select</string>
+ <key>195</key>
+ <string>Wing Flaps</string>
+ <key>196</key>
+ <string>Accelerator</string>
+ <key>197</key>
+ <string>Brake</string>
+ <key>198</key>
+ <string>Clutch</string>
+ <key>199</key>
+ <string>Shifter</string>
+ <key>200</key>
+ <string>Steering</string>
+ <key>201</key>
+ <string>Turret Direction</string>
+ <key>202</key>
+ <string>Barrel Elevation</string>
+ <key>203</key>
+ <string>Dive Plane</string>
+ <key>204</key>
+ <string>Ballast</string>
+ <key>205</key>
+ <string>Bicycle Crank</string>
+ <key>206</key>
+ <string>Handle Bars</string>
+ <key>207</key>
+ <string>Front Brake</string>
+ <key>208</key>
+ <string>Rear Brake</string>
+ </dict>
+ </dict>
+ <key>3</key>
+ <dict>
+ <key>description</key>
+ <string>VR Controls</string>
+ <key>ranges</key>
+ <dict>
+ </dict>
+ <key>usages</key>
+ <dict>
+ <key>0</key>
+ <string>Unidentified</string>
+ <key>1</key>
+ <string>Belt</string>
+ <key>2</key>
+ <string>Body Suit</string>
+ <key>3</key>
+ <string>Flexor</string>
+ <key>4</key>
+ <string>Glove</string>
+ <key>5</key>
+ <string>Head Tracker</string>
+ <key>6</key>
+ <string>Head Mounted Display</string>
+ <key>7</key>
+ <string>Hand Tracker</string>
+ <key>8</key>
+ <string>Oculometer</string>
+ <key>9</key>
+ <string>Vest</string>
+ <key>10</key>
+ <string>Animatronic Device</string>
+ <key>32</key>
+ <string>Stereo Enable</string>
+ <key>33</key>
+ <string>Display Enable</string>
+ </dict>
+ </dict>
+ <key>4</key>
+ <dict>
+ <key>description</key>
+ <string>Sports Controls</string>
+ <key>ranges</key>
+ <dict>
+ </dict>
+ <key>usages</key>
+ <dict>
+ <key>0</key>
+ <string>Unidentified</string>
+ <key>1</key>
+ <string>Baseball Bat</string>
+ <key>2</key>
+ <string>Golf Club</string>
+ <key>3</key>
+ <string>Rowing Machine</string>
+ <key>4</key>
+ <string>Treadmill</string>
+ <key>48</key>
+ <string>Oar</string>
+ <key>49</key>
+ <string>Slope</string>
+ <key>50</key>
+ <string>Rate</string>
+ <key>51</key>
+ <string>Stick Speed</string>
+ <key>52</key>
+ <string>Stick Face Angle</string>
+ <key>53</key>
+ <string>Stick Heel/Toe</string>
+ <key>54</key>
+ <string>Stick Follow Through</string>
+ <key>55</key>
+ <string>Stick Tempo</string>
+ <key>56</key>
+ <string>Stick Type</string>
+ <key>57</key>
+ <string>Stick Height</string>
+ <key>80</key>
+ <string>Putter</string>
+ <key>81</key>
+ <string>1 Iron</string>
+ <key>82</key>
+ <string>2 Iron</string>
+ <key>83</key>
+ <string>3 Iron</string>
+ <key>84</key>
+ <string>4 Iron</string>
+ <key>85</key>
+ <string>5 Iron</string>
+ <key>86</key>
+ <string>6 Iron</string>
+ <key>87</key>
+ <string>7 Iron</string>
+ <key>88</key>
+ <string>8 Iron</string>
+ <key>89</key>
+ <string>9 Iron</string>
+ <key>90</key>
+ <string>10 Iron</string>
+ <key>91</key>
+ <string>11 Iron</string>
+ <key>92</key>
+ <string>Sand Wedge</string>
+ <key>93</key>
+ <string>Loft Wedge</string>
+ <key>94</key>
+ <string>Power Wedge</string>
+ <key>95</key>
+ <string>1 Wood</string>
+ <key>96</key>
+ <string>3 Wood</string>
+ <key>97</key>
+ <string>5 Wood</string>
+ <key>98</key>
+ <string>7 Wood</string>
+ <key>99</key>
+ <string>9 Wood</string>
+ </dict>
+ </dict>
+ <key>5</key>
+ <dict>
+ <key>description</key>
+ <string>Game Controls</string>
+ <key>ranges</key>
+ <dict>
+ </dict>
+ <key>usages</key>
+ <dict>
+ <key>0</key>
+ <string>Undefined</string>
+ <key>1</key>
+ <string>3D Game Controller</string>
+ <key>2</key>
+ <string>Pinball Device</string>
+ <key>3</key>
+ <string>Gun Device</string>
+ <key>32</key>
+ <string>Point of View</string>
+ <key>33</key>
+ <string>Turn Right/Left</string>
+ <key>34</key>
+ <string>Pitch Right/Left</string>
+ <key>35</key>
+ <string>Roll Forward/Backward</string>
+ <key>36</key>
+ <string>Move Right/Left</string>
+ <key>37</key>
+ <string>Move Forward/Backward</string>
+ <key>38</key>
+ <string>Move Up/Down</string>
+ <key>39</key>
+ <string>Lean Right/Left</string>
+ <key>40</key>
+ <string>Lean Forward/Backward</string>
+ <key>41</key>
+ <string>Height of POV</string>
+ <key>42</key>
+ <string>Flipper</string>
+ <key>43</key>
+ <string>Secondary Flipper</string>
+ <key>44</key>
+ <string>Bump</string>
+ <key>45</key>
+ <string>New Game</string>
+ <key>46</key>
+ <string>Shoot Ball</string>
+ <key>47</key>
+ <string>Player</string>
+ <key>48</key>
+ <string>Gun Bolt</string>
+ <key>49</key>
+ <string>Gun Clip</string>
+ <key>50</key>
+ <string>Gun Selector</string>
+ <key>51</key>
+ <string>Gun Single Shot</string>
+ <key>52</key>
+ <string>Gun Burst</string>
+ <key>53</key>
+ <string>Gun Automatic</string>
+ <key>54</key>
+ <string>Gun Safety</string>
+ <key>55</key>
+ <string>Gamepad Fire/Jump</string>
+ <key>57</key>
+ <string>Gamepad Trigger</string>
+ </dict>
+ </dict>
+ <key>7</key>
+ <dict>
+ <key>description</key>
+ <string>Keyboard</string>
+ <key>ranges</key>
+ <dict>
+ </dict>
+ <key>usages</key>
+ <dict>
+ <key>0</key>
+ <string>No Event</string>
+ <key>1</key>
+ <string>Keyboard ErrorRollOver</string>
+ <key>2</key>
+ <string>Keyboard POSTFail</string>
+ <key>3</key>
+ <string>Keyboard ErrorUndefined</string>
+ <key>4</key>
+ <string>Keyboard a and A</string>
+ <key>5</key>
+ <string>Keyboard b and B</string>
+ <key>6</key>
+ <string>Keyboard c and C</string>
+ <key>7</key>
+ <string>Keyboard d and D</string>
+ <key>8</key>
+ <string>Keyboard e and E</string>
+ <key>9</key>
+ <string>Keyboard f and F</string>
+ <key>10</key>
+ <string>Keyboard g and G</string>
+ <key>11</key>
+ <string>Keyboard h and H</string>
+ <key>12</key>
+ <string>Keyboard i and I</string>
+ <key>13</key>
+ <string>Keyboard j and J</string>
+ <key>14</key>
+ <string>Keyboard k and K</string>
+ <key>15</key>
+ <string>Keyboard l and L</string>
+ <key>16</key>
+ <string>Keyboard m and M</string>
+ <key>17</key>
+ <string>Keyboard n and N</string>
+ <key>18</key>
+ <string>Keyboard o and O</string>
+ <key>19</key>
+ <string>Keyboard p and P</string>
+ <key>20</key>
+ <string>Keyboard q and Q</string>
+ <key>21</key>
+ <string>Keyboard r and R</string>
+ <key>22</key>
+ <string>Keyboard s and S</string>
+ <key>23</key>
+ <string>Keyboard t and T</string>
+ <key>24</key>
+ <string>Keyboard u and U</string>
+ <key>25</key>
+ <string>Keyboard v and V</string>
+ <key>26</key>
+ <string>Keyboard w and W</string>
+ <key>27</key>
+ <string>Keyboard x and X</string>
+ <key>28</key>
+ <string>Keyboard y and Y</string>
+ <key>29</key>
+ <string>Keyboard z and Z</string>
+ <key>30</key>
+ <string>Keyboard 1 and !</string>
+ <key>31</key>
+ <string>Keyboard 2 and @</string>
+ <key>32</key>
+ <string>Keyboard 3 and #</string>
+ <key>33</key>
+ <string>Keyboard 4 and $</string>
+ <key>34</key>
+ <string>Keyboard 5 and %</string>
+ <key>35</key>
+ <string>Keyboard 6 and ^</string>
+ <key>36</key>
+ <string>Keyboard 7 and &amp;</string>
+ <key>37</key>
+ <string>Keyboard 8 and *</string>
+ <key>38</key>
+ <string>Keyboard 9 and (</string>
+ <key>39</key>
+ <string>Keyboard 0 and )</string>
+ <key>40</key>
+ <string>Keyboard Return (ENTER)</string>
+ <key>41</key>
+ <string>Keyboard ESCAPE</string>
+ <key>42</key>
+ <string>Keyboard DELETE (Backspace)</string>
+ <key>43</key>
+ <string>Keyboard Tab</string>
+ <key>44</key>
+ <string>Keyboard Spacebar</string>
+ <key>45</key>
+ <string>Keyboard - and (underscore)</string>
+ <key>46</key>
+ <string>Keyboard = and +</string>
+ <key>47</key>
+ <string>Keyboard [ and {</string>
+ <key>48</key>
+ <string>Keyboard ] and }</string>
+ <key>49</key>
+ <string>Keyboard \ and |</string>
+ <key>50</key>
+ <string>Keyboard Non-US # and ~</string>
+ <key>51</key>
+ <string>Keyboard ; and :</string>
+ <key>52</key>
+ <string>Keyboard ' and "</string>
+ <key>53</key>
+ <string>Keyboard Grave Accent and Tilde</string>
+ <key>54</key>
+ <string>Keyboard, and &lt;</string>
+ <key>55</key>
+ <string>Keyboard . and &gt;</string>
+ <key>56</key>
+ <string>Keyboard / and ?</string>
+ <key>57</key>
+ <string>Keyboard Caps Lock</string>
+ <key>58</key>
+ <string>Keyboard F1</string>
+ <key>59</key>
+ <string>Keyboard F2</string>
+ <key>60</key>
+ <string>Keyboard F3</string>
+ <key>61</key>
+ <string>Keyboard F4</string>
+ <key>62</key>
+ <string>Keyboard F5</string>
+ <key>63</key>
+ <string>Keyboard F6</string>
+ <key>64</key>
+ <string>Keyboard F7</string>
+ <key>65</key>
+ <string>Keyboard F8</string>
+ <key>66</key>
+ <string>Keyboard F9</string>
+ <key>67</key>
+ <string>Keyboard F10</string>
+ <key>68</key>
+ <string>Keyboard F11</string>
+ <key>69</key>
+ <string>Keyboard F12</string>
+ <key>70</key>
+ <string>Keyboard PrintScreen</string>
+ <key>71</key>
+ <string>Keyboard Scroll Lock</string>
+ <key>72</key>
+ <string>Keyboard Pause</string>
+ <key>73</key>
+ <string>Keyboard Insert</string>
+ <key>74</key>
+ <string>Keyboard Home</string>
+ <key>75</key>
+ <string>Keyboard PageUp</string>
+ <key>76</key>
+ <string>Keyboard Delete Forward</string>
+ <key>77</key>
+ <string>Keyboard End</string>
+ <key>78</key>
+ <string>Keyboard PageDown</string>
+ <key>79</key>
+ <string>Keyboard RightArrow</string>
+ <key>80</key>
+ <string>Keyboard LeftArrow</string>
+ <key>81</key>
+ <string>Keyboard DownArrow</string>
+ <key>82</key>
+ <string>Keyboard UpArrow</string>
+ <key>83</key>
+ <string>Keypad Num Lock and Clear</string>
+ <key>84</key>
+ <string>Keypad /</string>
+ <key>85</key>
+ <string>Keypad *</string>
+ <key>86</key>
+ <string>Keypad -</string>
+ <key>87</key>
+ <string>Keypad +</string>
+ <key>88</key>
+ <string>Keypad ENTER</string>
+ <key>89</key>
+ <string>Keypad 1 and End</string>
+ <key>90</key>
+ <string>Keypad 2 and Down Arrow</string>
+ <key>91</key>
+ <string>Keypad 3 and PageDn</string>
+ <key>92</key>
+ <string>Keypad 4 and Left Arrow</string>
+ <key>93</key>
+ <string>Keypad 5</string>
+ <key>94</key>
+ <string>Keypad 6 and Right Arrow</string>
+ <key>95</key>
+ <string>Keypad 7 and Home</string>
+ <key>96</key>
+ <string>Keypad 8 and Up Arrow</string>
+ <key>97</key>
+ <string>Keypad 9 and PageUp</string>
+ <key>98</key>
+ <string>Keypad 0 and Insert</string>
+ <key>99</key>
+ <string>Keypad . and Delete</string>
+ <key>100</key>
+ <string>Keyboard Non-US \ and |</string>
+ <key>101</key>
+ <string>Keyboard Application</string>
+ <key>102</key>
+ <string>Keyboard Power</string>
+ <key>103</key>
+ <string>Keypad =</string>
+ <key>104</key>
+ <string>Keyboard F13</string>
+ <key>105</key>
+ <string>Keyboard F14</string>
+ <key>106</key>
+ <string>Keyboard F15</string>
+ <key>107</key>
+ <string>Keyboard F16</string>
+ <key>108</key>
+ <string>Keyboard F17</string>
+ <key>109</key>
+ <string>Keyboard F18</string>
+ <key>110</key>
+ <string>Keyboard F19</string>
+ <key>111</key>
+ <string>Keyboard F20</string>
+ <key>112</key>
+ <string>Keyboard F21</string>
+ <key>113</key>
+ <string>Keyboard F22</string>
+ <key>114</key>
+ <string>Keyboard F23</string>
+ <key>115</key>
+ <string>Keyboard F24</string>
+ <key>116</key>
+ <string>Keyboard Execute</string>
+ <key>117</key>
+ <string>Keyboard Help</string>
+ <key>118</key>
+ <string>Keyboard Menu</string>
+ <key>119</key>
+ <string>Keyboard Select</string>
+ <key>120</key>
+ <string>Keyboard Stop</string>
+ <key>121</key>
+ <string>Keyboard Again</string>
+ <key>122</key>
+ <string>Keyboard Undo</string>
+ <key>123</key>
+ <string>Keyboard Cut</string>
+ <key>124</key>
+ <string>Keyboard Copy</string>
+ <key>125</key>
+ <string>Keyboard Paste</string>
+ <key>126</key>
+ <string>Keyboard Find</string>
+ <key>127</key>
+ <string>Keyboard Mute</string>
+ <key>128</key>
+ <string>Keyboard Volume Up</string>
+ <key>129</key>
+ <string>Keyboard Volume Down</string>
+ <key>130</key>
+ <string>Keyboard Locking Caps Lock</string>
+ <key>131</key>
+ <string>Keyboard Locking Num Lock</string>
+ <key>132</key>
+ <string>Keyboard Locking Scroll Lock</string>
+ <key>133</key>
+ <string>Keypad Comma</string>
+ <key>134</key>
+ <string>Keypad Equal Sign</string>
+ <key>135</key>
+ <string>Keyboard International1</string>
+ <key>136</key>
+ <string>Keyboard International2</string>
+ <key>137</key>
+ <string>Keyboard International3</string>
+ <key>138</key>
+ <string>Keyboard International4</string>
+ <key>139</key>
+ <string>Keyboard International5</string>
+ <key>140</key>
+ <string>Keyboard International6</string>
+ <key>141</key>
+ <string>Keyboard International7</string>
+ <key>142</key>
+ <string>Keyboard International8</string>
+ <key>143</key>
+ <string>Keyboard International9</string>
+ <key>144</key>
+ <string>Keyboard LANG1</string>
+ <key>145</key>
+ <string>Keyboard LANG2</string>
+ <key>146</key>
+ <string>Keyboard LANG3</string>
+ <key>147</key>
+ <string>Keyboard LANG4</string>
+ <key>148</key>
+ <string>Keyboard LANG5</string>
+ <key>149</key>
+ <string>Keyboard LANG6</string>
+ <key>150</key>
+ <string>Keyboard LANG7</string>
+ <key>151</key>
+ <string>Keyboard LANG8</string>
+ <key>152</key>
+ <string>Keyboard LANG9</string>
+ <key>153</key>
+ <string>Keyboard Alternate Erase</string>
+ <key>154</key>
+ <string>Keyboard SysReq/Attention</string>
+ <key>155</key>
+ <string>Keyboard Cancel</string>
+ <key>156</key>
+ <string>Keyboard Clear</string>
+ <key>157</key>
+ <string>Keyboard Prior</string>
+ <key>158</key>
+ <string>Keyboard Return</string>
+ <key>159</key>
+ <string>Keyboard Separator</string>
+ <key>160</key>
+ <string>Keyboard Out</string>
+ <key>161</key>
+ <string>Keyboard Oper</string>
+ <key>162</key>
+ <string>Keyboard Clear/Again</string>
+ <key>163</key>
+ <string>Keyboard CrSel/Props</string>
+ <key>164</key>
+ <string>Keyboard ExSel</string>
+ <key>224</key>
+ <string>Keyboard LeftControl</string>
+ <key>225</key>
+ <string>Keyboard LeftShift</string>
+ <key>226</key>
+ <string>Keyboard LeftAlt</string>
+ <key>227</key>
+ <string>Keyboard Left GUI</string>
+ <key>228</key>
+ <string>Keyboard RightControl</string>
+ <key>229</key>
+ <string>Keyboard RightShift</string>
+ <key>230</key>
+ <string>Keyboard RightAlt</string>
+ <key>231</key>
+ <string>Keyboard Right GUI</string>
+ </dict>
+ </dict>
+ <key>8</key>
+ <dict>
+ <key>description</key>
+ <string>LEDs</string>
+ <key>ranges</key>
+ <dict>
+ <key>{76, 65535}</key>
+ <string>Reserved</string>
+ </dict>
+ <key>usages</key>
+ <dict>
+ <key>0</key>
+ <string>Undefined</string>
+ <key>1</key>
+ <string>Num Lock</string>
+ <key>2</key>
+ <string>Caps Lock</string>
+ <key>3</key>
+ <string>Scroll Lock</string>
+ <key>4</key>
+ <string>Compose</string>
+ <key>5</key>
+ <string>Kana</string>
+ <key>6</key>
+ <string>Power</string>
+ <key>7</key>
+ <string>Shift</string>
+ <key>8</key>
+ <string>Do Not Disturb</string>
+ <key>9</key>
+ <string>Mute</string>
+ <key>10</key>
+ <string>Tone Enable</string>
+ <key>11</key>
+ <string>High Cut Filter</string>
+ <key>12</key>
+ <string>Low Cut Filter</string>
+ <key>13</key>
+ <string>Equalizer Enable</string>
+ <key>14</key>
+ <string>Sound Field On</string>
+ <key>15</key>
+ <string>Surround Field On</string>
+ <key>16</key>
+ <string>Repeat</string>
+ <key>17</key>
+ <string>Stereo</string>
+ <key>18</key>
+ <string>Sampling Rate Detect</string>
+ <key>19</key>
+ <string>Spinning</string>
+ <key>20</key>
+ <string>CAV</string>
+ <key>21</key>
+ <string>CLV</string>
+ <key>22</key>
+ <string>Recording Format Detect</string>
+ <key>23</key>
+ <string>Off-Hook</string>
+ <key>24</key>
+ <string>Ring</string>
+ <key>25</key>
+ <string>Message Waiting</string>
+ <key>26</key>
+ <string>Data Mode</string>
+ <key>27</key>
+ <string>Battery Operation</string>
+ <key>28</key>
+ <string>Battery OK</string>
+ <key>29</key>
+ <string>Battery Low</string>
+ <key>30</key>
+ <string>Speaker</string>
+ <key>31</key>
+ <string>Head Set</string>
+ <key>32</key>
+ <string>Hold</string>
+ <key>33</key>
+ <string>Microphone</string>
+ <key>34</key>
+ <string>Coverage</string>
+ <key>35</key>
+ <string>Night Mode</string>
+ <key>36</key>
+ <string>Send Calls</string>
+ <key>37</key>
+ <string>Call Pickup</string>
+ <key>38</key>
+ <string>Conference</string>
+ <key>39</key>
+ <string>Stand-by</string>
+ <key>40</key>
+ <string>Camera On</string>
+ <key>41</key>
+ <string>Camera Off</string>
+ <key>42</key>
+ <string>On-Line</string>
+ <key>43</key>
+ <string>Off-Line</string>
+ <key>44</key>
+ <string>Busy</string>
+ <key>45</key>
+ <string>Ready</string>
+ <key>46</key>
+ <string>Paper-Out</string>
+ <key>47</key>
+ <string>Paper-Jam</string>
+ <key>48</key>
+ <string>Remote</string>
+ <key>49</key>
+ <string>Forward</string>
+ <key>50</key>
+ <string>Reverse</string>
+ <key>51</key>
+ <string>Stop</string>
+ <key>52</key>
+ <string>Rewind</string>
+ <key>53</key>
+ <string>Fast Forward</string>
+ <key>54</key>
+ <string>Play</string>
+ <key>55</key>
+ <string>Pause</string>
+ <key>56</key>
+ <string>Record</string>
+ <key>57</key>
+ <string>Error</string>
+ <key>58</key>
+ <string>Usage Selected Indicator</string>
+ <key>59</key>
+ <string>Usage In Use Indicator</string>
+ <key>60</key>
+ <string>Usage Multi Mode Indicator</string>
+ <key>61</key>
+ <string>Indicator On</string>
+ <key>62</key>
+ <string>Indicator Flash</string>
+ <key>63</key>
+ <string>Indicator Slow Blink</string>
+ <key>64</key>
+ <string>Indicator Fast Blink</string>
+ <key>65</key>
+ <string>Indicator Off</string>
+ <key>66</key>
+ <string>Flash On Time</string>
+ <key>67</key>
+ <string>Slow Blink On Time</string>
+ <key>68</key>
+ <string>Slow Blink Off Time</string>
+ <key>69</key>
+ <string>Fast Blink On Time</string>
+ <key>70</key>
+ <string>Fast Blink Off Time</string>
+ <key>71</key>
+ <string>Usage Indicator Color</string>
+ <key>72</key>
+ <string>Red</string>
+ <key>73</key>
+ <string>Green</string>
+ <key>74</key>
+ <string>Amber</string>
+ <key>75</key>
+ <string>Generic Indicator</string>
+ <key>76</key>
+ <string>System Suspend</string>
+ <key>77</key>
+ <string>External Power Connected</string>
+ </dict>
+ </dict>
+ <key>9</key>
+ <dict>
+ <key>default</key>
+ <string>Button %d</string>
+ <key>description</key>
+ <string>Button</string>
+ <key>ranges</key>
+ <dict>
+ </dict>
+ <key>usages</key>
+ <dict>
+ <key>0</key>
+ <string>No Button Pressed</string>
+ </dict>
+ </dict>
+ <key>10</key>
+ <dict>
+ <key>default</key>
+ <string>Instance %d</string>
+ <key>description</key>
+ <string>Ordinal</string>
+ <key>ranges</key>
+ <dict>
+ </dict>
+ <key>usages</key>
+ <dict>
+ <key>0</key>
+ <string>Unused</string>
+ </dict>
+ </dict>
+ <key>11</key>
+ <dict>
+ <key>description</key>
+ <string>Telephony</string>
+ <key>ranges</key>
+ <dict>
+ </dict>
+ <key>usages</key>
+ <dict>
+ <key>0</key>
+ <string>Unassigned</string>
+ <key>1</key>
+ <string>Phone</string>
+ <key>2</key>
+ <string>Answering Machine</string>
+ <key>3</key>
+ <string>Message Controls</string>
+ <key>4</key>
+ <string>Handset</string>
+ <key>5</key>
+ <string>Headset</string>
+ <key>6</key>
+ <string>Telephony Key Pad</string>
+ <key>7</key>
+ <string>Programmable Button</string>
+ <key>32</key>
+ <string>Hook Switch</string>
+ <key>33</key>
+ <string>Flash</string>
+ <key>34</key>
+ <string>Feature</string>
+ <key>35</key>
+ <string>Hold</string>
+ <key>36</key>
+ <string>Redial</string>
+ <key>37</key>
+ <string>Transfer</string>
+ <key>38</key>
+ <string>Drop</string>
+ <key>39</key>
+ <string>Park</string>
+ <key>40</key>
+ <string>Forward Calls</string>
+ <key>41</key>
+ <string>Alternate Function</string>
+ <key>42</key>
+ <string>Line</string>
+ <key>43</key>
+ <string>Speaker Phone</string>
+ <key>44</key>
+ <string>Conference</string>
+ <key>45</key>
+ <string>Ring Enable</string>
+ <key>46</key>
+ <string>Ring Select</string>
+ <key>47</key>
+ <string>Phone Mute</string>
+ <key>48</key>
+ <string>Caller ID</string>
+ <key>80</key>
+ <string>Speed Dial</string>
+ <key>81</key>
+ <string>Store Number</string>
+ <key>82</key>
+ <string>Recall Number</string>
+ <key>83</key>
+ <string>Phone Directory</string>
+ <key>112</key>
+ <string>Voice Mail</string>
+ <key>113</key>
+ <string>Screen Calls</string>
+ <key>114</key>
+ <string>Do Not Disturb</string>
+ <key>115</key>
+ <string>Message</string>
+ <key>116</key>
+ <string>Answer On/Off</string>
+ <key>144</key>
+ <string>Inside Dial Tone</string>
+ <key>145</key>
+ <string>Outside Dial Tone</string>
+ <key>146</key>
+ <string>Inside Ring Tone</string>
+ <key>147</key>
+ <string>Outside Ring Tone</string>
+ <key>148</key>
+ <string>Priority Ring Tone</string>
+ <key>149</key>
+ <string>Inside Ringback</string>
+ <key>150</key>
+ <string>Priority Ringback</string>
+ <key>151</key>
+ <string>Line Busy Tone</string>
+ <key>152</key>
+ <string>Reorder Tone</string>
+ <key>153</key>
+ <string>Call Waiting Tone</string>
+ <key>154</key>
+ <string>Confirmation Tone 1</string>
+ <key>155</key>
+ <string>Confirmation Tone 2</string>
+ <key>156</key>
+ <string>Tones Off</string>
+ <key>176</key>
+ <string>Phone Key 0</string>
+ <key>177</key>
+ <string>Phone Key 1</string>
+ <key>178</key>
+ <string>Phone Key 2</string>
+ <key>179</key>
+ <string>Phone Key 3</string>
+ <key>180</key>
+ <string>Phone Key 4</string>
+ <key>181</key>
+ <string>Phone Key 5</string>
+ <key>182</key>
+ <string>Phone Key 6</string>
+ <key>183</key>
+ <string>Phone Key 7</string>
+ <key>184</key>
+ <string>Phone Key 8</string>
+ <key>185</key>
+ <string>Phone Key 9</string>
+ <key>186</key>
+ <string>Phone Key Star</string>
+ <key>187</key>
+ <string>Phone Key Pound</string>
+ <key>188</key>
+ <string>Phone Key A</string>
+ <key>189</key>
+ <string>Phone Key B</string>
+ <key>190</key>
+ <string>Phone Key C</string>
+ <key>191</key>
+ <string>Phone Key D</string>
+ </dict>
+ </dict>
+ <key>12</key>
+ <dict>
+ <key>description</key>
+ <string>Consumer</string>
+ <key>ranges</key>
+ <dict>
+ </dict>
+ <key>usages</key>
+ <dict>
+ <key>0</key>
+ <string>Unassigned</string>
+ <key>1</key>
+ <string>Consumer Control</string>
+ <key>2</key>
+ <string>Numeric Key Pad</string>
+ <key>3</key>
+ <string>Programmable Buttons</string>
+ <key>32</key>
+ <string>+10</string>
+ <key>33</key>
+ <string>+100</string>
+ <key>34</key>
+ <string>AM/PM</string>
+ <key>48</key>
+ <string>Power</string>
+ <key>49</key>
+ <string>Reset</string>
+ <key>50</key>
+ <string>Sleep</string>
+ <key>51</key>
+ <string>Sleep After</string>
+ <key>52</key>
+ <string>Sleep Mode</string>
+ <key>53</key>
+ <string>Illumination</string>
+ <key>54</key>
+ <string>Function Buttons</string>
+ <key>64</key>
+ <string>Menu</string>
+ <key>65</key>
+ <string>Menu Pick</string>
+ <key>66</key>
+ <string>Menu Up</string>
+ <key>67</key>
+ <string>Menu Down</string>
+ <key>68</key>
+ <string>Menu Left</string>
+ <key>69</key>
+ <string>Menu Right</string>
+ <key>70</key>
+ <string>Menu Escape</string>
+ <key>71</key>
+ <string>Menu Value Increase</string>
+ <key>72</key>
+ <string>Menu Value Decrease</string>
+ <key>96</key>
+ <string>Data On Screen</string>
+ <key>97</key>
+ <string>Closed Caption</string>
+ <key>98</key>
+ <string>Closed Caption Select</string>
+ <key>99</key>
+ <string>VCR/TV</string>
+ <key>100</key>
+ <string>Broadcast Mode</string>
+ <key>101</key>
+ <string>Snapshot</string>
+ <key>102</key>
+ <string>Still</string>
+ <key>128</key>
+ <string>Selection</string>
+ <key>129</key>
+ <string>Assign Selection</string>
+ <key>130</key>
+ <string>Mode Step</string>
+ <key>131</key>
+ <string>Recall Last</string>
+ <key>132</key>
+ <string>Enter Channel</string>
+ <key>133</key>
+ <string>Order Movie</string>
+ <key>134</key>
+ <string>Channel</string>
+ <key>135</key>
+ <string>Media Selection</string>
+ <key>136</key>
+ <string>Media Select Computer</string>
+ <key>137</key>
+ <string>Media Select TV</string>
+ <key>138</key>
+ <string>Media Select WWW</string>
+ <key>139</key>
+ <string>Media Select DVD</string>
+ <key>140</key>
+ <string>Media Select Telephone</string>
+ <key>141</key>
+ <string>Media Select Program Guide</string>
+ <key>142</key>
+ <string>Media Select Video Phone</string>
+ <key>143</key>
+ <string>Media Select Games</string>
+ <key>144</key>
+ <string>Media Select Messages</string>
+ <key>145</key>
+ <string>Media Select CD</string>
+ <key>146</key>
+ <string>Media Select VCR</string>
+ <key>147</key>
+ <string>Media Select Tuner</string>
+ <key>148</key>
+ <string>Quit</string>
+ <key>149</key>
+ <string>Help</string>
+ <key>150</key>
+ <string>Media Select Tape</string>
+ <key>151</key>
+ <string>Media Select Cable</string>
+ <key>152</key>
+ <string>Media Select Satellite</string>
+ <key>153</key>
+ <string>Media Select Security</string>
+ <key>154</key>
+ <string>Media Select Home</string>
+ <key>155</key>
+ <string>Media Select Call</string>
+ <key>156</key>
+ <string>Channel Increment</string>
+ <key>157</key>
+ <string>Channel Decrement</string>
+ <key>158</key>
+ <string>Media Select SAP</string>
+ <key>160</key>
+ <string>VCR Plus</string>
+ <key>161</key>
+ <string>Once</string>
+ <key>162</key>
+ <string>Daily</string>
+ <key>163</key>
+ <string>Weekly</string>
+ <key>164</key>
+ <string>Monthly</string>
+ <key>176</key>
+ <string>Play</string>
+ <key>177</key>
+ <string>Pause</string>
+ <key>178</key>
+ <string>Record</string>
+ <key>179</key>
+ <string>Fast Forward</string>
+ <key>180</key>
+ <string>Rewind</string>
+ <key>181</key>
+ <string>Scan Next Track</string>
+ <key>182</key>
+ <string>Scan Previous Track</string>
+ <key>183</key>
+ <string>Stop</string>
+ <key>184</key>
+ <string>Eject</string>
+ <key>185</key>
+ <string>Random Play</string>
+ <key>186</key>
+ <string>Select DisC</string>
+ <key>187</key>
+ <string>Enter Disc</string>
+ <key>188</key>
+ <string>Repeat</string>
+ <key>189</key>
+ <string>Tracking</string>
+ <key>190</key>
+ <string>Track Normal</string>
+ <key>191</key>
+ <string>Slow Tracking</string>
+ <key>192</key>
+ <string>Frame Forward</string>
+ <key>193</key>
+ <string>Frame Back</string>
+ <key>194</key>
+ <string>Mark</string>
+ <key>195</key>
+ <string>Clear Mark</string>
+ <key>196</key>
+ <string>Repeat From Mark</string>
+ <key>197</key>
+ <string>Return To Mark</string>
+ <key>198</key>
+ <string>Search Mark Forward</string>
+ <key>199</key>
+ <string>Search Mark Backwards</string>
+ <key>200</key>
+ <string>Counter Reset</string>
+ <key>201</key>
+ <string>Show Counter</string>
+ <key>202</key>
+ <string>Tracking Increment</string>
+ <key>203</key>
+ <string>Tracking Decrement</string>
+ <key>205</key>
+ <string>Pause/Play</string>
+ <key>224</key>
+ <string>Volume</string>
+ <key>225</key>
+ <string>Balance</string>
+ <key>226</key>
+ <string>Mute</string>
+ <key>227</key>
+ <string>Bass</string>
+ <key>228</key>
+ <string>Treble</string>
+ <key>229</key>
+ <string>Bass Boost</string>
+ <key>230</key>
+ <string>Surround Mode</string>
+ <key>231</key>
+ <string>Loudness</string>
+ <key>232</key>
+ <string>MPX</string>
+ <key>233</key>
+ <string>Volume Up</string>
+ <key>234</key>
+ <string>Volume Down</string>
+ <key>240</key>
+ <string>Speed Select</string>
+ <key>241</key>
+ <string>Playback Speed</string>
+ <key>242</key>
+ <string>Standard Play</string>
+ <key>243</key>
+ <string>Long Play</string>
+ <key>244</key>
+ <string>Extended Play</string>
+ <key>245</key>
+ <string>Slow</string>
+ <key>256</key>
+ <string>Fan Enable</string>
+ <key>257</key>
+ <string>Fan Speed</string>
+ <key>258</key>
+ <string>Light</string>
+ <key>259</key>
+ <string>Light Illumination Level</string>
+ <key>260</key>
+ <string>Climate Control Enable</string>
+ <key>261</key>
+ <string>Room Temperature</string>
+ <key>262</key>
+ <string>Security Enable</string>
+ <key>263</key>
+ <string>Fire Alarm</string>
+ <key>264</key>
+ <string>Police Alarm</string>
+ <key>336</key>
+ <string>Balance Right</string>
+ <key>337</key>
+ <string>Balance Left</string>
+ <key>338</key>
+ <string>Bass Increment</string>
+ <key>339</key>
+ <string>Bass Decrement</string>
+ <key>340</key>
+ <string>Treble Increment</string>
+ <key>341</key>
+ <string>Treble Decrement</string>
+ <key>352</key>
+ <string>Speaker System</string>
+ <key>353</key>
+ <string>Channel Left</string>
+ <key>354</key>
+ <string>Channel Right</string>
+ <key>355</key>
+ <string>Channel Center</string>
+ <key>356</key>
+ <string>Channel Front</string>
+ <key>357</key>
+ <string>Channel Center Front</string>
+ <key>358</key>
+ <string>Channel Side</string>
+ <key>359</key>
+ <string>Channel Surround</string>
+ <key>360</key>
+ <string>Channel Low Frequency Enhancement</string>
+ <key>361</key>
+ <string>Channel Top</string>
+ <key>362</key>
+ <string>Channel Unknown</string>
+ <key>368</key>
+ <string>Sub-channel</string>
+ <key>369</key>
+ <string>Sub-channel Increment</string>
+ <key>370</key>
+ <string>Sub-channel Decrement</string>
+ <key>371</key>
+ <string>Alternate Audio Increment</string>
+ <key>372</key>
+ <string>Alternate Audio Decrement</string>
+ <key>384</key>
+ <string>Application Launch Buttons</string>
+ <key>385</key>
+ <string>AL Launch Button Configuration Tool</string>
+ <key>386</key>
+ <string>AL Programmable Button Configuration</string>
+ <key>387</key>
+ <string>AL Consumer Control Configuration</string>
+ <key>388</key>
+ <string>AL Word Processor</string>
+ <key>389</key>
+ <string>AL Text Editor</string>
+ <key>390</key>
+ <string>AL Spreadsheet</string>
+ <key>391</key>
+ <string>AL Graphics Editor</string>
+ <key>392</key>
+ <string>AL Presentation App</string>
+ <key>393</key>
+ <string>AL Database App</string>
+ <key>394</key>
+ <string>AL Email Reader</string>
+ <key>395</key>
+ <string>AL Newsreader</string>
+ <key>396</key>
+ <string>AL Voicemail</string>
+ <key>397</key>
+ <string>AL Contacts/Address Book</string>
+ <key>398</key>
+ <string>AL Calendar/Schedule</string>
+ <key>399</key>
+ <string>AL Task/Project Manager</string>
+ <key>400</key>
+ <string>AL Log/Journal/Timecard</string>
+ <key>401</key>
+ <string>AL Checkbook/Finance</string>
+ <key>402</key>
+ <string>AL Calculator</string>
+ <key>403</key>
+ <string>AL A/V Capture/Playback</string>
+ <key>404</key>
+ <string>AL Local Machine Browser</string>
+ <key>405</key>
+ <string>AL LAN/WAN Browser</string>
+ <key>406</key>
+ <string>AL Internet Browser</string>
+ <key>407</key>
+ <string>AL Remote Networking/ISP Connect</string>
+ <key>408</key>
+ <string>AL Network Conference</string>
+ <key>409</key>
+ <string>AL Network Chat</string>
+ <key>410</key>
+ <string>AL Telephony/Dialer</string>
+ <key>411</key>
+ <string>AL Logon</string>
+ <key>412</key>
+ <string>AL Logoff</string>
+ <key>413</key>
+ <string>AL Logon/Logoff</string>
+ <key>414</key>
+ <string>AL Terminal Lock/Screensaver</string>
+ <key>415</key>
+ <string>AL Control Panel</string>
+ <key>416</key>
+ <string>AL Command Line Processor/Run</string>
+ <key>417</key>
+ <string>AL Process/Task Manager</string>
+ <key>418</key>
+ <string>AL Select Tast/Application</string>
+ <key>419</key>
+ <string>AL Next Task/Application</string>
+ <key>420</key>
+ <string>AL Previous Task/Application</string>
+ <key>421</key>
+ <string>AL Preemptive Halt Task/Application</string>
+ <key>423</key>
+ <string>AL My Documents</string>
+ <key>427</key>
+ <string>AC Spell</string>
+ <key>438</key>
+ <string>AL My Pictures</string>
+ <key>439</key>
+ <string>AL My Music</string>
+ <key>512</key>
+ <string>Generic GUI Application Controls</string>
+ <key>513</key>
+ <string>AC New</string>
+ <key>514</key>
+ <string>AC Open</string>
+ <key>515</key>
+ <string>AC Close</string>
+ <key>516</key>
+ <string>AC Exit</string>
+ <key>517</key>
+ <string>AC Maximize</string>
+ <key>518</key>
+ <string>AC Minimize</string>
+ <key>519</key>
+ <string>AC Save</string>
+ <key>520</key>
+ <string>AC Print</string>
+ <key>521</key>
+ <string>AC Properties</string>
+ <key>538</key>
+ <string>AC Undo</string>
+ <key>539</key>
+ <string>AC Copy</string>
+ <key>540</key>
+ <string>AC Cut</string>
+ <key>541</key>
+ <string>AC Paste</string>
+ <key>542</key>
+ <string>AC Select All</string>
+ <key>543</key>
+ <string>AC Find</string>
+ <key>544</key>
+ <string>AC Find and Replace</string>
+ <key>545</key>
+ <string>AC Search</string>
+ <key>546</key>
+ <string>AC Go To</string>
+ <key>547</key>
+ <string>AC Home</string>
+ <key>548</key>
+ <string>AC Back</string>
+ <key>549</key>
+ <string>AC Forward</string>
+ <key>550</key>
+ <string>AC Stop</string>
+ <key>551</key>
+ <string>AC Refresh</string>
+ <key>552</key>
+ <string>AC Previous Link</string>
+ <key>553</key>
+ <string>AC Next Link</string>
+ <key>554</key>
+ <string>AC Bookmarks</string>
+ <key>555</key>
+ <string>AC History</string>
+ <key>556</key>
+ <string>AC Subscriptions</string>
+ <key>557</key>
+ <string>AC Zoom In</string>
+ <key>558</key>
+ <string>AC Zoom Out</string>
+ <key>559</key>
+ <string>AC Zoom</string>
+ <key>560</key>
+ <string>AC Full Screen View</string>
+ <key>561</key>
+ <string>AC Normal View</string>
+ <key>562</key>
+ <string>AC View Toggle</string>
+ <key>563</key>
+ <string>AC Scroll Up</string>
+ <key>564</key>
+ <string>AC Scroll Down</string>
+ <key>565</key>
+ <string>AC Scroll</string>
+ <key>566</key>
+ <string>AC Pan Left</string>
+ <key>567</key>
+ <string>AC Pan Right</string>
+ <key>568</key>
+ <string>AC Pan</string>
+ <key>569</key>
+ <string>AC New Window</string>
+ <key>570</key>
+ <string>AC Tile Horizontally</string>
+ <key>571</key>
+ <string>AC Tile Vertically</string>
+ <key>572</key>
+ <string>AC Format</string>
+ <key>633</key>
+ <string>AC Redo</string>
+ <key>649</key>
+ <string>AC Reply</string>
+ <key>651</key>
+ <string>AC Fwd</string>
+ <key>652</key>
+ <string>AC Send</string>
+ </dict>
+ </dict>
+ <key>13</key>
+ <dict>
+ <key>description</key>
+ <string>Digitizer</string>
+ <key>ranges</key>
+ <dict>
+ </dict>
+ <key>usages</key>
+ <dict>
+ <key>0</key>
+ <string>Undefined</string>
+ <key>1</key>
+ <string>Digitizer</string>
+ <key>2</key>
+ <string>Pen</string>
+ <key>3</key>
+ <string>Light Pen</string>
+ <key>4</key>
+ <string>Touch Screen</string>
+ <key>5</key>
+ <string>Touch Pad</string>
+ <key>6</key>
+ <string>White Board</string>
+ <key>7</key>
+ <string>Coordinate Measuring Machine</string>
+ <key>8</key>
+ <string>3-D Digitizer</string>
+ <key>9</key>
+ <string>Stereo Plotter</string>
+ <key>10</key>
+ <string>Articulated Arm</string>
+ <key>11</key>
+ <string>Armature</string>
+ <key>12</key>
+ <string>Multiple Point Digitizer</string>
+ <key>13</key>
+ <string>Free Space Wand</string>
+ <key>32</key>
+ <string>Stylus</string>
+ <key>33</key>
+ <string>Puck</string>
+ <key>34</key>
+ <string>Finger</string>
+ <key>48</key>
+ <string>Tip Pressure</string>
+ <key>49</key>
+ <string>Barrel Pressure</string>
+ <key>50</key>
+ <string>In Range</string>
+ <key>51</key>
+ <string>Touch</string>
+ <key>52</key>
+ <string>Untouch</string>
+ <key>53</key>
+ <string>Tap</string>
+ <key>54</key>
+ <string>Quality</string>
+ <key>55</key>
+ <string>Data Valid</string>
+ <key>56</key>
+ <string>Transducer Index</string>
+ <key>57</key>
+ <string>Tablet Function Keys</string>
+ <key>58</key>
+ <string>Program Change Keys</string>
+ <key>59</key>
+ <string>Battery Strength</string>
+ <key>60</key>
+ <string>Invert</string>
+ <key>61</key>
+ <string>X Tilt</string>
+ <key>62</key>
+ <string>Y Tilt</string>
+ <key>63</key>
+ <string>Azimuth</string>
+ <key>64</key>
+ <string>Altitude</string>
+ <key>65</key>
+ <string>Twist</string>
+ <key>66</key>
+ <string>Tip Switch</string>
+ <key>67</key>
+ <string>Secondary Tip Switch</string>
+ <key>68</key>
+ <string>Barrel Switch</string>
+ <key>69</key>
+ <string>Eraser</string>
+ <key>70</key>
+ <string>Tablet Pick</string>
+ </dict>
+ </dict>
+ <key>15</key>
+ <dict>
+ <key>description</key>
+ <string>Physical Interface Device</string>
+ <key>ranges</key>
+ <dict>
+ </dict>
+ <key>usages</key>
+ <dict>
+ </dict>
+ </dict>
+ <key>16</key>
+ <dict>
+ <key>default</key>
+ <string>Unicode Char u%04x</string>
+ <key>description</key>
+ <string>Unicode</string>
+ <key>ranges</key>
+ <dict>
+ </dict>
+ <key>usages</key>
+ <dict>
+ </dict>
+ </dict>
+ <key>20</key>
+ <dict>
+ <key>description</key>
+ <string>Alphnumeric Display</string>
+ <key>ranges</key>
+ <dict>
+ </dict>
+ <key>usages</key>
+ <dict>
+ <key>0</key>
+ <string>Undefined</string>
+ <key>1</key>
+ <string>Alphanumeric Display</string>
+ <key>32</key>
+ <string>Display Attributes Report</string>
+ <key>33</key>
+ <string>ASCII Character Set</string>
+ <key>34</key>
+ <string>Data Read Back</string>
+ <key>35</key>
+ <string>Font Read Back</string>
+ <key>36</key>
+ <string>Display Control Report</string>
+ <key>37</key>
+ <string>Clear Display</string>
+ <key>38</key>
+ <string>Display Enable</string>
+ <key>39</key>
+ <string>Screen Saver Delay</string>
+ <key>40</key>
+ <string>Screen Saver Enable</string>
+ <key>41</key>
+ <string>Vertical Scroll</string>
+ <key>42</key>
+ <string>Horizontal Scroll</string>
+ <key>43</key>
+ <string>Character Report</string>
+ <key>44</key>
+ <string>Display Data</string>
+ <key>45</key>
+ <string>Display Status</string>
+ <key>46</key>
+ <string>Stat Not Ready</string>
+ <key>47</key>
+ <string>Stat Ready</string>
+ <key>48</key>
+ <string>Err Not a loadable character</string>
+ <key>49</key>
+ <string>Err Font data cannot be read</string>
+ <key>50</key>
+ <string>Cursor Position Report</string>
+ <key>51</key>
+ <string>Row</string>
+ <key>52</key>
+ <string>Column</string>
+ <key>53</key>
+ <string>Rows</string>
+ <key>54</key>
+ <string>Columns</string>
+ <key>55</key>
+ <string>Cursor Pixel Positioning</string>
+ <key>56</key>
+ <string>Cursor Mode</string>
+ <key>57</key>
+ <string>Cursor Enable</string>
+ <key>58</key>
+ <string>Cursor Blink</string>
+ <key>59</key>
+ <string>Font Report</string>
+ <key>60</key>
+ <string>Font Data</string>
+ <key>61</key>
+ <string>Character Width</string>
+ <key>62</key>
+ <string>Character Height</string>
+ <key>63</key>
+ <string>Character Spacing Horizontal</string>
+ <key>64</key>
+ <string>Character Spacing Vertical</string>
+ <key>65</key>
+ <string>Unicode Character Set</string>
+ </dict>
+ </dict>
+ <key>128</key>
+ <dict>
+ <key>description</key>
+ <string>Monitor</string>
+ <key>ranges</key>
+ <dict>
+ </dict>
+ <key>usages</key>
+ <dict>
+ <key>0</key>
+ <string>Undefined</string>
+ <key>1</key>
+ <string>Monitor Control</string>
+ <key>2</key>
+ <string>EDID Information</string>
+ <key>3</key>
+ <string>VDIF Information</string>
+ <key>4</key>
+ <string>VESA Version</string>
+ <key>5</key>
+ <string>On Screen Display</string>
+ <key>6</key>
+ <string>Auto Size Center</string>
+ <key>7</key>
+ <string>Polarity Horz Synch</string>
+ <key>8</key>
+ <string>Polarity Vert Synch</string>
+ <key>9</key>
+ <string>Sync Type</string>
+ <key>10</key>
+ <string>Screen Position</string>
+ <key>11</key>
+ <string>Horizontal Frequency</string>
+ <key>12</key>
+ <string>Vertical Frequency</string>
+ </dict>
+ </dict>
+ <key>129</key>
+ <dict>
+ <key>default</key>
+ <string>ENUM %d</string>
+ <key>description</key>
+ <string>Monitor Enumerated Values</string>
+ <key>ranges</key>
+ <dict>
+ </dict>
+ <key>usages</key>
+ <dict>
+ <key>0</key>
+ <string>unassigned</string>
+ </dict>
+ </dict>
+ <key>130</key>
+ <dict>
+ <key>description</key>
+ <string>VESA Virtual Controls</string>
+ <key>ranges</key>
+ <dict>
+ </dict>
+ <key>usages</key>
+ <dict>
+ <key>16</key>
+ <string>Brightness</string>
+ <key>18</key>
+ <string>Contrast</string>
+ <key>22</key>
+ <string>Video Gain Red</string>
+ <key>24</key>
+ <string>Video Gain Green</string>
+ <key>26</key>
+ <string>Video Gain Blue</string>
+ <key>28</key>
+ <string>Focus</string>
+ <key>32</key>
+ <string>Horizontal Position</string>
+ <key>34</key>
+ <string>Horizontal Size</string>
+ <key>36</key>
+ <string>Horizontal Pincushion</string>
+ <key>38</key>
+ <string>Horizontal Pincushion Balance</string>
+ <key>40</key>
+ <string>Horizontal Misconvergence</string>
+ <key>42</key>
+ <string>Horizontal Linearity</string>
+ <key>44</key>
+ <string>Horizontal Linearity Balance</string>
+ <key>48</key>
+ <string>Vertical Position</string>
+ <key>50</key>
+ <string>Vertical Size</string>
+ <key>52</key>
+ <string>Vertical Pincushion</string>
+ <key>54</key>
+ <string>Vertical Pincushion Balance</string>
+ <key>56</key>
+ <string>Vertical Misconvergence</string>
+ <key>58</key>
+ <string>Vertical Linearity</string>
+ <key>60</key>
+ <string>Vertical Linearity Balance</string>
+ <key>64</key>
+ <string>Parallelogram Distortion</string>
+ <key>66</key>
+ <string>Trapezoidal Distortion</string>
+ <key>68</key>
+ <string>Tilt</string>
+ <key>70</key>
+ <string>Top Corner Distortion Control</string>
+ <key>72</key>
+ <string>Top Corner Distortion Balance</string>
+ <key>74</key>
+ <string>Bottom Corner Distortion Control</string>
+ <key>76</key>
+ <string>Bottom Corner Distortion Balance</string>
+ <key>86</key>
+ <string>MoirHorizontal</string>
+ <key>88</key>
+ <string>MoirVertical</string>
+ <key>94</key>
+ <string>Input Level Select</string>
+ <key>96</key>
+ <string>Input Source Select</string>
+ <key>98</key>
+ <string>Stereo Mode</string>
+ <key>108</key>
+ <string>Video Black Level Red</string>
+ <key>110</key>
+ <string>Video Black Level Green</string>
+ <key>112</key>
+ <string>Video Black Level Blue</string>
+ </dict>
+ </dict>
+ <key>131</key>
+ <dict>
+ <key>description</key>
+ <string>VESA Command</string>
+ <key>ranges</key>
+ <dict>
+ </dict>
+ <key>usages</key>
+ <dict>
+ <key>0</key>
+ <string>Undefined</string>
+ <key>1</key>
+ <string>Settings</string>
+ <key>2</key>
+ <string>Degauss</string>
+ </dict>
+ </dict>
+ <key>132</key>
+ <dict>
+ <key>description</key>
+ <string>Power Device</string>
+ <key>ranges</key>
+ <dict>
+ </dict>
+ <key>usages</key>
+ <dict>
+ <key>0</key>
+ <string>Undefined</string>
+ <key>1</key>
+ <string>iName</string>
+ <key>2</key>
+ <string>PresentStatus</string>
+ <key>3</key>
+ <string>ChangedStatus</string>
+ <key>4</key>
+ <string>UPS</string>
+ <key>5</key>
+ <string>PowerSupply</string>
+ <key>16</key>
+ <string>BatterySystem</string>
+ <key>17</key>
+ <string>BatterySystemID</string>
+ <key>18</key>
+ <string>Battery</string>
+ <key>19</key>
+ <string>BatteryID</string>
+ <key>20</key>
+ <string>Charger</string>
+ <key>21</key>
+ <string>ChargerID</string>
+ <key>22</key>
+ <string>PowerConverter</string>
+ <key>23</key>
+ <string>PowerConverterID</string>
+ <key>24</key>
+ <string>OutletSystem</string>
+ <key>25</key>
+ <string>OutletSystemID</string>
+ <key>26</key>
+ <string>Input</string>
+ <key>27</key>
+ <string>InputID</string>
+ <key>28</key>
+ <string>Output</string>
+ <key>29</key>
+ <string>OutputID</string>
+ <key>30</key>
+ <string>Flow</string>
+ <key>31</key>
+ <string>FlowID</string>
+ <key>32</key>
+ <string>Outlet</string>
+ <key>33</key>
+ <string>OutletID</string>
+ <key>34</key>
+ <string>Gang</string>
+ <key>35</key>
+ <string>GangID</string>
+ <key>36</key>
+ <string>Sink</string>
+ <key>37</key>
+ <string>SinkID</string>
+ <key>48</key>
+ <string>Voltage</string>
+ <key>49</key>
+ <string>Current</string>
+ <key>50</key>
+ <string>Frequency</string>
+ <key>51</key>
+ <string>ApparentPower</string>
+ <key>52</key>
+ <string>ActivePower</string>
+ <key>53</key>
+ <string>PercentLoad</string>
+ <key>54</key>
+ <string>Temperature</string>
+ <key>55</key>
+ <string>Humidity</string>
+ <key>64</key>
+ <string>ConfigVoltage</string>
+ <key>65</key>
+ <string>ConfigCurrent</string>
+ <key>66</key>
+ <string>ConfigFrequency</string>
+ <key>67</key>
+ <string>ConfigApparentPower</string>
+ <key>68</key>
+ <string>ConfigActivePower</string>
+ <key>69</key>
+ <string>ConfigPercentLoad</string>
+ <key>70</key>
+ <string>ConfigTemperature</string>
+ <key>71</key>
+ <string>ConfigHumidity</string>
+ <key>80</key>
+ <string>SwitchOnControl</string>
+ <key>81</key>
+ <string>SwitchOffControl</string>
+ <key>82</key>
+ <string>ToggleControl</string>
+ <key>83</key>
+ <string>LowVoltageTransfer</string>
+ <key>84</key>
+ <string>HighVoltageTransfer</string>
+ <key>85</key>
+ <string>DelayBeforeReboot</string>
+ <key>86</key>
+ <string>DelayBeforeStartup</string>
+ <key>87</key>
+ <string>DelayBeforeShutdown</string>
+ <key>88</key>
+ <string>Test</string>
+ <key>89</key>
+ <string>Vendorspecificcommand</string>
+ <key>96</key>
+ <string>Present</string>
+ <key>97</key>
+ <string>Good</string>
+ <key>98</key>
+ <string>InternalFailure</string>
+ <key>99</key>
+ <string>VoltageOutOfRange</string>
+ <key>100</key>
+ <string>FrequencyOutOfRange</string>
+ <key>101</key>
+ <string>Overload</string>
+ <key>102</key>
+ <string>OverCharged</string>
+ <key>103</key>
+ <string>OverTemperature</string>
+ <key>104</key>
+ <string>ShutdownRequested</string>
+ <key>105</key>
+ <string>ShutdownImminent</string>
+ <key>106</key>
+ <string>VendorSpecificAnswerValid</string>
+ <key>107</key>
+ <string>SwitchOn/Off</string>
+ <key>108</key>
+ <string>Switcheble</string>
+ <key>109</key>
+ <string>Used</string>
+ <key>110</key>
+ <string>Boost</string>
+ <key>111</key>
+ <string>Buck</string>
+ <key>112</key>
+ <string>Initialized</string>
+ <key>113</key>
+ <string>Tested</string>
+ </dict>
+ </dict>
+ <key>133</key>
+ <dict>
+ <key>description</key>
+ <string>Battery System</string>
+ <key>ranges</key>
+ <dict>
+ </dict>
+ <key>usages</key>
+ <dict>
+ <key>0</key>
+ <string>Undefined</string>
+ <key>1</key>
+ <string>SMBBatteryMode</string>
+ <key>2</key>
+ <string>SMBBatteryStatus</string>
+ <key>3</key>
+ <string>SMBAlarmWarning</string>
+ <key>4</key>
+ <string>SMBChargerMode</string>
+ <key>5</key>
+ <string>SMBChargerStatus</string>
+ <key>6</key>
+ <string>SMBChargerSpecInfo</string>
+ <key>7</key>
+ <string>SMBSelectorState</string>
+ <key>8</key>
+ <string>SMBSelectorPreset</string>
+ <key>9</key>
+ <string>SMBSelectorInfo</string>
+ <key>16</key>
+ <string>OptionalMfgFunction1</string>
+ <key>17</key>
+ <string>OptionalMfgFunction2</string>
+ <key>18</key>
+ <string>OptionalMfgFunction3</string>
+ <key>19</key>
+ <string>OptionalMfgFunction4</string>
+ <key>20</key>
+ <string>OptionalMfgFunction5</string>
+ <key>21</key>
+ <string>ConnectionToSMBus</string>
+ <key>22</key>
+ <string>OutputConnection</string>
+ <key>23</key>
+ <string>ChargerConnection</string>
+ <key>24</key>
+ <string>BatteryInsertion</string>
+ <key>25</key>
+ <string>Usenext</string>
+ <key>26</key>
+ <string>OKToUse</string>
+ <key>40</key>
+ <string>ManufacturerAccess</string>
+ <key>41</key>
+ <string>RemainingCapacityLimit</string>
+ <key>42</key>
+ <string>RemainingTimeLimit</string>
+ <key>43</key>
+ <string>AtRate</string>
+ <key>44</key>
+ <string>CapacityMode</string>
+ <key>45</key>
+ <string>BroadcastToCharger</string>
+ <key>46</key>
+ <string>PrimaryBattery</string>
+ <key>47</key>
+ <string>ChargeController</string>
+ <key>64</key>
+ <string>TerminateCharge</string>
+ <key>65</key>
+ <string>TermminateDischarge</string>
+ <key>66</key>
+ <string>BelowRemainingCapacityLimit</string>
+ <key>67</key>
+ <string>RemainingTimeLimitExpired</string>
+ <key>68</key>
+ <string>Charging</string>
+ <key>69</key>
+ <string>Discharging</string>
+ <key>70</key>
+ <string>FullyCharged</string>
+ <key>71</key>
+ <string>FullyDischarged</string>
+ <key>72</key>
+ <string>ConditionningFlag</string>
+ <key>73</key>
+ <string>AtRateOK</string>
+ <key>74</key>
+ <string>SMBErrorCode</string>
+ <key>75</key>
+ <string>NeedReplacement</string>
+ <key>96</key>
+ <string>AtRateTimeToFull</string>
+ <key>97</key>
+ <string>AtRateTimeToEmpty</string>
+ <key>98</key>
+ <string>AverageCurrent</string>
+ <key>99</key>
+ <string>Maxerror</string>
+ <key>100</key>
+ <string>RelativeStateOfCharge</string>
+ <key>101</key>
+ <string>AbsoluteStateOfCharge</string>
+ <key>102</key>
+ <string>RemainingCapacity</string>
+ <key>103</key>
+ <string>FullChargeCapacity</string>
+ <key>104</key>
+ <string>RunTimeToEmpty</string>
+ <key>105</key>
+ <string>AverageTimeToEmpty</string>
+ <key>106</key>
+ <string>AverageTimeToFull</string>
+ <key>107</key>
+ <string>CycleCount</string>
+ <key>128</key>
+ <string>BattPackModelLevel</string>
+ <key>129</key>
+ <string>InternalChargeController</string>
+ <key>130</key>
+ <string>PrimaryBatterySupport</string>
+ <key>131</key>
+ <string>DesignCapacity</string>
+ <key>132</key>
+ <string>SpecificationInfo</string>
+ <key>133</key>
+ <string>ManufacturerDate</string>
+ <key>134</key>
+ <string>SerialNumber</string>
+ <key>135</key>
+ <string>iManufacturerName</string>
+ <key>136</key>
+ <string>iDevicename</string>
+ <key>137</key>
+ <string>iDeviceChemistery</string>
+ <key>138</key>
+ <string>iManufacturerData</string>
+ <key>139</key>
+ <string>Rechargeable</string>
+ <key>140</key>
+ <string>WarningCapacityLimit</string>
+ <key>141</key>
+ <string>CapacityGranularity1</string>
+ <key>142</key>
+ <string>CapacityGranularity2</string>
+ <key>192</key>
+ <string>InhibitCharge</string>
+ <key>193</key>
+ <string>EnablePolling</string>
+ <key>194</key>
+ <string>ResetToZero</string>
+ <key>208</key>
+ <string>ACPresent</string>
+ <key>209</key>
+ <string>BatteryPresent</string>
+ <key>210</key>
+ <string>PowerFail</string>
+ <key>211</key>
+ <string>AlarmInhibited</string>
+ <key>212</key>
+ <string>ThermistorUnderRange</string>
+ <key>213</key>
+ <string>ThermistorHot</string>
+ <key>214</key>
+ <string>ThermistorCold</string>
+ <key>215</key>
+ <string>ThermistorOverRange</string>
+ <key>216</key>
+ <string>VoltageOutOfRange</string>
+ <key>217</key>
+ <string>CurrentOutOfRange</string>
+ <key>218</key>
+ <string>CurrentNotRegulated</string>
+ <key>219</key>
+ <string>VoltageNotRegulated</string>
+ <key>220</key>
+ <string>MasterMode</string>
+ <key>221</key>
+ <string>ChargerBattery/HostControlled</string>
+ <key>240</key>
+ <string>ChargerSpecInfo</string>
+ <key>241</key>
+ <string>ChargerSpecRef</string>
+ <key>242</key>
+ <string>Level2</string>
+ <key>243</key>
+ <string>Level3</string>
+ </dict>
+ </dict>
+ <key>140</key>
+ <dict>
+ <key>description</key>
+ <string>Bar Code Scanner</string>
+ <key>ranges</key>
+ <dict>
+ </dict>
+ <key>usages</key>
+ <dict>
+ </dict>
+ </dict>
+ <key>141</key>
+ <dict>
+ <key>description</key>
+ <string>Scale Device</string>
+ <key>ranges</key>
+ <dict>
+ </dict>
+ <key>usages</key>
+ <dict>
+ </dict>
+ </dict>
+ <key>144</key>
+ <dict>
+ <key>description</key>
+ <string>Camera Control</string>
+ <key>ranges</key>
+ <dict>
+ </dict>
+ <key>usages</key>
+ <dict>
+ </dict>
+ </dict>
+ <key>145</key>
+ <dict>
+ <key>description</key>
+ <string>Arcade Device</string>
+ <key>ranges</key>
+ <dict>
+ </dict>
+ <key>usages</key>
+ <dict>
+ <key>233</key>
+ <string>Base Up</string>
+ <key>234</key>
+ <string>Base Down</string>
+ </dict>
+ </dict>
+ </dict>
+</plist>
diff --git a/lib/DDHidUsage.h b/lib/DDHidUsage.h
new file mode 100644
index 0000000..8dc5654
--- /dev/null
+++ b/lib/DDHidUsage.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+
+@interface DDHidUsage : NSObject
+{
+ unsigned mUsagePage;
+ unsigned mUsageId;
+}
+
++ (DDHidUsage *) usageWithUsagePage: (unsigned) usagePage
+ usageId: (unsigned) usageId;
+
+- (id) initWithUsagePage: (unsigned) usagePage
+ usageId: (unsigned) usageId;
+
+- (unsigned) usagePage;
+
+- (unsigned) usageId;
+
+- (NSString *) usageName;
+
+- (NSString *) usageNameWithIds;
+
+- (NSString *) description;
+
+- (BOOL) isEqualToUsagePage: (unsigned) usagePage usageId: (unsigned) usageId;
+
+@end
diff --git a/lib/DDHidUsage.m b/lib/DDHidUsage.m
new file mode 100644
index 0000000..8fe2c11
--- /dev/null
+++ b/lib/DDHidUsage.m
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import "DDHidUsage.h"
+#import "DDHidUsageTables.h"
+
+@implementation DDHidUsage
+
++ (DDHidUsage *) usageWithUsagePage: (unsigned) usagePage
+ usageId: (unsigned) usageId;
+{
+ return [[[self alloc] initWithUsagePage: usagePage usageId: usageId]
+ autorelease];
+}
+
+- (id) initWithUsagePage: (unsigned) usagePage
+ usageId: (unsigned) usageId;
+{
+ self = [super init];
+ if (self == nil)
+ return nil;
+
+ mUsagePage = usagePage;
+ mUsageId = usageId;
+
+ return self;
+}
+
+- (unsigned) usagePage;
+{
+ return mUsagePage;
+}
+
+- (unsigned) usageId;
+{
+ return mUsageId;
+}
+
+- (NSString *) usageName;
+{
+ DDHidUsageTables * usageTables = [DDHidUsageTables standardUsageTables];
+ return
+ [usageTables descriptionForUsagePage: mUsagePage
+ usage: mUsageId];
+}
+
+- (NSString *) usageNameWithIds;
+{
+ return [NSString stringWithFormat: @"%@ (0x%04x : 0x%04x)",
+ [self usageName], mUsagePage, mUsageId];
+}
+
+- (NSString *) description;
+{
+ return [NSString stringWithFormat: @"HID Usage: %@", [self usageName]];
+}
+
+- (BOOL) isEqualToUsagePage: (unsigned) usagePage usageId: (unsigned) usageId;
+{
+ return ((mUsagePage == usagePage) && (mUsageId == usageId));
+}
+
+@end
diff --git a/lib/DDHidUsageTables.h b/lib/DDHidUsageTables.h
new file mode 100644
index 0000000..be8d46e
--- /dev/null
+++ b/lib/DDHidUsageTables.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+
+@interface DDHidUsageTables : NSObject
+{
+ NSDictionary * mLookupTables;
+}
+
++ (DDHidUsageTables *) standardUsageTables;
+
+- (id) initWithLookupTables: (NSDictionary *) lookupTables;
+
+- (NSString *) descriptionForUsagePage: (unsigned) usagePage
+ usage: (unsigned) usage;
+
+@end
diff --git a/lib/DDHidUsageTables.m b/lib/DDHidUsageTables.m
new file mode 100644
index 0000000..9e7703a
--- /dev/null
+++ b/lib/DDHidUsageTables.m
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import "DDHidUsageTables.h"
+
+@implementation DDHidUsageTables
+
+static DDHidUsageTables * sStandardUsageTables = nil;
+
++ (DDHidUsageTables *) standardUsageTables;
+{
+ if (sStandardUsageTables == nil)
+ {
+ NSBundle * myBundle = [NSBundle bundleForClass: self];
+ NSString * usageTablesPath =
+ [myBundle pathForResource: @"DDHidStandardUsages" ofType: @"plist"];
+ NSDictionary * lookupTables =
+ [NSDictionary dictionaryWithContentsOfFile: usageTablesPath];
+ sStandardUsageTables =
+ [[DDHidUsageTables alloc] initWithLookupTables: lookupTables];
+ [sStandardUsageTables retain];
+ }
+
+ return sStandardUsageTables;
+}
+
+- (id) initWithLookupTables: (NSDictionary *) lookupTables;
+{
+ self = [super init];
+ if (self == nil)
+ return nil;
+
+ mLookupTables = [lookupTables retain];
+
+ return self;
+}
+
+- (NSString *) descriptionForUsagePage: (unsigned) usagePage
+ usage: (unsigned) usage
+{
+ NSString * usagePageString = [NSString stringWithFormat: @"%u", usagePage];
+ NSString * usageString = [NSString stringWithFormat: @"%u", usage];
+ // NSNumber * usagePageNumber = [NSNumber numberWithUnsignedInt: usagePage];
+
+ NSDictionary * usagePageLookup = [mLookupTables objectForKey: usagePageString];
+ if (usagePageLookup == nil)
+ return @"Unknown usage page";
+
+ NSDictionary * usageLookup = [usagePageLookup objectForKey: @"usages"];
+ NSString * description = [usageLookup objectForKey: usageString];
+ if (description != nil)
+ return description;
+
+ NSString * defaultUsage = [usagePageLookup objectForKey: @"default"];
+ if (defaultUsage != nil)
+ {
+ description = [NSString stringWithFormat: defaultUsage, usage];
+ return description;
+ }
+
+ return @"Unknown usage";
+}
+
+@end
diff --git a/lib/NSDictionary+DDHidExtras.h b/lib/NSDictionary+DDHidExtras.h
new file mode 100644
index 0000000..750d0d4
--- /dev/null
+++ b/lib/NSDictionary+DDHidExtras.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import <Cocoa/Cocoa.h>
+
+
+@interface NSDictionary (DDHidExtras)
+
+- (unsigned) ddhid_unsignedForKey: (NSString *) key;
+
+- (id) ddhid_objectForString: (const char *) key;
+
+- (NSString *) ddhid_stringForString: (const char *) key;
+- (long) ddhid_longForString: (const char *) key;
+- (unsigned int) ddhid_unsignedIntForString: (const char *) key;
+- (BOOL) ddhid_boolForString: (const char *) key;
+
+@end
+
+@interface NSMutableDictionary (DDHidExtras)
+
+- (void) ddhid_setObject: (id) object forString: (const char *) key;
+- (void) ddhid_setInt: (int) i forKey: (id) key;
+
+@end
diff --git a/lib/NSDictionary+DDHidExtras.m b/lib/NSDictionary+DDHidExtras.m
new file mode 100644
index 0000000..4864a48
--- /dev/null
+++ b/lib/NSDictionary+DDHidExtras.m
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2007 Dave Dribin
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#import "NSDictionary+DDHidExtras.h"
+
+
+@implementation NSDictionary (DDHidExtras)
+
+- (unsigned) ddhid_unsignedForKey: (NSString *) key;
+{
+ NSNumber * number = [self objectForKey: key];
+ return [number unsignedIntValue];
+}
+
+- (id) ddhid_objectForString: (const char *) key;
+{
+ NSString * objcKey = [NSString stringWithUTF8String: key];
+ return [self objectForKey: objcKey];
+}
+
+- (NSString *) ddhid_stringForString: (const char *) key;
+{
+ return [self ddhid_objectForString: key];
+}
+
+- (long) ddhid_longForString: (const char *) key;
+{
+ NSNumber * number = [self ddhid_objectForString: key];
+ return [number longValue];
+}
+
+- (unsigned int) ddhid_unsignedIntForString: (const char *) key;
+{
+ NSNumber * number = [self ddhid_objectForString: key];
+ return [number unsignedIntValue];
+}
+
+- (BOOL) ddhid_boolForString: (const char *) key;
+{
+ NSNumber * number = [self ddhid_objectForString: key];
+ return [number boolValue];
+}
+
+@end
+
+@implementation NSMutableDictionary (DDHidExtras)
+
+- (void) ddhid_setObject: (id) object forString: (const char *) key;
+{
+ NSString * objcKey = [NSString stringWithUTF8String: key];
+ [self setObject: object forKey: objcKey];
+}
+
+- (void) ddhid_setInt: (int) i forKey: (id) key;
+{
+ NSNumber * number = [NSNumber numberWithInt: i];
+ [self setObject: number forKey: key];
+}
+
+@end
diff --git a/usb_hid_usages.txt b/usb_hid_usages.txt
new file mode 100644
index 0000000..93ae0ed
--- /dev/null
+++ b/usb_hid_usages.txt
@@ -0,0 +1,1086 @@
+# $NetBSD: usb_hid_usages,v 1.2 2004/05/16 13:22:23 lukem Exp $
+#
+# USB HID usage table
+# Syntax:
+# - lines that do not start with a white space give the number and name of
+# a usage page.
+# - lines that start with a white space give the number and name of
+# a usage with the last given page.
+# If the number is * then the line matches all usages and the name
+# is a printf formatting string that will be given the usage number.
+#
+1 Generic Desktop
+ 0x00 Undefined
+ 0x01 Pointer
+ 0x02 Mouse
+ 0x03 Reserved
+ 0x04 Joystick
+ 0x05 Game Pad
+ 0x06 Keyboard
+ 0x07 Keypad
+ 0x08 Multi-axis Controller
+ 0x30 X
+ 0x31 Y
+ 0x32 Z
+ 0x33 Rx
+ 0x34 Ry
+ 0x35 Rz
+ 0x36 Slider
+ 0x37 Dial
+ 0x38 Wheel
+ 0x39 Hat Switch
+ 0x3A Counted Buffer
+ 0x3B Byte Count
+ 0x3C Motion Wakeup
+ 0x40 Vx
+ 0x41 Vy
+ 0x42 Vz
+ 0x43 Vbrx
+ 0x44 Vbry
+ 0x45 Vbrx
+ 0x46 Vno
+ 0x80 System Control
+ 0x81 System Power Down
+ 0x82 System Sleep
+ 0x83 System Wake Up
+ 0x84 System Context Menu
+ 0x85 System Main Menu
+ 0x86 System App Menu
+ 0x87 System Menu Help
+ 0x88 System Menu Exit
+ 0x89 System Menu Select
+ 0x8A System Menu Right
+ 0x8B System Menu Left
+ 0x8C System Menu Up
+ 0x8D System Menu Down
+ 0x90 D-pad Up
+ 0x91 D-pad Down
+ 0x92 D-pad Right
+ 0x93 D-pad Left
+
+2 Simulation Controls
+ 0x00 Undefined
+ 0x01 Flight Simulation Device
+ 0x02 Automobile Simulation Device
+ 0x03 Tank Simulation Device
+ 0x04 Spaceship Simulation Device
+ 0x05 Submarine Simulation Device
+ 0x06 Sailing Simulation Device
+ 0x07 Motorcycle Simulation Device
+ 0x08 Sports Simulation Device
+ 0x09 Airplane Simulation Device
+ 0x0A Helicopter Simulation Device
+ 0x0B Magic Carpet Simulation Device
+ 0x0C Bicycle
+ 0x20 Flight Control Stick
+ 0x21 Flight Stick
+ 0x22 Cyclic Control
+ 0x23 Cyclic Trim
+ 0x24 Flight Yoke
+ 0x25 Track Control
+ 0x26 Driving Control
+ 0xB0 Aileron
+ 0xB1 Aileron Trim
+ 0xB2 Anti-Torque Control
+ 0xB3 Auto-pilot Enable
+ 0xB4 Chaff Release
+ 0xB5 Collective Control
+ 0xB6 Dive Brake
+ 0xB7 Electronic Counter Measures
+ 0xB8 Elevator
+ 0xB9 Elevator Trim
+ 0xBA Rudder
+ 0xBB Throttle
+ 0xBC Flight Communication
+ 0xBD Flare Release
+ 0xBE Landing Gear
+ 0xBF Toe Brake
+ 0xC0 Trigger
+ 0xC1 Weapons Arm
+ 0xC2 Weapons Select
+ 0xC3 Wing Flaps
+ 0xC4 Accelerator
+ 0xC5 Brake
+ 0xC6 Clutch
+ 0xC7 Shifter
+ 0xC8 Steering
+ 0xC9 Turret Direction
+ 0xCA Barrel Elevation
+ 0xCB Dive Plane
+ 0xCC Ballast
+ 0xCD Bicycle Crank
+ 0xCE Handle Bars
+ 0xCF Front Brake
+ 0xD0 Rear Brake
+
+3 VR Controls
+ 0x00 Unidentified
+ 0x01 Belt
+ 0x02 Body Suit
+ 0x03 Flexor
+ 0x04 Glove
+ 0x05 Head Tracker
+ 0x06 Head Mounted Display
+ 0x07 Hand Tracker
+ 0x08 Oculometer
+ 0x09 Vest
+ 0x0A Animatronic Device
+ 0x20 Stereo Enable
+ 0x21 Display Enable
+
+4 Sports Controls
+ 0x00 Unidentified
+ 0x01 Baseball Bat
+ 0x02 Golf Club
+ 0x03 Rowing Machine
+ 0x04 Treadmill
+ 0x30 Oar
+ 0x31 Slope
+ 0x32 Rate
+ 0x33 Stick Speed
+ 0x34 Stick Face Angle
+ 0x35 Stick Heel/Toe
+ 0x36 Stick Follow Through
+ 0x37 Stick Tempo
+ 0x38 Stick Type
+ 0x39 Stick Height
+ 0x50 Putter
+ 0x51 1 Iron
+ 0x52 2 Iron
+ 0x53 3 Iron
+ 0x54 4 Iron
+ 0x55 5 Iron
+ 0x56 6 Iron
+ 0x57 7 Iron
+ 0x58 8 Iron
+ 0x59 9 Iron
+ 0x5A 10 Iron
+ 0x5B 11 Iron
+ 0x5C Sand Wedge
+ 0x5D Loft Wedge
+ 0x5E Power Wedge
+ 0x5F 1 Wood
+ 0x60 3 Wood
+ 0x61 5 Wood
+ 0x62 7 Wood
+ 0x63 9 Wood
+
+5 Game Controls
+ 0x00 Undefined
+ 0x01 3D Game Controller
+ 0x02 Pinball Device
+ 0x03 Gun Device
+ 0x20 Point of View
+ 0x21 Turn Right/Left
+ 0x22 Pitch Right/Left
+ 0x23 Roll Forward/Backward
+ 0x24 Move Right/Left
+ 0x25 Move Forward/Backward
+ 0x26 Move Up/Down
+ 0x27 Lean Right/Left
+ 0x28 Lean Forward/Backward
+ 0x29 Height of POV
+ 0x2A Flipper
+ 0x2B Secondary Flipper
+ 0x2C Bump
+ 0x2D New Game
+ 0x2E Shoot Ball
+ 0x2F Player
+ 0x30 Gun Bolt
+ 0x31 Gun Clip
+ 0x32 Gun Selector
+ 0x33 Gun Single Shot
+ 0x34 Gun Burst
+ 0x35 Gun Automatic
+ 0x36 Gun Safety
+ 0x37 Gamepad Fire/Jump
+ 0x39 Gamepad Trigger
+
+7 Keyboard
+ 0x00 No Event
+ 0x01 Keyboard ErrorRollOver
+ 0x02 Keyboard POSTFail
+ 0x03 Keyboard ErrorUndefined
+ 0x04 Keyboard a and A
+ 0x05 Keyboard b and B
+ 0x06 Keyboard c and C
+ 0x07 Keyboard d and D
+ 0x08 Keyboard e and E
+ 0x09 Keyboard f and F
+ 0x0A Keyboard g and G
+ 0x0B Keyboard h and H
+ 0x0C Keyboard i and I
+ 0x0D Keyboard j and J
+ 0x0E Keyboard k and K
+ 0x0F Keyboard l and L
+ 0x10 Keyboard m and M
+ 0x11 Keyboard n and N
+ 0x12 Keyboard o and O
+ 0x13 Keyboard p and P
+ 0x14 Keyboard q and Q
+ 0x15 Keyboard r and R
+ 0x16 Keyboard s and S
+ 0x17 Keyboard t and T
+ 0x18 Keyboard u and U
+ 0x19 Keyboard v and V
+ 0x1A Keyboard w and W
+ 0x1B Keyboard x and X
+ 0x1C Keyboard y and Y
+ 0x1D Keyboard z and Z
+ 0x1E Keyboard 1 and !
+ 0x1F Keyboard 2 and @
+ 0x20 Keyboard 3 and #
+ 0x21 Keyboard 4 and $
+ 0x22 Keyboard 5 and %
+ 0x23 Keyboard 6 and ^
+ 0x24 Keyboard 7 and &
+ 0x25 Keyboard 8 and *
+ 0x26 Keyboard 9 and (
+ 0x27 Keyboard 0 and )
+ 0x28 Keyboard Return (ENTER)
+ 0x29 Keyboard ESCAPE
+ 0x2A Keyboard DELETE (Backspace)
+ 0x2B Keyboard Tab
+ 0x2C Keyboard Spacebar
+ 0x2D Keyboard - and (underscore)
+ 0x2E Keyboard = and +
+ 0x2F Keyboard [ and {
+ 0x30 Keyboard ] and }
+ 0x31 Keyboard \ and |
+ 0x32 Keyboard Non-US # and ~
+ 0x33 Keyboard ; and :
+ 0x34 Keyboard ' and "
+ 0x35 Keyboard Grave Accent and Tilde
+ 0x36 Keyboard, and <
+ 0x37 Keyboard . and >
+ 0x38 Keyboard / and ?
+ 0x39 Keyboard Caps Lock
+ 0x3A Keyboard F1
+ 0x3B Keyboard F2
+ 0x3C Keyboard F3
+ 0x3D Keyboard F4
+ 0x3E Keyboard F5
+ 0x3F Keyboard F6
+ 0x40 Keyboard F7
+ 0x41 Keyboard F8
+ 0x42 Keyboard F9
+ 0x43 Keyboard F10
+ 0x44 Keyboard F11
+ 0x45 Keyboard F12
+ 0x46 Keyboard PrintScreen
+ 0x47 Keyboard Scroll Lock
+ 0x48 Keyboard Pause
+ 0x49 Keyboard Insert
+ 0x4A Keyboard Home
+ 0x4B Keyboard PageUp
+ 0x4C Keyboard Delete Forward
+ 0x4D Keyboard End
+ 0x4E Keyboard PageDown
+ 0x4F Keyboard RightArrow
+ 0x50 Keyboard LeftArrow
+ 0x51 Keyboard DownArrow
+ 0x52 Keyboard UpArrow
+ 0x53 Keypad Num Lock and Clear
+ 0x54 Keypad /
+ 0x55 Keypad *
+ 0x56 Keypad -
+ 0x57 Keypad +
+ 0x58 Keypad ENTER
+ 0x59 Keypad 1 and End
+ 0x5A Keypad 2 and Down Arrow
+ 0x5B Keypad 3 and PageDn
+ 0x5C Keypad 4 and Left Arrow
+ 0x5D Keypad 5
+ 0x5E Keypad 6 and Right Arrow
+ 0x5F Keypad 7 and Home
+ 0x60 Keypad 8 and Up Arrow
+ 0x61 Keypad 9 and PageUp
+ 0x62 Keypad 0 and Insert
+ 0x63 Keypad . and Delete
+ 0x64 Keyboard Non-US \ and |
+ 0x65 Keyboard Application
+ 0x66 Keyboard Power
+ 0x67 Keypad =
+ 0x68 Keyboard F13
+ 0x69 Keyboard F14
+ 0x6A Keyboard F15
+ 0x6B Keyboard F16
+ 0x6C Keyboard F17
+ 0x6D Keyboard F18
+ 0x6E Keyboard F19
+ 0x6F Keyboard F20
+ 0x70 Keyboard F21
+ 0x71 Keyboard F22
+ 0x72 Keyboard F23
+ 0x73 Keyboard F24
+ 0x74 Keyboard Execute
+ 0x75 Keyboard Help
+ 0x76 Keyboard Menu
+ 0x77 Keyboard Select
+ 0x78 Keyboard Stop
+ 0x79 Keyboard Again
+ 0x7A Keyboard Undo
+ 0x7B Keyboard Cut
+ 0x7C Keyboard Copy
+ 0x7D Keyboard Paste
+ 0x7E Keyboard Find
+ 0x7F Keyboard Mute
+ 0x80 Keyboard Volume Up
+ 0x81 Keyboard Volume Down
+ 0x82 Keyboard Locking Caps Lock
+ 0x83 Keyboard Locking Num Lock
+ 0x84 Keyboard Locking Scroll Lock
+ 0x85 Keypad Comma
+ 0x86 Keypad Equal Sign
+ 0x87 Keyboard International1
+ 0x88 Keyboard International2
+ 0x89 Keyboard International3
+ 0x8A Keyboard International4
+ 0x8B Keyboard International5
+ 0x8C Keyboard International6
+ 0x8D Keyboard International7
+ 0x8E Keyboard International8
+ 0x8F Keyboard International9
+ 0x90 Keyboard LANG1
+ 0x91 Keyboard LANG2
+ 0x92 Keyboard LANG3
+ 0x93 Keyboard LANG4
+ 0x94 Keyboard LANG5
+ 0x95 Keyboard LANG6
+ 0x96 Keyboard LANG7
+ 0x97 Keyboard LANG8
+ 0x98 Keyboard LANG9
+ 0x99 Keyboard Alternate Erase
+ 0x9A Keyboard SysReq/Attention
+ 0x9B Keyboard Cancel
+ 0x9C Keyboard Clear
+ 0x9D Keyboard Prior
+ 0x9E Keyboard Return
+ 0x9F Keyboard Separator
+ 0xA0 Keyboard Out
+ 0xA1 Keyboard Oper
+ 0xA2 Keyboard Clear/Again
+ 0xA3 Keyboard CrSel/Props
+ 0xA4 Keyboard ExSel
+ 0xE0 Keyboard LeftControl
+ 0xE1 Keyboard LeftShift
+ 0xE2 Keyboard LeftAlt
+ 0xE3 Keyboard Left GUI
+ 0xE4 Keyboard RightControl
+ 0xE5 Keyboard RightShift
+ 0xE6 Keyboard RightAlt
+ 0xE7 Keyboard Right GUI
+
+8 LEDs
+ 0x00 Undefined
+ 0x01 Num Lock
+ 0x02 Caps Lock
+ 0x03 Scroll Lock
+ 0x04 Compose
+ 0x05 Kana
+ 0x06 Power
+ 0x07 Shift
+ 0x08 Do Not Disturb
+ 0x09 Mute
+ 0x0A Tone Enable
+ 0x0B High Cut Filter
+ 0x0C Low Cut Filter
+ 0x0D Equalizer Enable
+ 0x0E Sound Field On
+ 0x0F Surround Field On
+ 0x10 Repeat
+ 0x11 Stereo
+ 0x12 Sampling Rate Detect
+ 0x13 Spinning
+ 0x14 CAV
+ 0x15 CLV
+ 0x16 Recording Format Detect
+ 0x17 Off-Hook
+ 0x18 Ring
+ 0x19 Message Waiting
+ 0x1A Data Mode
+ 0x1B Battery Operation
+ 0x1C Battery OK
+ 0x1D Battery Low
+ 0x1E Speaker
+ 0x1F Head Set
+ 0x20 Hold
+ 0x21 Microphone
+ 0x22 Coverage
+ 0x23 Night Mode
+ 0x24 Send Calls
+ 0x25 Call Pickup
+ 0x26 Conference
+ 0x27 Stand-by
+ 0x28 Camera On
+ 0x29 Camera Off
+ 0x2A On-Line
+ 0x2B Off-Line
+ 0x2C Busy
+ 0x2D Ready
+ 0x2E Paper-Out
+ 0x2F Paper-Jam
+ 0x30 Remote
+ 0x31 Forward
+ 0x32 Reverse
+ 0x33 Stop
+ 0x34 Rewind
+ 0x35 Fast Forward
+ 0x36 Play
+ 0x37 Pause
+ 0x38 Record
+ 0x39 Error
+ 0x3A Usage Selected Indicator
+ 0x3B Usage In Use Indicator
+ 0x3C Usage Multi Mode Indicator
+ 0x3D Indicator On
+ 0x3E Indicator Flash
+ 0x3F Indicator Slow Blink
+ 0x40 Indicator Fast Blink
+ 0x41 Indicator Off
+ 0x42 Flash On Time
+ 0x43 Slow Blink On Time
+ 0x44 Slow Blink Off Time
+ 0x45 Fast Blink On Time
+ 0x46 Fast Blink Off Time
+ 0x47 Usage Indicator Color
+ 0x48 Red
+ 0x49 Green
+ 0x4A Amber
+ 0x4B Generic Indicator
+ 0x4C System Suspend
+ 0x4D External Power Connected
+ 0x4C-FFFF Reserved
+
+9 Button
+ 0x00 No Button Pressed
+ * Button %d
+
+10 Ordinal
+ 0x00 Unused
+ * Instance %d
+
+11 Telephony
+ 0x00 Unassigned
+ 0x01 Phone
+ 0x02 Answering Machine
+ 0x03 Message Controls
+ 0x04 Handset
+ 0x05 Headset
+ 0x06 Telephony Key Pad
+ 0x07 Programmable Button
+ 0x20 Hook Switch
+ 0x21 Flash
+ 0x22 Feature
+ 0x23 Hold
+ 0x24 Redial
+ 0x25 Transfer
+ 0x26 Drop
+ 0x27 Park
+ 0x28 Forward Calls
+ 0x29 Alternate Function
+ 0x2A Line
+ 0x2B Speaker Phone
+ 0x2C Conference
+ 0x2D Ring Enable
+ 0x2E Ring Select
+ 0x2F Phone Mute
+ 0x30 Caller ID
+ 0x50 Speed Dial
+ 0x51 Store Number
+ 0x52 Recall Number
+ 0x53 Phone Directory
+ 0x70 Voice Mail
+ 0x71 Screen Calls
+ 0x72 Do Not Disturb
+ 0x73 Message
+ 0x74 Answer On/Off
+ 0x90 Inside Dial Tone
+ 0x91 Outside Dial Tone
+ 0x92 Inside Ring Tone
+ 0x93 Outside Ring Tone
+ 0x94 Priority Ring Tone
+ 0x95 Inside Ringback
+ 0x96 Priority Ringback
+ 0x97 Line Busy Tone
+ 0x98 Reorder Tone
+ 0x99 Call Waiting Tone
+ 0x9A Confirmation Tone 1
+ 0x9B Confirmation Tone 2
+ 0x9C Tones Off
+ 0xB0 Phone Key 0
+ 0xB1 Phone Key 1
+ 0xB2 Phone Key 2
+ 0xB3 Phone Key 3
+ 0xB4 Phone Key 4
+ 0xB5 Phone Key 5
+ 0xB6 Phone Key 6
+ 0xB7 Phone Key 7
+ 0xB8 Phone Key 8
+ 0xB9 Phone Key 9
+ 0xBA Phone Key Star
+ 0xBB Phone Key Pound
+ 0xBC Phone Key A
+ 0xBD Phone Key B
+ 0xBE Phone Key C
+ 0xBF Phone Key D
+
+12 Consumer
+ 0x00 Unassigned
+ 0x01 Consumer Control
+ 0x02 Numeric Key Pad
+ 0x03 Programmable Buttons
+ 0x20 +10
+ 0x21 +100
+ 0x22 AM/PM
+ 0x30 Power
+ 0x31 Reset
+ 0x32 Sleep
+ 0x33 Sleep After
+ 0x34 Sleep Mode
+ 0x35 Illumination
+ 0x36 Function Buttons
+ 0x40 Menu
+ 0x41 Menu Pick
+ 0x42 Menu Up
+ 0x43 Menu Down
+ 0x44 Menu Left
+ 0x45 Menu Right
+ 0x46 Menu Escape
+ 0x47 Menu Value Increase
+ 0x48 Menu Value Decrease
+ 0x60 Data On Screen
+ 0x61 Closed Caption
+ 0x62 Closed Caption Select
+ 0x63 VCR/TV
+ 0x64 Broadcast Mode
+ 0x65 Snapshot
+ 0x66 Still
+ 0x80 Selection
+ 0x81 Assign Selection
+ 0x82 Mode Step
+ 0x83 Recall Last
+ 0x84 Enter Channel
+ 0x85 Order Movie
+ 0x86 Channel
+ 0x87 Media Selection
+ 0x88 Media Select Computer
+ 0x89 Media Select TV
+ 0x8A Media Select WWW
+ 0x8B Media Select DVD
+ 0x8C Media Select Telephone
+ 0x8D Media Select Program Guide
+ 0x8E Media Select Video Phone
+ 0x8F Media Select Games
+ 0x90 Media Select Messages
+ 0x91 Media Select CD
+ 0x92 Media Select VCR
+ 0x93 Media Select Tuner
+ 0x94 Quit
+ 0x95 Help
+ 0x96 Media Select Tape
+ 0x97 Media Select Cable
+ 0x98 Media Select Satellite
+ 0x99 Media Select Security
+ 0x9A Media Select Home
+ 0x9B Media Select Call
+ 0x9C Channel Increment
+ 0x9D Channel Decrement
+ 0x9E Media Select SAP
+ 0xA0 VCR Plus
+ 0xA1 Once
+ 0xA2 Daily
+ 0xA3 Weekly
+ 0xA4 Monthly
+ 0xB0 Play
+ 0xB1 Pause
+ 0xB2 Record
+ 0xB3 Fast Forward
+ 0xB4 Rewind
+ 0xB5 Scan Next Track
+ 0xB6 Scan Previous Track
+ 0xB7 Stop
+ 0xB8 Eject
+ 0xB9 Random Play
+ 0xBA Select DisC
+ 0xBB Enter Disc
+ 0xBC Repeat
+ 0xBD Tracking
+ 0xBE Track Normal
+ 0xBF Slow Tracking
+ 0xC0 Frame Forward
+ 0xC1 Frame Back
+ 0xC2 Mark
+ 0xC3 Clear Mark
+ 0xC4 Repeat From Mark
+ 0xC5 Return To Mark
+ 0xC6 Search Mark Forward
+ 0xC7 Search Mark Backwards
+ 0xC8 Counter Reset
+ 0xC9 Show Counter
+ 0xCA Tracking Increment
+ 0xCB Tracking Decrement
+ 0xCD Pause/Play
+ 0xE0 Volume
+ 0xE1 Balance
+ 0xE2 Mute
+ 0xE3 Bass
+ 0xE4 Treble
+ 0xE5 Bass Boost
+ 0xE6 Surround Mode
+ 0xE7 Loudness
+ 0xE8 MPX
+ 0xE9 Volume Up
+ 0xEA Volume Down
+ 0xF0 Speed Select
+ 0xF1 Playback Speed
+ 0xF2 Standard Play
+ 0xF3 Long Play
+ 0xF4 Extended Play
+ 0xF5 Slow
+ 0x100 Fan Enable
+ 0x101 Fan Speed
+ 0x102 Light
+ 0x103 Light Illumination Level
+ 0x104 Climate Control Enable
+ 0x105 Room Temperature
+ 0x106 Security Enable
+ 0x107 Fire Alarm
+ 0x108 Police Alarm
+ 0x150 Balance Right
+ 0x151 Balance Left
+ 0x152 Bass Increment
+ 0x153 Bass Decrement
+ 0x154 Treble Increment
+ 0x155 Treble Decrement
+ 0x160 Speaker System
+ 0x161 Channel Left
+ 0x162 Channel Right
+ 0x163 Channel Center
+ 0x164 Channel Front
+ 0x165 Channel Center Front
+ 0x166 Channel Side
+ 0x167 Channel Surround
+ 0x168 Channel Low Frequency Enhancement
+ 0x169 Channel Top
+ 0x16A Channel Unknown
+ 0x170 Sub-channel
+ 0x171 Sub-channel Increment
+ 0x172 Sub-channel Decrement
+ 0x173 Alternate Audio Increment
+ 0x174 Alternate Audio Decrement
+ 0x180 Application Launch Buttons
+ 0x181 AL Launch Button Configuration Tool
+ 0x182 AL Programmable Button Configuration
+ 0x183 AL Consumer Control Configuration
+ 0x184 AL Word Processor
+ 0x185 AL Text Editor
+ 0x186 AL Spreadsheet
+ 0x187 AL Graphics Editor
+ 0x188 AL Presentation App
+ 0x189 AL Database App
+ 0x18A AL Email Reader
+ 0x18B AL Newsreader
+ 0x18C AL Voicemail
+ 0x18D AL Contacts/Address Book
+ 0x18E AL Calendar/Schedule
+ 0x18F AL Task/Project Manager
+ 0x190 AL Log/Journal/Timecard
+ 0x191 AL Checkbook/Finance
+ 0x192 AL Calculator
+ 0x193 AL A/V Capture/Playback
+ 0x194 AL Local Machine Browser
+ 0x195 AL LAN/WAN Browser
+ 0x196 AL Internet Browser
+ 0x197 AL Remote Networking/ISP Connect
+ 0x198 AL Network Conference
+ 0x199 AL Network Chat
+ 0x19A AL Telephony/Dialer
+ 0x19B AL Logon
+ 0x19C AL Logoff
+ 0x19D AL Logon/Logoff
+ 0x19E AL Terminal Lock/Screensaver
+ 0x19F AL Control Panel
+ 0x1A0 AL Command Line Processor/Run
+ 0x1A1 AL Process/Task Manager
+ 0x1A2 AL Select Tast/Application
+ 0x1A3 AL Next Task/Application
+ 0x1A4 AL Previous Task/Application
+ 0x1A5 AL Preemptive Halt Task/Application
+ 0x1A7 AL My Documents
+ 0x1AB AC Spell
+ 0x1B6 AL My Pictures
+ 0x1B7 AL My Music
+ 0x200 Generic GUI Application Controls
+ 0x201 AC New
+ 0x202 AC Open
+ 0x203 AC Close
+ 0x204 AC Exit
+ 0x205 AC Maximize
+ 0x206 AC Minimize
+ 0x207 AC Save
+ 0x208 AC Print
+ 0x209 AC Properties
+ 0x21A AC Undo
+ 0x21B AC Copy
+ 0x21C AC Cut
+ 0x21D AC Paste
+ 0x21E AC Select All
+ 0x21F AC Find
+ 0x220 AC Find and Replace
+ 0x221 AC Search
+ 0x222 AC Go To
+ 0x223 AC Home
+ 0x224 AC Back
+ 0x225 AC Forward
+ 0x226 AC Stop
+ 0x227 AC Refresh
+ 0x228 AC Previous Link
+ 0x229 AC Next Link
+ 0x22A AC Bookmarks
+ 0x22B AC History
+ 0x22C AC Subscriptions
+ 0x22D AC Zoom In
+ 0x22E AC Zoom Out
+ 0x22F AC Zoom
+ 0x230 AC Full Screen View
+ 0x231 AC Normal View
+ 0x232 AC View Toggle
+ 0x233 AC Scroll Up
+ 0x234 AC Scroll Down
+ 0x235 AC Scroll
+ 0x236 AC Pan Left
+ 0x237 AC Pan Right
+ 0x238 AC Pan
+ 0x239 AC New Window
+ 0x23A AC Tile Horizontally
+ 0x23B AC Tile Vertically
+ 0x23C AC Format
+ 0x279 AC Redo
+ 0x289 AC Reply
+ 0x28B AC Fwd
+ 0x28C AC Send
+
+13 Digitizer
+ 0x00 Undefined
+ 0x01 Digitizer
+ 0x02 Pen
+ 0x03 Light Pen
+ 0x04 Touch Screen
+ 0x05 Touch Pad
+ 0x06 White Board
+ 0x07 Coordinate Measuring Machine
+ 0x08 3-D Digitizer
+ 0x09 Stereo Plotter
+ 0x0A Articulated Arm
+ 0x0B Armature
+ 0x0C Multiple Point Digitizer
+ 0x0D Free Space Wand
+ 0x20 Stylus
+ 0x21 Puck
+ 0x22 Finger
+ 0x30 Tip Pressure
+ 0x31 Barrel Pressure
+ 0x32 In Range
+ 0x33 Touch
+ 0x34 Untouch
+ 0x35 Tap
+ 0x36 Quality
+ 0x37 Data Valid
+ 0x38 Transducer Index
+ 0x39 Tablet Function Keys
+ 0x3A Program Change Keys
+ 0x3B Battery Strength
+ 0x3C Invert
+ 0x3D X Tilt
+ 0x3E Y Tilt
+ 0x3F Azimuth
+ 0x40 Altitude
+ 0x41 Twist
+ 0x42 Tip Switch
+ 0x43 Secondary Tip Switch
+ 0x44 Barrel Switch
+ 0x45 Eraser
+ 0x46 Tablet Pick
+
+15 Physical Interface Device
+
+16 Unicode
+ * Unicode Char u%04x
+
+20 Alphnumeric Display
+ 0x00 Undefined
+ 0x01 Alphanumeric Display
+ 0x20 Display Attributes Report
+ 0x21 ASCII Character Set
+ 0x22 Data Read Back
+ 0x23 Font Read Back
+ 0x24 Display Control Report
+ 0x25 Clear Display
+ 0x26 Display Enable
+ 0x27 Screen Saver Delay
+ 0x28 Screen Saver Enable
+ 0x29 Vertical Scroll
+ 0x2A Horizontal Scroll
+ 0x2B Character Report
+ 0x2C Display Data
+ 0x2D Display Status
+ 0x2E Stat Not Ready
+ 0x2F Stat Ready
+ 0x30 Err Not a loadable character
+ 0x31 Err Font data cannot be read
+ 0x32 Cursor Position Report
+ 0x33 Row
+ 0x34 Column
+ 0x35 Rows
+ 0x36 Columns
+ 0x37 Cursor Pixel Positioning
+ 0x38 Cursor Mode
+ 0x39 Cursor Enable
+ 0x3A Cursor Blink
+ 0x3B Font Report
+ 0x3C Font Data
+ 0x3D Character Width
+ 0x3E Character Height
+ 0x3F Character Spacing Horizontal
+ 0x40 Character Spacing Vertical
+ 0x41 Unicode Character Set
+
+128 Monitor
+ 0x00 Undefined
+ 0x01 Monitor Control
+ 0x02 EDID Information
+ 0x03 VDIF Information
+ 0x04 VESA Version
+ 0x05 On Screen Display
+ 0x06 Auto Size Center
+ 0x07 Polarity Horz Synch
+ 0x08 Polarity Vert Synch
+ 0x09 Sync Type
+ 0x0A Screen Position
+ 0x0B Horizontal Frequency
+ 0x0C Vertical Frequency
+
+129 Monitor Enumerated Values
+ 0x00 unassigned
+ * ENUM %d
+
+130 VESA Virtual Controls
+ 0x10 Brightness
+ 0x12 Contrast
+ 0x16 Video Gain Red
+ 0x18 Video Gain Green
+ 0x1A Video Gain Blue
+ 0x1C Focus
+ 0x20 Horizontal Position
+ 0x22 Horizontal Size
+ 0x24 Horizontal Pincushion
+ 0x26 Horizontal Pincushion Balance
+ 0x28 Horizontal Misconvergence
+ 0x2A Horizontal Linearity
+ 0x2C Horizontal Linearity Balance
+ 0x30 Vertical Position
+ 0x32 Vertical Size
+ 0x34 Vertical Pincushion
+ 0x36 Vertical Pincushion Balance
+ 0x38 Vertical Misconvergence
+ 0x3A Vertical Linearity
+ 0x3C Vertical Linearity Balance
+ 0x40 Parallelogram Distortion
+ 0x42 Trapezoidal Distortion
+ 0x44 Tilt
+ 0x46 Top Corner Distortion Control
+ 0x48 Top Corner Distortion Balance
+ 0x4A Bottom Corner Distortion Control
+ 0x4C Bottom Corner Distortion Balance
+ 0x56 MoirHorizontal
+ 0x58 MoirVertical
+ 0x5E Input Level Select
+ 0x60 Input Source Select
+ 0x62 Stereo Mode
+ 0x6C Video Black Level Red
+ 0x6E Video Black Level Green
+ 0x70 Video Black Level Blue
+
+131 VESA Command
+ 0x00 Undefined
+ 0x01 Settings
+ 0x02 Degauss
+
+132 Power Device
+ 0x00 Undefined
+ 0x01 iName
+ 0x02 PresentStatus
+ 0x03 ChangedStatus
+ 0x04 UPS
+ 0x05 PowerSupply
+ 0x10 BatterySystem
+ 0x11 BatterySystemID
+ 0x12 Battery
+ 0x13 BatteryID
+ 0x14 Charger
+ 0x15 ChargerID
+ 0x16 PowerConverter
+ 0x17 PowerConverterID
+ 0x18 OutletSystem
+ 0x19 OutletSystemID
+ 0x1A Input
+ 0x1B InputID
+ 0x1C Output
+ 0x1D OutputID
+ 0x1E Flow
+ 0x1F FlowID
+ 0x20 Outlet
+ 0x21 OutletID
+ 0x22 Gang
+ 0x23 GangID
+ 0x24 Sink
+ 0x25 SinkID
+ 0x30 Voltage
+ 0x31 Current
+ 0x32 Frequency
+ 0x33 ApparentPower
+ 0x34 ActivePower
+ 0x35 PercentLoad
+ 0x36 Temperature
+ 0x37 Humidity
+ 0x40 ConfigVoltage
+ 0x41 ConfigCurrent
+ 0x42 ConfigFrequency
+ 0x43 ConfigApparentPower
+ 0x44 ConfigActivePower
+ 0x45 ConfigPercentLoad
+ 0x46 ConfigTemperature
+ 0x47 ConfigHumidity
+ 0x50 SwitchOnControl
+ 0x51 SwitchOffControl
+ 0x52 ToggleControl
+ 0x53 LowVoltageTransfer
+ 0x54 HighVoltageTransfer
+ 0x55 DelayBeforeReboot
+ 0x56 DelayBeforeStartup
+ 0x57 DelayBeforeShutdown
+ 0x58 Test
+ 0x59 Vendorspecificcommand
+ 0x60 Present
+ 0x61 Good
+ 0x62 InternalFailure
+ 0x63 VoltageOutOfRange
+ 0x64 FrequencyOutOfRange
+ 0x65 Overload
+ 0x66 OverCharged
+ 0x67 OverTemperature
+ 0x68 ShutdownRequested
+ 0x69 ShutdownImminent
+ 0x6A VendorSpecificAnswerValid
+ 0x6B SwitchOn/Off
+ 0x6C Switcheble
+ 0x6D Used
+ 0x6E Boost
+ 0x6F Buck
+ 0x70 Initialized
+ 0x71 Tested
+
+133 Battery System
+ 0x00 Undefined
+ 0x01 SMBBatteryMode
+ 0x02 SMBBatteryStatus
+ 0x03 SMBAlarmWarning
+ 0x04 SMBChargerMode
+ 0x05 SMBChargerStatus
+ 0x06 SMBChargerSpecInfo
+ 0x07 SMBSelectorState
+ 0x08 SMBSelectorPreset
+ 0x09 SMBSelectorInfo
+ 0x10 OptionalMfgFunction1
+ 0x11 OptionalMfgFunction2
+ 0x12 OptionalMfgFunction3
+ 0x13 OptionalMfgFunction4
+ 0x14 OptionalMfgFunction5
+ 0x15 ConnectionToSMBus
+ 0x16 OutputConnection
+ 0x17 ChargerConnection
+ 0x18 BatteryInsertion
+ 0x19 Usenext
+ 0x1A OKToUse
+ 0x28 ManufacturerAccess
+ 0x29 RemainingCapacityLimit
+ 0x2A RemainingTimeLimit
+ 0x2B AtRate
+ 0x2C CapacityMode
+ 0x2D BroadcastToCharger
+ 0x2E PrimaryBattery
+ 0x2F ChargeController
+ 0x40 TerminateCharge
+ 0x41 TermminateDischarge
+ 0x42 BelowRemainingCapacityLimit
+ 0x43 RemainingTimeLimitExpired
+ 0x44 Charging
+ 0x45 Discharging
+ 0x46 FullyCharged
+ 0x47 FullyDischarged
+ 0x48 ConditionningFlag
+ 0x49 AtRateOK
+ 0x4A SMBErrorCode
+ 0x4B NeedReplacement
+ 0x60 AtRateTimeToFull
+ 0x61 AtRateTimeToEmpty
+ 0x62 AverageCurrent
+ 0x63 Maxerror
+ 0x64 RelativeStateOfCharge
+ 0x65 AbsoluteStateOfCharge
+ 0x66 RemainingCapacity
+ 0x67 FullChargeCapacity
+ 0x68 RunTimeToEmpty
+ 0x69 AverageTimeToEmpty
+ 0x6A AverageTimeToFull
+ 0x6B CycleCount
+ 0x80 BattPackModelLevel
+ 0x81 InternalChargeController
+ 0x82 PrimaryBatterySupport
+ 0x83 DesignCapacity
+ 0x84 SpecificationInfo
+ 0x85 ManufacturerDate
+ 0x86 SerialNumber
+ 0x87 iManufacturerName
+ 0x88 iDevicename
+ 0x89 iDeviceChemistery
+ 0x8A iManufacturerData
+ 0x8B Rechargeable
+ 0x8C WarningCapacityLimit
+ 0x8D CapacityGranularity1
+ 0x8E CapacityGranularity2
+ 0xC0 InhibitCharge
+ 0xC1 EnablePolling
+ 0xC2 ResetToZero
+ 0xD0 ACPresent
+ 0xD1 BatteryPresent
+ 0xD2 PowerFail
+ 0xD3 AlarmInhibited
+ 0xD4 ThermistorUnderRange
+ 0xD5 ThermistorHot
+ 0xD6 ThermistorCold
+ 0xD7 ThermistorOverRange
+ 0xD8 VoltageOutOfRange
+ 0xD9 CurrentOutOfRange
+ 0xDA CurrentNotRegulated
+ 0xDB VoltageNotRegulated
+ 0xDC MasterMode
+ 0xDD ChargerBattery/HostControlled
+ 0xF0 ChargerSpecInfo
+ 0xF1 ChargerSpecRef
+ 0xF2 Level2
+ 0xF3 Level3
+
+140 Bar Code Scanner
+
+141 Scale Device
+
+144 Camera Control
+
+145 Arcade Device
+
+# Some Microsoft non-standard extensions
+0xff00 Microsoft
+ 0xe9 Base Up
+ 0xea Base Down
diff --git a/usb_hid_usages2plist b/usb_hid_usages2plist
new file mode 100755
index 0000000..f50c5b9
--- /dev/null
+++ b/usb_hid_usages2plist
@@ -0,0 +1,46 @@
+#!/usr/bin/env ruby
+
+$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "vendor"))
+$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "lib"))
+
+require 'pp'
+require 'plist'
+
+usb_hid_usages = ARGV[0]
+
+usage_tables = {}
+current_usage = 0;
+current_usage_table = nil
+
+File.open(usb_hid_usages).each_line do |line|
+ next if line =~ /^\s*#/
+ next if line =~ /^\s*$/
+
+ if (line =~ /^(\d+)\s+(.*)\s*$/)
+ current_usage = $1.to_i
+ usage_description = $2
+ current_usage_table = {'usages' => {}, 'ranges' => {}}
+ current_usage_table['description'] = usage_description
+ usage_tables[current_usage] = current_usage_table
+ elsif (line =~ /^\s+(\S+)\s+(.*)\s*$/)
+ usage_page = $1
+ usage_page_description = $2
+
+ if (usage_page =~ /^0x((?:\d|[a-fA-F])+)$/)
+ usage_page = $1.hex
+ current_usage_table['usages'][usage_page] = usage_page_description
+ elsif (usage_page =~ /^0x((?:\d|[a-fA-F])+)-((?:\d|[a-fA-F])+)$/)
+ range_start = $1.hex
+ range_end = $2.hex
+ range = "{#{range_start}, #{range_end}}";
+ current_usage_table['ranges'][range] = usage_page_description
+ elsif (usage_page == '*')
+ current_usage_table['default'] = usage_page_description
+ else
+ puts "Uknown page: #{usage_page}"
+ end
+
+ end
+end
+
+puts Plist.dump(usage_tables) \ No newline at end of file
diff --git a/vendor/NSXReturnThrowError/NSXReturnThrowError.h b/vendor/NSXReturnThrowError/NSXReturnThrowError.h
new file mode 100644
index 0000000..b8aa11a
--- /dev/null
+++ b/vendor/NSXReturnThrowError/NSXReturnThrowError.h
@@ -0,0 +1,103 @@
+/***************************************************************************//**
+ NSXReturnThrowError.h
+ Copyright (c) 2007 Jonathan 'Wolf' Rentzsch: <http://rentzsch.com>
+ Some rights reserved: <http://opensource.org/licenses/mit-license.php>
+
+ @section Overview
+
+ NSXReturnThrowError does two things:
+
+ 1. Eases wrapping error codes into NSError objects.
+
+ 2. Enhances NSError by adding origin information to the error instance.
+ Origin information includes the actual line of code that returned
+ the error, as well as the file+line+function/method name.
+
+ A big NSXReturnThrowError feature is that it deduces the correct NSError
+ error domain based on the wrapped code's return type+value. Bonus: it
+ does so without requiring ObjC++, relying on \@encode acrobatics
+ instead.
+
+ NSXReturnThrowError was coded against 10.4, but should be compatible
+ with 10.3 as well. However that's currently untested.
+
+ @section Usage
+
+ NSXReturnThrowError handles both types of error handling: explicit
+ returning of NSError objects and raising NSExceptions.
+
+ Use NSXReturnError() if you're returning NSError objects explicitly:
+
+ @code
+ - (id)demoReturnError:(NSError**)error_ {
+ id result = nil;
+ NSError *error = nil;
+
+ NSXReturnError(SomeCarbonFunction());
+ if (!error)
+ NSXReturnError(someposixfunction());
+ if (!error)
+ NSXReturnError(some_mach_function());
+ if (!error)
+ NSXReturnError([SomeCocoaClass sharedInstance]);
+
+ if (error_) *error_ = error;
+ return result;
+ }
+ @endcode
+
+ Use NSXThrowError() if you'd prefer to raise NSException objects:
+
+ @code
+ - (id)demo {
+ id result = nil;
+
+ NSXThrowError(SomeCarbonFunction());
+ NSXThrowError(someposixfunction());
+ NSXThrowError(some_mach_function());
+ NSXThrowError([SomeCocoaClass newObject]);
+
+ return result;
+ }
+ @endcode
+
+ The current structure of the raised NSException object is that it's a
+ normal NSException whose name is "NSError". The actual error object is
+ hung off the exception's userInfo dictionary with the key of @"error".
+
+ @mainpage NSXReturnThrowError
+ @todo Add a compile-time flag for whether to stuff __FILE__+friends
+ info into the generated NSError or not.
+
+
+ ***************************************************************************/
+
+#import <Foundation/Foundation.h>
+
+extern NSString *NSXErrorExceptionName;
+extern NSString *NULLPointerErrorDomain;
+extern NSString *BOOLErrorDomain;
+
+void NSXMakeErrorImp(const char *objCType_, intptr_t result_, const char *file_, unsigned line_, const char *function_, const char *code_, NSError **error_);
+
+#define NSXMakeError(ERROR, CODE) \
+ do{ \
+ typeof(CODE) codeResult = (CODE); \
+ NSXMakeErrorImp(@encode(typeof(CODE)), (intptr_t)codeResult, __FILE__, __LINE__, __PRETTY_FUNCTION__, #CODE, &ERROR); \
+ }while(0)
+
+#define NSXReturnError(CODE) NSXMakeError(error, CODE)
+
+#define NSXRaiseError(ERROR) \
+ [[NSException exceptionWithName:NSXErrorExceptionName \
+ reason:[error description] \
+ userInfo:[NSDictionary dictionaryWithObject:error forKey:@"error"]] raise];
+
+#define NSXThrowError(CODE) \
+ do{ \
+ NSError *error = nil; \
+ NSXReturnError(CODE); \
+ if (error) { \
+ NSXRaiseError(ERROR); \
+ } \
+ }while(0)
diff --git a/vendor/NSXReturnThrowError/NSXReturnThrowError.m b/vendor/NSXReturnThrowError/NSXReturnThrowError.m
new file mode 100644
index 0000000..22f31a5
--- /dev/null
+++ b/vendor/NSXReturnThrowError/NSXReturnThrowError.m
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ NSXReturnThrowError.m
+ Copyright (c) 2007 Jonathan 'Wolf' Rentzsch: <http://rentzsch.com>
+ Some rights reserved: <http://opensource.org/licenses/mit-license.php>
+
+ ***************************************************************************/
+
+#import "NSXReturnThrowError.h"
+
+NSString *NSXErrorExceptionName = @"NSXError";
+NSString *NULLPointerErrorDomain = @"NULLPointerErrorDomain";
+NSString *BOOLErrorDomain = @"BOOLErrorDomain";
+
+typedef enum {
+ NSXErrorCodeType_Unknown,
+ NSXErrorCodeType_Cocoa, // "@"
+ NSXErrorCodeType_PosixOrMach, // "i" (-1 == posix+errno, otherwise mach)
+ NSXErrorCodeType_Carbon, // "s" || "l"
+ NSXErrorCodeType_ptr, // "r*" || "*" || "^"
+ NSXErrorCodeType_BOOL // "c"
+} NSXErrorCodeType;
+
+static NSXErrorCodeType NSXErrorCodeTypeFromObjCType(const char *objCType) {
+ switch (objCType[0]) {
+ case 's':
+ case 'l':
+ return NSXErrorCodeType_Carbon;
+ case 'i':
+ return NSXErrorCodeType_PosixOrMach;
+ case '@':
+ return NSXErrorCodeType_Cocoa;
+ case '^':
+ case '*':
+ return NSXErrorCodeType_ptr;
+ case 'r':
+ return '*' == objCType[1] ? NSXErrorCodeType_ptr : NSXErrorCodeType_Unknown;
+ case 'c':
+ return NSXErrorCodeType_BOOL;
+ default:
+ return NSXErrorCodeType_Unknown;
+ }
+}
+
+void NSXMakeErrorImp(const char *objCType_, intptr_t result_, const char *file_, unsigned line_, const char *function_, const char *code_, NSError **error_) {
+ NSString *errorDomain = nil;
+ int errorCode = (int)result_;
+
+ switch (NSXErrorCodeTypeFromObjCType(objCType_)) {
+ case NSXErrorCodeType_Cocoa:
+ // codeResult's type is an id/NSObject* pointer. 0 == nil == failure.
+ if (0 == result_) {
+ errorDomain = @"NSCocoaErrorDomain"; // Could use NSCocoaErrorDomain symbol, but that would force us to 10.4.
+ errorCode = -1;
+ }
+ break;
+ case NSXErrorCodeType_Carbon:
+ // codeResult's type is OSErr (short) or OSStatus (long). 0 == noErr == success.
+ if (0 != result_) {
+ errorDomain = NSOSStatusErrorDomain;
+ }
+ break;
+ case NSXErrorCodeType_PosixOrMach:
+ // codeResult's type is int, which is used for both posix error codes and mach_error_t/kern_return_t.
+ // 0 means success for both, and we can differentiate posix error codes since they're always -1 (the
+ // actual posix code stored in errno).
+ if (0 != result_) {
+ if (-1 == result_) {
+ // Posix error code.
+ errorDomain = NSPOSIXErrorDomain;
+ errorCode = errno;
+ } else {
+ // Mach error code.
+ errorDomain = NSMachErrorDomain;
+ }
+ }
+ break;
+ case NSXErrorCodeType_ptr:
+ // codeResult's type is some sort of non-id/non-NSObject* pointer. 0 == NULL == failure.
+ if (0 == result_) {
+ errorDomain = NULLPointerErrorDomain;
+ errorCode = -1;
+ }
+ break;
+ case NSXErrorCodeType_BOOL:
+ // codeResult's type is a BOOL. 0 == NO == failure.
+ if (0 == result_) {
+ errorDomain = BOOLErrorDomain;
+ errorCode = -1;
+ }
+ break;
+ default:
+ NSCAssert1(NO, @"NSXErrorCodeType_Unknown: \"%s\"", objCType_);
+ break;
+ }
+
+ if (errorDomain) {
+ *error_ = [NSError errorWithDomain:errorDomain
+ code:errorCode
+ userInfo:[NSDictionary dictionaryWithObjectsAndKeys:
+ [NSString stringWithUTF8String:file_], @"reportingFile",
+ [NSNumber numberWithInt:line_], @"reportingLine",
+ [NSString stringWithUTF8String:function_], @"reportingMethod",
+ [NSString stringWithUTF8String:code_], @"origin",
+ nil]];
+ }
+}
diff --git a/versions.xcconfig b/versions.xcconfig
new file mode 100644
index 0000000..b0e1427
--- /dev/null
+++ b/versions.xcconfig
@@ -0,0 +1,2 @@
+CURRENT_MARKETING_VERSION = 1.1
+CURRENT_PROJECT_VERSION = 1010.9.0