mirror of
https://github.com/mauiaaron/apple2.git
synced 2024-07-01 01:29:43 +00:00
Squashed 'Apple2Mac/DDHidLib/' content from commit e6a9848
git-subtree-dir: Apple2Mac/DDHidLib git-subtree-split: e6a9848859fc84e689afb85799658f4980651106
This commit is contained in:
commit
7d64531b89
18
.gitignore
vendored
Normal file
18
.gitignore
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
# Xcode
|
||||
.DS_Store
|
||||
build/
|
||||
*.pbxuser
|
||||
!default.pbxuser
|
||||
*.mode1v3
|
||||
!default.mode1v3
|
||||
*.mode2v3
|
||||
!default.mode2v3
|
||||
*.perspectivev3
|
||||
!default.perspectivev3
|
||||
*.xcworkspace
|
||||
!default.xcworkspace
|
||||
xcuserdata
|
||||
profile
|
||||
*.moved-aside
|
||||
DerivedData
|
||||
.idea/
|
22
DDHidLib-Info.plist
Normal file
22
DDHidLib-Info.plist
Normal file
|
@ -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>
|
1109
DDHidLib.xcodeproj/project.pbxproj
Normal file
1109
DDHidLib.xcodeproj/project.pbxproj
Normal file
File diff suppressed because it is too large
Load Diff
181
LICENSE.html
Normal file
181
LICENSE.html
Normal file
|
@ -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'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'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'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) <year> <copyright holders></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>
|
11
README.md
Normal file
11
README.md
Normal file
|
@ -0,0 +1,11 @@
|
|||
DDHidLib
|
||||
=====
|
||||
###by Dave Dribin
|
||||
|
||||
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.
|
||||
- dropped ppc and added x64 support
|
13
browser/English.lproj/EventWatcher.nib/classes.nib
generated
Normal file
13
browser/English.lproj/EventWatcher.nib/classes.nib
generated
Normal file
|
@ -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;
|
||||
}
|
16
browser/English.lproj/EventWatcher.nib/info.nib
generated
Normal file
16
browser/English.lproj/EventWatcher.nib/info.nib
generated
Normal file
|
@ -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>
|
BIN
browser/English.lproj/EventWatcher.nib/keyedobjects.nib
generated
Normal file
BIN
browser/English.lproj/EventWatcher.nib/keyedobjects.nib
generated
Normal file
Binary file not shown.
BIN
browser/English.lproj/InfoPlist.strings
Normal file
BIN
browser/English.lproj/InfoPlist.strings
Normal file
Binary file not shown.
19
browser/English.lproj/MainMenu.nib/classes.nib
generated
Normal file
19
browser/English.lproj/MainMenu.nib/classes.nib
generated
Normal file
|
@ -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;
|
||||
}
|
22
browser/English.lproj/MainMenu.nib/info.nib
generated
Normal file
22
browser/English.lproj/MainMenu.nib/info.nib
generated
Normal file
|
@ -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>
|
BIN
browser/English.lproj/MainMenu.nib/keyedobjects.nib
generated
Normal file
BIN
browser/English.lproj/MainMenu.nib/keyedobjects.nib
generated
Normal file
Binary file not shown.
7
browser/HIDBrowser_Prefix.pch
Normal file
7
browser/HIDBrowser_Prefix.pch
Normal file
|
@ -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
|
34
browser/HexFormatter.h
Normal file
34
browser/HexFormatter.h
Normal file
|
@ -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
|
49
browser/HexFormatter.m
Normal file
49
browser/HexFormatter.m
Normal file
|
@ -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
|
42
browser/HidBrowserController.h
Normal file
42
browser/HidBrowserController.h
Normal file
|
@ -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
|
144
browser/HidBrowserController.m
Normal file
144
browser/HidBrowserController.m
Normal file
|
@ -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
|
30
browser/Info.plist
Normal file
30
browser/Info.plist
Normal file
|
@ -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>
|
57
browser/WatcherWindowController.h
Normal file
57
browser/WatcherWindowController.h
Normal file
|
@ -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
|
269
browser/WatcherWindowController.m
Normal file
269
browser/WatcherWindowController.m
Normal file
|
@ -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
|
30
browser/main.m
Normal file
30
browser/main.m
Normal file
|
@ -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);
|
||||
}
|
24
changelog.yml
Normal file
24
changelog.yml
Normal file
|
@ -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.
|
62
device_test/AppleMikeyPaneController.h
Normal file
62
device_test/AppleMikeyPaneController.h
Normal file
|
@ -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;
|
||||
NSUInteger mMikeyIndex;
|
||||
NSMutableArray * mEvents;
|
||||
|
||||
// Don't retain these
|
||||
DDHidAppleMikey * mCurrentMikey;
|
||||
}
|
||||
|
||||
- (NSArray *) mikeys;
|
||||
- (void) setMikeys: (NSArray *) theMikeys;
|
||||
|
||||
- (NSUInteger) mikeyIndex;
|
||||
- (void) setMikeyIndex: (NSUInteger) 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
|
160
device_test/AppleMikeyPaneController.m
Normal file
160
device_test/AppleMikeyPaneController.m
Normal file
|
@ -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
|
||||
//===========================================================
|
||||
- (NSUInteger) mikeyIndex
|
||||
{
|
||||
return mMikeyIndex;
|
||||
}
|
||||
|
||||
- (void) setMikeyIndex: (NSUInteger) 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] autorelease];
|
||||
[row setObject: upOrDown ? @"Down" : @"Up" forKey: @"event"];
|
||||
[row setObject:usage forKey: @"description"];
|
||||
[mMikeysEventsController addObject: row];
|
||||
}
|
||||
|
||||
@end
|
BIN
device_test/AppleRemote.tiff
Normal file
BIN
device_test/AppleRemote.tiff
Normal file
Binary file not shown.
51
device_test/AppleRemotePaneController.h
Normal file
51
device_test/AppleRemotePaneController.h
Normal file
|
@ -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
|
145
device_test/AppleRemotePaneController.m
Normal file
145
device_test/AppleRemotePaneController.m
Normal file
|
@ -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
|
35
device_test/BoolFormatter.h
Normal file
35
device_test/BoolFormatter.h
Normal file
|
@ -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
|
82
device_test/BoolFormatter.m
Normal file
82
device_test/BoolFormatter.m
Normal file
|
@ -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
|
39
device_test/ButtonState.h
Normal file
39
device_test/ButtonState.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
- (id) initWithName: (NSString *) name;
|
||||
- (NSString *) name;
|
||||
|
||||
- (BOOL) pressed;
|
||||
- (void) setPressed: (BOOL) flag;
|
||||
|
||||
@end
|
77
device_test/ButtonState.m
Normal file
77
device_test/ButtonState.m
Normal file
|
@ -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
|
||||
|
35
device_test/DeviceTestController.h
Normal file
35
device_test/DeviceTestController.h
Normal file
|
@ -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
|
49
device_test/DeviceTestController.m
Normal file
49
device_test/DeviceTestController.m
Normal file
|
@ -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
|
BIN
device_test/English.lproj/InfoPlist.strings
Normal file
BIN
device_test/English.lproj/InfoPlist.strings
Normal file
Binary file not shown.
5311
device_test/English.lproj/MainMenu.nib/designable.nib
generated
Normal file
5311
device_test/English.lproj/MainMenu.nib/designable.nib
generated
Normal file
File diff suppressed because it is too large
Load Diff
BIN
device_test/English.lproj/MainMenu.nib/keyedobjects.nib
generated
Normal file
BIN
device_test/English.lproj/MainMenu.nib/keyedobjects.nib
generated
Normal file
Binary file not shown.
26
device_test/Info.plist
Normal file
26
device_test/Info.plist
Normal file
|
@ -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>
|
72
device_test/JoystickPaneController.h
Normal file
72
device_test/JoystickPaneController.h
Normal file
|
@ -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;
|
||||
NSUInteger mJoystickIndex;
|
||||
|
||||
// Don't retain these
|
||||
DDHidJoystick * mCurrentJoystick;
|
||||
}
|
||||
|
||||
- (NSArray *) joysticks;
|
||||
|
||||
- (NSArray *) joystickButtons;
|
||||
|
||||
- (NSUInteger) joystickIndex;
|
||||
- (void) setJoystickIndex: (NSUInteger) 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
|
174
device_test/JoystickPaneController.m
Normal file
174
device_test/JoystickPaneController.m
Normal file
|
@ -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
|
||||
//===========================================================
|
||||
- (NSUInteger) joystickIndex
|
||||
{
|
||||
return mJoystickIndex;
|
||||
}
|
||||
|
||||
- (void) setJoystickIndex: (NSUInteger) 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
|
64
device_test/KeyboardPaneController.h
Normal file
64
device_test/KeyboardPaneController.h
Normal file
|
@ -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;
|
||||
NSUInteger mKeyboardIndex;
|
||||
NSMutableArray * mEvents;
|
||||
|
||||
// Don't retain these
|
||||
DDHidKeyboard * mCurrentKeyboard;
|
||||
}
|
||||
|
||||
- (NSArray *) keyboards;
|
||||
- (void) setKeyboards: (NSArray *) theKeyboards;
|
||||
|
||||
- (NSUInteger) keyboardIndex;
|
||||
- (void) setKeyboardIndex: (NSUInteger) 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
|
179
device_test/KeyboardPaneController.m
Normal file
179
device_test/KeyboardPaneController.m
Normal file
|
@ -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
|
||||
//===========================================================
|
||||
- (NSUInteger) keyboardIndex
|
||||
{
|
||||
return mKeyboardIndex;
|
||||
}
|
||||
|
||||
- (void) setKeyboardIndex: (NSUInteger) 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] autorelease];
|
||||
[row setObject: event forKey: @"event"];
|
||||
[row setObject: description forKey: @"description"];
|
||||
[mKeyboardEventsController addObject: row];
|
||||
}
|
||||
|
||||
@end
|
||||
|
68
device_test/MousePaneController.h
Normal file
68
device_test/MousePaneController.h
Normal file
|
@ -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;
|
||||
|
||||
NSUInteger mMouseIndex;
|
||||
int mMouseX;
|
||||
int mMouseY;
|
||||
int mMouseWheel;
|
||||
NSMutableArray * mMouseButtons;
|
||||
}
|
||||
|
||||
- (BOOL) no;
|
||||
|
||||
- (NSArray *) mice;
|
||||
- (void) setMice: (NSArray *) newMice;
|
||||
|
||||
- (NSArray *) mouseButtons;
|
||||
|
||||
- (NSUInteger) mouseIndex;
|
||||
- (void) setMouseIndex: (NSUInteger) 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
|
211
device_test/MousePaneController.m
Normal file
211
device_test/MousePaneController.m
Normal file
|
@ -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
|
||||
//===========================================================
|
||||
- (NSUInteger) mouseIndex
|
||||
{
|
||||
return mMouseIndex;
|
||||
}
|
||||
|
||||
//===========================================================
|
||||
// - setMouseIndex:
|
||||
//===========================================================
|
||||
- (void) setMouseIndex: (NSUInteger) 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
|
||||
|
42
device_test/RemoteFeedbackView.h
Normal file
42
device_test/RemoteFeedbackView.h
Normal file
|
@ -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
|
162
device_test/RemoteFeedbackView.m
Normal file
162
device_test/RemoteFeedbackView.m
Normal file
|
@ -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 = NSZeroPoint;
|
||||
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
|
30
device_test/main.m
Normal file
30
device_test/main.m
Normal file
|
@ -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);
|
||||
}
|
23
header.c
Normal file
23
header.c
Normal file
|
@ -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.
|
||||
*/
|
66
lib/DDHidAppleMikey.h
Normal file
66
lib/DDHidAppleMikey.h
Normal file
|
@ -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
|
164
lib/DDHidAppleMikey.m
Normal file
164
lib/DDHidAppleMikey.m
Normal file
|
@ -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>
|
||||
|
||||
#define APPLE_MIC_ONLY 1
|
||||
|
||||
@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 mikeys
|
||||
id a2 = [self allDevicesMatchingUsagePage:12 usageId:1 withClass:self skipZeroLocations:NO];
|
||||
#if APPLE_MIC_ONLY
|
||||
a2 = [a2 filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"productName == \"Apple Mikey HID Driver\""]];
|
||||
#endif
|
||||
|
||||
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
|
84
lib/DDHidAppleRemote.h
Normal file
84
lib/DDHidAppleRemote.h
Normal file
|
@ -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
|
236
lib/DDHidAppleRemote.m
Normal file
236
lib/DDHidAppleRemote.m
Normal file
|
@ -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
|
||||
|
131
lib/DDHidDevice.h
Normal file
131
lib/DDHidDevice.h
Normal file
|
@ -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
|
595
lib/DDHidDevice.m
Normal file
595
lib/DDHidDevice.m
Normal file
|
@ -0,0 +1,595 @@
|
|||
/*
|
||||
* 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);
|
||||
id retVal = nil;
|
||||
if(hidMatchDictionary) {
|
||||
retVal = [self allDevicesMatchingCFDictionary: hidMatchDictionary
|
||||
withClass: [DDHidDevice class]
|
||||
skipZeroLocations: NO];
|
||||
//CFRelease(hidMatchDictionary);//dont free, it is freed by IOServiceGetMatchingServices
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
+ (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);
|
||||
id retVal = nil;
|
||||
if(hidMatchDictionary) {
|
||||
NSMutableDictionary * objcMatchDictionary =
|
||||
(NSMutableDictionary *) hidMatchDictionary;
|
||||
[objcMatchDictionary ddhid_setObject: [NSNumber numberWithUnsignedInt: usagePage]
|
||||
forString: kIOHIDDeviceUsagePageKey];
|
||||
[objcMatchDictionary ddhid_setObject: [NSNumber numberWithUnsignedInt: usageId]
|
||||
forString: kIOHIDDeviceUsageKey];
|
||||
retVal = [self allDevicesMatchingCFDictionary: hidMatchDictionary
|
||||
withClass: hidClass
|
||||
skipZeroLocations: skipZeroLocations];
|
||||
//CFRelease(hidMatchDictionary);//dont free, it is freed by IOServiceGetMatchingServices
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
+ (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
|
||||
|
65
lib/DDHidElement.h
Normal file
65
lib/DDHidElement.h
Normal file
|
@ -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
|
185
lib/DDHidElement.m
Normal file
185
lib/DDHidElement.m
Normal file
|
@ -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
|
45
lib/DDHidEvent.h
Normal file
45
lib/DDHidEvent.h
Normal file
|
@ -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
|
81
lib/DDHidEvent.m
Normal file
81
lib/DDHidEvent.m
Normal file
|
@ -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
|
132
lib/DDHidJoystick.h
Normal file
132
lib/DDHidJoystick.h
Normal file
|
@ -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
|
654
lib/DDHidJoystick.m
Normal file
654
lib/DDHidJoystick.m
Normal file
|
@ -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], (int)[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
|
68
lib/DDHidKeyboard.h
Normal file
68
lib/DDHidKeyboard.h
Normal file
|
@ -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
|
173
lib/DDHidKeyboard.m
Normal file
173
lib/DDHidKeyboard.m
Normal file
|
@ -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
|
74
lib/DDHidKeyboardBarcodeScanner.h
Normal file
74
lib/DDHidKeyboardBarcodeScanner.h
Normal file
|
@ -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;
|
||||
|
||||
- (NSUInteger) 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
|
222
lib/DDHidKeyboardBarcodeScanner.m
Normal file
222
lib/DDHidKeyboardBarcodeScanner.m
Normal file
|
@ -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;
|
||||
}
|
||||
|
||||
- (NSUInteger) 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
|
36
lib/DDHidLib.h
Normal file
36
lib/DDHidLib.h
Normal file
|
@ -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"
|
78
lib/DDHidMouse.h
Normal file
78
lib/DDHidMouse.h
Normal file
|
@ -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
|
||||
|
279
lib/DDHidMouse.m
Normal file
279
lib/DDHidMouse.m
Normal file
|
@ -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], (int)[event value]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
70
lib/DDHidQueue.h
Normal file
70
lib/DDHidQueue.h
Normal file
|
@ -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
|
174
lib/DDHidQueue.m
Normal file
174
lib/DDHidQueue.m
Normal file
|
@ -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 "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];
|
||||
CFRelease(mEventSource);
|
||||
|
||||
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];
|
||||
|
||||
}
|
2327
lib/DDHidStandardUsages.plist
Normal file
2327
lib/DDHidStandardUsages.plist
Normal file
File diff suppressed because it is too large
Load Diff
52
lib/DDHidUsage.h
Normal file
52
lib/DDHidUsage.h
Normal file
|
@ -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
|
84
lib/DDHidUsage.m
Normal file
84
lib/DDHidUsage.m
Normal file
|
@ -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
|
40
lib/DDHidUsageTables.h
Normal file
40
lib/DDHidUsageTables.h
Normal file
|
@ -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
|
85
lib/DDHidUsageTables.m
Normal file
85
lib/DDHidUsageTables.m
Normal file
|
@ -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
|
46
lib/NSDictionary+DDHidExtras.h
Normal file
46
lib/NSDictionary+DDHidExtras.h
Normal file
|
@ -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
|
81
lib/NSDictionary+DDHidExtras.m
Normal file
81
lib/NSDictionary+DDHidExtras.m
Normal file
|
@ -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
|
1086
usb_hid_usages.txt
Normal file
1086
usb_hid_usages.txt
Normal file
File diff suppressed because it is too large
Load Diff
46
usb_hid_usages2plist
Executable file
46
usb_hid_usages2plist
Executable file
|
@ -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)
|
103
vendor/NSXReturnThrowError/NSXReturnThrowError.h
vendored
Normal file
103
vendor/NSXReturnThrowError/NSXReturnThrowError.h
vendored
Normal file
|
@ -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)
|
106
vendor/NSXReturnThrowError/NSXReturnThrowError.m
vendored
Normal file
106
vendor/NSXReturnThrowError/NSXReturnThrowError.m
vendored
Normal file
|
@ -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_) {
|
||||
*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]];
|
||||
}
|
||||
}
|
2
versions.xcconfig
Normal file
2
versions.xcconfig
Normal file
|
@ -0,0 +1,2 @@
|
|||
CURRENT_MARKETING_VERSION = 1.1.1
|
||||
CURRENT_PROJECT_VERSION = 1010.9.0
|
Loading…
Reference in New Issue
Block a user