Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / lang / LangPrimSource / HID_Utilities / HID_Name_Lookup.c
blobe01942a86716d4eff21bbec6d520ca66ece74171
1 //
2 // File: HID_Name_Lookup.c
3 //
4 // Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. ("Apple")
5 // in consideration of your agreement to the following terms, and your use,
6 // installation, modification or redistribution of this Apple software
7 // constitutes acceptance of these terms. If you do not agree with these
8 // terms, please do not use, install, modify or redistribute this Apple
9 // software.
11 // In consideration of your agreement to abide by the following terms, and
12 // subject to these terms, Apple grants you a personal, non - exclusive
13 // license, under Apple's copyrights in this original Apple software ( the
14 // "Apple Software" ), to use, reproduce, modify and redistribute the Apple
15 // Software, with or without modifications, in source and / or binary forms;
16 // provided that if you redistribute the Apple Software in its entirety and
17 // without modifications, you must retain this notice and the following text
18 // and disclaimers in all such redistributions of the Apple Software. Neither
19 // the name, trademarks, service marks or logos of Apple Inc. may be used to
20 // endorse or promote products derived from the Apple Software without specific
21 // prior written permission from Apple. Except as expressly stated in this
22 // notice, no other rights or licenses, express or implied, are granted by
23 // Apple herein, including but not limited to any patent rights that may be
24 // infringed by your derivative works or by other works in which the Apple
25 // Software may be incorporated.
27 // The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
28 // WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
29 // WARRANTIES OF NON - INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
30 // PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION
31 // ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
33 // IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
34 // CONSEQUENTIAL DAMAGES ( INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
36 // INTERRUPTION ) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION
37 // AND / OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER
38 // UNDER THEORY OF CONTRACT, TORT ( INCLUDING NEGLIGENCE ), STRICT LIABILITY OR
39 // OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 // Copyright © 2002-2009 Apple Inc. All Rights Reserved.
43 //*****************************************************
44 #pragma mark - includes & imports
45 //*****************************************************
46 #include "HID_Utilities_External.h"
47 //*****************************************************
48 #pragma mark - typedefs, enums, defines, etc.
49 //*****************************************************
50 #define FAKE_MISSING_NAMES 0 // for debugging; returns the vendor, product & cookie ( or usage info ) as numbers.
51 #define VERBOSE_ELEMENT_NAMES 0 // set TRUE to include vender & product names in element names ( useful for debugging )
53 #define kNameKeyCFStringRef CFSTR( "Name" )
54 //*****************************************************
55 #pragma mark - local ( static ) function prototypes
56 //*****************************************************
58 #if 0 // currently unused
59 static SInt32 hu_SaveToXMLFile( CFPropertyListRef inCFPRef, CFURLRef inCFURLRef );
60 static SInt32 hu_XMLSave( CFPropertyListRef inCFPropertyListRef, CFStringRef inResourceName, CFStringRef inResourceExtension );
61 #endif
62 static CFPropertyListRef hu_LoadFromXMLFile( CFURLRef inCFURLRef );
63 static CFPropertyListRef hu_XMLLoad( CFStringRef inResourceName, CFStringRef inResourceExtension );
65 static Boolean hu_XMLSearchForElementNameByCookie( long inVendorID, long inProductID, IOHIDElementCookie inCookie, char * outCStr );
66 static Boolean hu_XMLSearchForElementNameByUsage( long inVendorID, long inProductID, long inUsagePage, long inUsage, char * outCStr );
68 static Boolean hu_XMLSearchForVendorNameByVendorID( long inVendorID, char * outCStr );
69 static Boolean hu_XMLSearchForProductNameByVendorProductID( long inVendorID, long inProductID, char * outCStr );
71 #if 0 // currently unused
72 static Boolean hu_AddVendorProductToCFDict( CFMutableDictionaryRef inCFMutableDictionaryRef, long inVendorID, CFStringRef inVendorCFStringRef, long inProductID, CFStringRef inProductCFStringRef );
73 static Boolean hu_AddDeviceElementToUsageXML( IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHIDElementRef );
74 #endif
75 //*****************************************************
76 #pragma mark - exported globals
77 //*****************************************************
78 #pragma mark - local ( static ) globals
79 //*****************************************************
80 static CFPropertyListRef gCookieCFPropertyListRef = NULL;
81 static CFPropertyListRef gUsageCFPropertyListRef = NULL;
83 //*****************************************************
84 #pragma mark - exported function implementations
85 //*****************************************************
87 /*************************************************************************
89 * HIDGetVendorNameFromVendorID( inVendorID, inProductID, inCookie, outCStrName )
91 * Purpose: Uses an devices vendor ID to generate a name for it.
93 * Notes: Now uses XML files to store dictionary of names
95 * Inputs: inVendorID - the elements vendor ID
96 * outCStrName - address where result will be returned
97 * Returns: Boolean - if successful
99 Boolean HIDGetVendorNameFromVendorID( long inVendorID, char * outCStrName )
101 Boolean result = FALSE;
102 * outCStrName = 0; // clear name
104 if ( hu_XMLSearchForVendorNameByVendorID( inVendorID, outCStrName ) )
105 return TRUE;
107 #if FAKE_MISSING_NAMES
108 sprintf( outCStrName, "#{ V: %ld}#", inVendorID );
109 result = TRUE;
110 #endif FAKE_MISSING_NAMES
111 return result;
112 } // HIDGetVendorNameFromVendorID
114 /*************************************************************************
116 * HIDGetProductNameFromVendorProductID( inVendorID, inProductID, outCStrName )
118 * Purpose: Uses an elements vendor, product & usage info to generate a name for it.
120 * Notes: Now uses XML files to store dictionary of names
122 * Inputs: inVendorID - the elements vendor ID
123 * inProductID - the elements product ID
124 * inUsagePage - the elements usage page
125 * inUsage - the elements usage
126 * outCStrName - address where result will be returned
127 * Returns: Boolean - if successful
129 Boolean HIDGetProductNameFromVendorProductID( long inVendorID, long inProductID, char * outCStrName )
131 Boolean result = FALSE;
132 * outCStrName = 0; // clear name
134 if ( hu_XMLSearchForProductNameByVendorProductID( inVendorID, inProductID, outCStrName ) )
135 return TRUE;
137 #if FAKE_MISSING_NAMES
138 sprintf( outCStrName, "#{ V: %ld, P: %ld, U: %ld: %ld}#", inVendorID, inProductID, inUsagePage, inUsage );
139 result = TRUE;
140 #endif FAKE_MISSING_NAMES
141 return result;
142 } // HIDGetProductNameFromVendorProductID
144 /*************************************************************************
146 * HIDGetElementNameFromVendorProductCookie( inVendorID, inProductID, inCookie, outCStrName )
148 * Purpose: Uses an elements vendor, product & cookie to generate a name for it.
150 * Notes: Now uses XML files to store dictionary of names
152 * Inputs: inVendorID - the elements vendor ID
153 * inProductID - the elements product ID
154 * inCookie - the elements cookie
155 * outCStrName - address where result will be returned
156 * Returns: Boolean - if successful
158 Boolean HIDGetElementNameFromVendorProductCookie (int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName)
160 Boolean result = FALSE;
161 *outCStrName = 0; // clear name
163 // Look in the XML file first
164 if ( hu_XMLSearchForElementNameByCookie( inVendorID, inProductID, inCookie, outCStrName ) )
165 return TRUE;
167 #if FAKE_MISSING_NAMES
168 sprintf( outCStrName, "#{ V: %ld, P: %ld, C: %ld}#", inVendorID, inProductID, inCookie );
169 #else
170 result = FALSE;
171 #endif FAKE_MISSING_NAMES
172 return result;
173 } // HIDGetElementNameFromVendorProductCookie
175 /*************************************************************************
177 * HIDGetElementNameFromVendorProductUsage( inVendorID, inProductID, inUsagePage, inUsage, outCStrName )
179 * Purpose: Uses an elements vendor, product & usage info to generate a name for it.
181 * Notes: Now uses XML files to store dictionary of names
183 * Inputs: inVendorID - the elements vendor ID
184 * inProductID - the elements product ID
185 * inUsagePage - the elements usage page
186 * inUsage - the elements usage
187 * outCStrName - address where result will be returned
188 * Returns: Boolean - if successful
190 Boolean HIDGetElementNameFromVendorProductUsage( long inVendorID, long inProductID, long inUsagePage, long inUsage, char * outCStrName )
192 Boolean result = FALSE;
193 * outCStrName = 0; // clear name
195 if ( hu_XMLSearchForElementNameByUsage( inVendorID, inProductID, inUsagePage, inUsage, outCStrName ) )
196 return TRUE;
198 #if FAKE_MISSING_NAMES
199 sprintf( outCStrName, "#{ V: %ld, P: %ld, U: %ld: %ld}#", inVendorID, inProductID, inUsagePage, inUsage );
200 result = TRUE;
201 #endif FAKE_MISSING_NAMES
202 return result;
203 } // HIDGetElementNameFromVendorProductUsage
205 #if 0 // currently unused
206 /*************************************************************************
208 * HIDAddDeviceToXML( inDevice )
210 * Purpose: Adds a devices info to the HID_device_usage_strings.plist( XML ) file
212 * Inputs: inDevice - the device
213 * Returns: Boolean - if successful
215 static Boolean HIDAddDeviceToXML( IOHIDDeviceRef inIOHIDDeviceRef )
217 Boolean result = FALSE;
219 if ( HIDIsValidDevice( inIOHIDDeviceRef ) ) {
220 CFStringRef vendorCFStringRef = IOHIDDevice_GetManufacturer( inIOHIDDeviceRef );
221 CFStringRef productCFStringRef = IOHIDDevice_GetProduct( inIOHIDDeviceRef );
222 if ( vendorCFStringRef && productCFStringRef ) {
224 #if 0 // don't update the cookie xml file
225 gCookieCFPropertyListRef = hu_XMLLoad( CFSTR( "HID_cookie_strings" ), CFSTR( "plist" ) );
226 if ( gCookieCFPropertyListRef ) {
227 CFMutableDictionaryRef tCFMutableDictionaryRef = CFDictionaryCreateMutableCopy( kCFAllocatorDefault, 0, gCookieCFPropertyListRef );
228 if ( tCFMutableDictionaryRef ) {
229 if ( hu_AddVendorProductToCFDict( tCFMutableDictionaryRef, vendorID, vendorCFStringRef, productID, productCFStringRef ) ) {
230 hu_XMLSave( tCFMutableDictionaryRef, CFSTR( "HID_cookie_strings" ), CFSTR( "plist" ) );
231 result = TRUE;
233 CFRelease( tCFMutableDictionaryRef );
236 #endif
237 if ( gUsageCFPropertyListRef )
238 CFRelease( gUsageCFPropertyListRef );
240 gUsageCFPropertyListRef = hu_XMLLoad( CFSTR( "HID_device_usage_strings" ), CFSTR( "plist" ) );
241 if ( gUsageCFPropertyListRef ) {
242 CFMutableDictionaryRef tCFMutableDictionaryRef = CFDictionaryCreateMutableCopy( kCFAllocatorDefault, 0, gUsageCFPropertyListRef );
243 if ( tCFMutableDictionaryRef ) {
244 long vendorID = IOHIDDevice_GetVendorID( inIOHIDDeviceRef );
245 long productID = IOHIDDevice_GetProductID( inIOHIDDeviceRef );
246 if ( hu_AddVendorProductToCFDict( tCFMutableDictionaryRef, vendorID, vendorCFStringRef, productID, productCFStringRef ) ) {
247 hu_XMLSave( tCFMutableDictionaryRef, CFSTR( "HID_device_usage_strings" ), CFSTR( "plist" ) );
248 result = TRUE;
250 CFRelease( tCFMutableDictionaryRef );
255 return result;
256 } // HIDAddDeviceToXML
258 /*************************************************************************
260 * HIDAddDeviceElementToXML( inDevice, inElement )
262 * Purpose: Adds a devices info to the HID_device_usage_strings.plist( XML ) file
264 * Inputs: inDevice - the device
265 * inElement - the element
267 * Returns: Boolean - if successful
269 Boolean HIDAddDeviceElementToXML( IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHIDElementRef )
271 Boolean result = FALSE;
273 if ( HIDIsValidElement( inIOHIDElementRef ) ) {
274 if ( HIDAddDeviceToXML( inIOHIDDeviceRef ) )
275 result = TRUE;
277 if ( hu_AddDeviceElementToUsageXML( inIOHIDDeviceRef, inIOHIDElementRef ) ) {
278 result = TRUE;
281 return result;
282 } // HIDAddDeviceElementToXML
283 #endif
284 /*************************************************************************
286 * HIDGetTypeName( inIOHIDElementType, outCStrName )
288 * Purpose: return a C string for a given element type( see IOHIDKeys.h )
289 * Notes: returns "Unknown Type" for invalid types
291 * Inputs: inIOHIDElementType - type element type
292 * outCStrName - address where to store element type string
294 * Returns: outCStrName - the element type string
297 void HIDGetTypeName( IOHIDElementType inIOHIDElementType, char * outCStrName )
299 switch( inIOHIDElementType ) {
300 case kIOHIDElementTypeInput_Misc: {
301 sprintf( outCStrName, "Miscellaneous Input" );
302 break;
304 case kIOHIDElementTypeInput_Button: {
305 sprintf( outCStrName, "Button Input" );
306 break;
308 case kIOHIDElementTypeInput_Axis: {
309 sprintf( outCStrName, "Axis Input" );
310 break;
312 case kIOHIDElementTypeInput_ScanCodes: {
313 sprintf( outCStrName, "Scan Code Input" );
314 break;
316 case kIOHIDElementTypeOutput: {
317 sprintf( outCStrName, "Output" );
318 break;
320 case kIOHIDElementTypeFeature: {
321 sprintf( outCStrName, "Feature" );
322 break;
324 case kIOHIDElementTypeCollection: {
325 sprintf( outCStrName, "Collection" );
326 break;
328 default: {
329 sprintf( outCStrName, "Unknown Type" );
330 break;
333 } // HIDGetTypeName
336 void HIDGetUsageName (const long valueUsagePage, const long valueUsage, char * cstrName)
338 switch (valueUsagePage)
340 case kHIDPage_Undefined:
341 switch (valueUsage)
343 default: sprintf (cstrName, "Undefined Page, Usage 0x%lx", valueUsage); break;
345 break;
346 case kHIDPage_GenericDesktop:
347 switch (valueUsage)
349 case kHIDUsage_GD_Pointer: sprintf (cstrName, "Pointer"); break;
350 case kHIDUsage_GD_Mouse: sprintf (cstrName, "Mouse"); break;
351 case kHIDUsage_GD_Joystick: sprintf (cstrName, "Joystick"); break;
352 case kHIDUsage_GD_GamePad: sprintf (cstrName, "GamePad"); break;
353 case kHIDUsage_GD_Keyboard: sprintf (cstrName, "Keyboard"); break;
354 case kHIDUsage_GD_Keypad: sprintf (cstrName, "Keypad"); break;
355 case kHIDUsage_GD_MultiAxisController: sprintf (cstrName, "Multi-Axis Controller"); break;
357 case kHIDUsage_GD_X: sprintf (cstrName, "X-Axis"); break;
358 case kHIDUsage_GD_Y: sprintf (cstrName, "Y-Axis"); break;
359 case kHIDUsage_GD_Z: sprintf (cstrName, "Z-Axis"); break;
360 case kHIDUsage_GD_Rx: sprintf (cstrName, "X-Rotation"); break;
361 case kHIDUsage_GD_Ry: sprintf (cstrName, "Y-Rotation"); break;
362 case kHIDUsage_GD_Rz: sprintf (cstrName, "Z-Rotation"); break;
363 case kHIDUsage_GD_Slider: sprintf (cstrName, "Slider"); break;
364 case kHIDUsage_GD_Dial: sprintf (cstrName, "Dial"); break;
365 case kHIDUsage_GD_Wheel: sprintf (cstrName, "Wheel"); break;
366 case kHIDUsage_GD_Hatswitch: sprintf (cstrName, "Hatswitch"); break;
367 case kHIDUsage_GD_CountedBuffer: sprintf (cstrName, "Counted Buffer"); break;
368 case kHIDUsage_GD_ByteCount: sprintf (cstrName, "Byte Count"); break;
369 case kHIDUsage_GD_MotionWakeup: sprintf (cstrName, "Motion Wakeup"); break;
370 case kHIDUsage_GD_Start: sprintf (cstrName, "Start"); break;
371 case kHIDUsage_GD_Select: sprintf (cstrName, "Select"); break;
373 case kHIDUsage_GD_Vx: sprintf (cstrName, "X-Velocity"); break;
374 case kHIDUsage_GD_Vy: sprintf (cstrName, "Y-Velocity"); break;
375 case kHIDUsage_GD_Vz: sprintf (cstrName, "Z-Velocity"); break;
376 case kHIDUsage_GD_Vbrx: sprintf (cstrName, "X-Rotation Velocity"); break;
377 case kHIDUsage_GD_Vbry: sprintf (cstrName, "Y-Rotation Velocity"); break;
378 case kHIDUsage_GD_Vbrz: sprintf (cstrName, "Z-Rotation Velocity"); break;
379 case kHIDUsage_GD_Vno: sprintf (cstrName, "Vno"); break;
381 case kHIDUsage_GD_SystemControl: sprintf (cstrName, "System Control"); break;
382 case kHIDUsage_GD_SystemPowerDown: sprintf (cstrName, "System Power Down"); break;
383 case kHIDUsage_GD_SystemSleep: sprintf (cstrName, "System Sleep"); break;
384 case kHIDUsage_GD_SystemWakeUp: sprintf (cstrName, "System Wake Up"); break;
385 case kHIDUsage_GD_SystemContextMenu: sprintf (cstrName, "System Context Menu"); break;
386 case kHIDUsage_GD_SystemMainMenu: sprintf (cstrName, "System Main Menu"); break;
387 case kHIDUsage_GD_SystemAppMenu: sprintf (cstrName, "System App Menu"); break;
388 case kHIDUsage_GD_SystemMenuHelp: sprintf (cstrName, "System Menu Help"); break;
389 case kHIDUsage_GD_SystemMenuExit: sprintf (cstrName, "System Menu Exit"); break;
390 case kHIDUsage_GD_SystemMenu: sprintf (cstrName, "System Menu"); break;
391 case kHIDUsage_GD_SystemMenuRight: sprintf (cstrName, "System Menu Right"); break;
392 case kHIDUsage_GD_SystemMenuLeft: sprintf (cstrName, "System Menu Left"); break;
393 case kHIDUsage_GD_SystemMenuUp: sprintf (cstrName, "System Menu Up"); break;
394 case kHIDUsage_GD_SystemMenuDown: sprintf (cstrName, "System Menu Down"); break;
396 case kHIDUsage_GD_DPadUp: sprintf (cstrName, "DPad Up"); break;
397 case kHIDUsage_GD_DPadDown: sprintf (cstrName, "DPad Down"); break;
398 case kHIDUsage_GD_DPadRight: sprintf (cstrName, "DPad Right"); break;
399 case kHIDUsage_GD_DPadLeft: sprintf (cstrName, "DPad Left"); break;
401 case kHIDUsage_GD_Reserved: sprintf (cstrName, "Reserved"); break;
403 default: sprintf (cstrName, "Generic Desktop Usage 0x%lx", valueUsage); break;
405 break;
406 case kHIDPage_Simulation:
407 switch (valueUsage)
409 default: sprintf (cstrName, "Simulation Usage 0x%lx", valueUsage); break;
411 break;
412 case kHIDPage_VR:
413 switch (valueUsage)
415 default: sprintf (cstrName, "VR Usage 0x%lx", valueUsage); break;
417 break;
418 case kHIDPage_Sport:
419 switch (valueUsage)
421 default: sprintf (cstrName, "Sport Usage 0x%lx", valueUsage); break;
423 break;
424 case kHIDPage_Game:
425 switch (valueUsage)
427 default: sprintf (cstrName, "Game Usage 0x%lx", valueUsage); break;
429 break;
430 case kHIDPage_KeyboardOrKeypad:
431 switch (valueUsage)
433 default: sprintf (cstrName, "Keyboard Usage 0x%lx", valueUsage); break;
435 break;
436 case kHIDPage_LEDs:
437 switch (valueUsage)
439 // some LED usages
440 case kHIDUsage_LED_IndicatorRed: sprintf (cstrName, "Red LED"); break;
441 case kHIDUsage_LED_IndicatorGreen: sprintf (cstrName, "Green LED"); break;
442 case kHIDUsage_LED_IndicatorAmber: sprintf (cstrName, "Amber LED"); break;
443 case kHIDUsage_LED_GenericIndicator: sprintf (cstrName, "Generic LED"); break;
444 case kHIDUsage_LED_SystemSuspend: sprintf (cstrName, "System Suspend LED"); break;
445 case kHIDUsage_LED_ExternalPowerConnected: sprintf (cstrName, "External Power LED"); break;
446 default: sprintf (cstrName, "LED Usage 0x%lx", valueUsage); break;
448 break;
449 case kHIDPage_Button:
450 switch (valueUsage)
452 default: sprintf (cstrName, "Button #%ld", valueUsage); break;
454 break;
455 case kHIDPage_Ordinal:
456 switch (valueUsage)
458 default: sprintf (cstrName, "Ordinal Instance %lx", valueUsage); break;
460 break;
461 case kHIDPage_Telephony:
462 switch (valueUsage)
464 default: sprintf (cstrName, "Telephony Usage 0x%lx", valueUsage); break;
466 break;
467 case kHIDPage_Consumer:
468 switch (valueUsage)
470 default: sprintf (cstrName, "Consumer Usage 0x%lx", valueUsage); break;
472 break;
473 case kHIDPage_Digitizer:
474 switch (valueUsage)
476 default: sprintf (cstrName, "Digitizer Usage 0x%lx", valueUsage); break;
478 break;
479 case kHIDPage_PID:
480 if (((valueUsage >= 0x02) && (valueUsage <= 0x1F)) || ((valueUsage >= 0x29) && (valueUsage <= 0x2F)) ||
481 ((valueUsage >= 0x35) && (valueUsage <= 0x3F)) || ((valueUsage >= 0x44) && (valueUsage <= 0x4F)) ||
482 (valueUsage == 0x8A) || (valueUsage == 0x93) || ((valueUsage >= 0x9D) && (valueUsage <= 0x9E)) ||
483 ((valueUsage >= 0xA1) && (valueUsage <= 0xA3)) || ((valueUsage >= 0xAD) && (valueUsage <= 0xFFFF)))
484 sprintf (cstrName, "PID Reserved");
485 else
486 switch (valueUsage)
488 case 0x00: sprintf (cstrName, "PID Undefined Usage"); break;
489 case kHIDUsage_PID_PhysicalInterfaceDevice: sprintf (cstrName, "Physical Interface Device"); break;
490 case kHIDUsage_PID_Normal: sprintf (cstrName, "Normal Force"); break;
492 case kHIDUsage_PID_SetEffectReport: sprintf (cstrName, "Set Effect Report"); break;
493 case kHIDUsage_PID_EffectBlockIndex: sprintf (cstrName, "Effect Block Index"); break;
494 case kHIDUsage_PID_ParamBlockOffset: sprintf (cstrName, "Parameter Block Offset"); break;
495 case kHIDUsage_PID_ROM_Flag: sprintf (cstrName, "ROM Flag"); break;
497 case kHIDUsage_PID_EffectType: sprintf (cstrName, "Effect Type"); break;
498 case kHIDUsage_PID_ET_ConstantForce: sprintf (cstrName, "Effect Type Constant Force"); break;
499 case kHIDUsage_PID_ET_Ramp: sprintf (cstrName, "Effect Type Ramp"); break;
500 case kHIDUsage_PID_ET_CustomForceData: sprintf (cstrName, "Effect Type Custom Force Data"); break;
501 case kHIDUsage_PID_ET_Square: sprintf (cstrName, "Effect Type Square"); break;
502 case kHIDUsage_PID_ET_Sine: sprintf (cstrName, "Effect Type Sine"); break;
503 case kHIDUsage_PID_ET_Triangle: sprintf (cstrName, "Effect Type Triangle"); break;
504 case kHIDUsage_PID_ET_SawtoothUp: sprintf (cstrName, "Effect Type Sawtooth Up"); break;
505 case kHIDUsage_PID_ET_SawtoothDown: sprintf (cstrName, "Effect Type Sawtooth Down"); break;
506 case kHIDUsage_PID_ET_Spring: sprintf (cstrName, "Effect Type Spring"); break;
507 case kHIDUsage_PID_ET_Damper: sprintf (cstrName, "Effect Type Damper"); break;
508 case kHIDUsage_PID_ET_Inertia: sprintf (cstrName, "Effect Type Inertia"); break;
509 case kHIDUsage_PID_ET_Friction: sprintf (cstrName, "Effect Type Friction"); break;
510 case kHIDUsage_PID_Duration: sprintf (cstrName, "Effect Duration"); break;
511 case kHIDUsage_PID_SamplePeriod: sprintf (cstrName, "Effect Sample Period"); break;
512 case kHIDUsage_PID_Gain: sprintf (cstrName, "Effect Gain"); break;
513 case kHIDUsage_PID_TriggerButton: sprintf (cstrName, "Effect Trigger Button"); break;
514 case kHIDUsage_PID_TriggerRepeatInterval: sprintf (cstrName, "Effect Trigger Repeat Interval"); break;
516 case kHIDUsage_PID_AxesEnable: sprintf (cstrName, "Axis Enable"); break;
517 case kHIDUsage_PID_DirectionEnable: sprintf (cstrName, "Direction Enable"); break;
519 case kHIDUsage_PID_Direction: sprintf (cstrName, "Direction"); break;
521 case kHIDUsage_PID_TypeSpecificBlockOffset: sprintf (cstrName, "Type Specific Block Offset"); break;
523 case kHIDUsage_PID_BlockType: sprintf (cstrName, "Block Type"); break;
525 case kHIDUsage_PID_SetEnvelopeReport: sprintf (cstrName, "Set Envelope Report"); break;
526 case kHIDUsage_PID_AttackLevel: sprintf (cstrName, "Envelope Attack Level"); break;
527 case kHIDUsage_PID_AttackTime: sprintf (cstrName, "Envelope Attack Time"); break;
528 case kHIDUsage_PID_FadeLevel: sprintf (cstrName, "Envelope Fade Level"); break;
529 case kHIDUsage_PID_FadeTime: sprintf (cstrName, "Envelope Fade Time"); break;
531 case kHIDUsage_PID_SetConditionReport: sprintf (cstrName, "Set Condition Report"); break;
532 case kHIDUsage_PID_CP_Offset: sprintf (cstrName, "Condition CP Offset"); break;
533 case kHIDUsage_PID_PositiveCoefficient: sprintf (cstrName, "Condition Positive Coefficient"); break;
534 case kHIDUsage_PID_NegativeCoefficient: sprintf (cstrName, "Condition Negative Coefficient"); break;
535 case kHIDUsage_PID_PositiveSaturation: sprintf (cstrName, "Condition Positive Saturation"); break;
536 case kHIDUsage_PID_NegativeSaturation: sprintf (cstrName, "Condition Negative Saturation"); break;
537 case kHIDUsage_PID_DeadBand: sprintf (cstrName, "Condition Dead Band"); break;
539 case kHIDUsage_PID_DownloadForceSample: sprintf (cstrName, "Download Force Sample"); break;
540 case kHIDUsage_PID_IsochCustomForceEnable: sprintf (cstrName, "Isoch Custom Force Enable"); break;
542 case kHIDUsage_PID_CustomForceDataReport: sprintf (cstrName, "Custom Force Data Report"); break;
543 case kHIDUsage_PID_CustomForceData: sprintf (cstrName, "Custom Force Data"); break;
545 case kHIDUsage_PID_CustomForceVendorDefinedData: sprintf (cstrName, "Custom Force Vendor Defined Data"); break;
546 case kHIDUsage_PID_SetCustomForceReport: sprintf (cstrName, "Set Custom Force Report"); break;
547 case kHIDUsage_PID_CustomForceDataOffset: sprintf (cstrName, "Custom Force Data Offset"); break;
548 case kHIDUsage_PID_SampleCount: sprintf (cstrName, "Custom Force Sample Count"); break;
550 case kHIDUsage_PID_SetPeriodicReport: sprintf (cstrName, "Set Periodic Report"); break;
551 case kHIDUsage_PID_Offset: sprintf (cstrName, "Periodic Offset"); break;
552 case kHIDUsage_PID_Magnitude: sprintf (cstrName, "Periodic Magnitude"); break;
553 case kHIDUsage_PID_Phase: sprintf (cstrName, "Periodic Phase"); break;
554 case kHIDUsage_PID_Period: sprintf (cstrName, "Periodic Period"); break;
556 case kHIDUsage_PID_SetConstantForceReport: sprintf (cstrName, "Set Constant Force Report"); break;
558 case kHIDUsage_PID_SetRampForceReport: sprintf (cstrName, "Set Ramp Force Report"); break;
559 case kHIDUsage_PID_RampStart: sprintf (cstrName, "Ramp Start"); break;
560 case kHIDUsage_PID_RampEnd: sprintf (cstrName, "Ramp End"); break;
562 case kHIDUsage_PID_EffectOperationReport: sprintf (cstrName, "Effect Operation Report"); break;
564 case kHIDUsage_PID_EffectOperation: sprintf (cstrName, "Effect Operation"); break;
565 case kHIDUsage_PID_OpEffectStart: sprintf (cstrName, "Op Effect Start"); break;
566 case kHIDUsage_PID_OpEffectStartSolo: sprintf (cstrName, "Op Effect Start Solo"); break;
567 case kHIDUsage_PID_OpEffectStop: sprintf (cstrName, "Op Effect Stop"); break;
568 case kHIDUsage_PID_LoopCount: sprintf (cstrName, "Op Effect Loop Count"); break;
570 case kHIDUsage_PID_DeviceGainReport: sprintf (cstrName, "Device Gain Report"); break;
571 case kHIDUsage_PID_DeviceGain: sprintf (cstrName, "Device Gain"); break;
573 case kHIDUsage_PID_PoolReport: sprintf (cstrName, "PID Pool Report"); break;
574 case kHIDUsage_PID_RAM_PoolSize: sprintf (cstrName, "RAM Pool Size"); break;
575 case kHIDUsage_PID_ROM_PoolSize: sprintf (cstrName, "ROM Pool Size"); break;
576 case kHIDUsage_PID_ROM_EffectBlockCount: sprintf (cstrName, "ROM Effect Block Count"); break;
577 case kHIDUsage_PID_SimultaneousEffectsMax: sprintf (cstrName, "Simultaneous Effects Max"); break;
578 case kHIDUsage_PID_PoolAlignment: sprintf (cstrName, "Pool Alignment"); break;
580 case kHIDUsage_PID_PoolMoveReport: sprintf (cstrName, "PID Pool Move Report"); break;
581 case kHIDUsage_PID_MoveSource: sprintf (cstrName, "Move Source"); break;
582 case kHIDUsage_PID_MoveDestination: sprintf (cstrName, "Move Destination"); break;
583 case kHIDUsage_PID_MoveLength: sprintf (cstrName, "Move Length"); break;
585 case kHIDUsage_PID_BlockLoadReport: sprintf (cstrName, "PID Block Load Report"); break;
587 case kHIDUsage_PID_BlockLoadStatus: sprintf (cstrName, "Block Load Status"); break;
588 case kHIDUsage_PID_BlockLoadSuccess: sprintf (cstrName, "Block Load Success"); break;
589 case kHIDUsage_PID_BlockLoadFull: sprintf (cstrName, "Block Load Full"); break;
590 case kHIDUsage_PID_BlockLoadError: sprintf (cstrName, "Block Load Error"); break;
591 case kHIDUsage_PID_BlockHandle: sprintf (cstrName, "Block Handle"); break;
593 case kHIDUsage_PID_BlockFreeReport: sprintf (cstrName, "PID Block Free Report"); break;
595 case kHIDUsage_PID_TypeSpecificBlockHandle: sprintf (cstrName, "Type Specific Block Handle"); break;
597 case kHIDUsage_PID_StateReport: sprintf (cstrName, "PID State Report"); break;
598 case kHIDUsage_PID_EffectPlaying: sprintf (cstrName, "Effect Playing"); break;
600 case kHIDUsage_PID_DeviceControlReport: sprintf (cstrName, "PID Device Control Report"); break;
602 case kHIDUsage_PID_DeviceControl: sprintf (cstrName, "PID Device Control"); break;
603 case kHIDUsage_PID_DC_EnableActuators: sprintf (cstrName, "Device Control Enable Actuators"); break;
604 case kHIDUsage_PID_DC_DisableActuators: sprintf (cstrName, "Device Control Disable Actuators"); break;
605 case kHIDUsage_PID_DC_StopAllEffects: sprintf (cstrName, "Device Control Stop All Effects"); break;
606 case kHIDUsage_PID_DC_DeviceReset: sprintf (cstrName, "Device Control Reset"); break;
607 case kHIDUsage_PID_DC_DevicePause: sprintf (cstrName, "Device Control Pause"); break;
608 case kHIDUsage_PID_DC_DeviceContinue: sprintf (cstrName, "Device Control Continue"); break;
609 case kHIDUsage_PID_DevicePaused: sprintf (cstrName, "Device Paused"); break;
610 case kHIDUsage_PID_ActuatorsEnabled: sprintf (cstrName, "Actuators Enabled"); break;
611 case kHIDUsage_PID_SafetySwitch: sprintf (cstrName, "Safety Switch"); break;
612 case kHIDUsage_PID_ActuatorOverrideSwitch: sprintf (cstrName, "Actuator Override Switch"); break;
613 case kHIDUsage_PID_ActuatorPower: sprintf (cstrName, "Actuator Power"); break;
614 case kHIDUsage_PID_StartDelay: sprintf (cstrName, "Start Delay"); break;
616 case kHIDUsage_PID_ParameterBlockSize: sprintf (cstrName, "Parameter Block Size"); break;
617 case kHIDUsage_PID_DeviceManagedPool: sprintf (cstrName, "Device Managed Pool"); break;
618 case kHIDUsage_PID_SharedParameterBlocks: sprintf (cstrName, "Shared Parameter Blocks"); break;
620 case kHIDUsage_PID_CreateNewEffectReport: sprintf (cstrName, "Create New Effect Report"); break;
621 case kHIDUsage_PID_RAM_PoolAvailable: sprintf (cstrName, "RAM Pool Available"); break;
622 default: sprintf (cstrName, "PID Usage 0x%lx", valueUsage); break;
624 break;
625 case kHIDPage_Unicode:
626 switch (valueUsage)
628 default: sprintf (cstrName, "Unicode Usage 0x%lx", valueUsage); break;
630 break;
631 case kHIDPage_PowerDevice:
632 if (((valueUsage >= 0x06) && (valueUsage <= 0x0F)) || ((valueUsage >= 0x26) && (valueUsage <= 0x2F)) ||
633 ((valueUsage >= 0x39) && (valueUsage <= 0x3F)) || ((valueUsage >= 0x48) && (valueUsage <= 0x4F)) ||
634 ((valueUsage >= 0x58) && (valueUsage <= 0x5F)) || (valueUsage == 0x6A) ||
635 ((valueUsage >= 0x74) && (valueUsage <= 0xFC)))
636 sprintf (cstrName, "Power Device Reserved");
637 else
638 switch (valueUsage)
640 case kHIDUsage_PD_Undefined: sprintf (cstrName, "Power Device Undefined Usage"); break;
641 case kHIDUsage_PD_iName: sprintf (cstrName, "Power Device Name Index"); break;
642 case kHIDUsage_PD_PresentStatus: sprintf (cstrName, "Power Device Present Status"); break;
643 case kHIDUsage_PD_ChangedStatus: sprintf (cstrName, "Power Device Changed Status"); break;
644 case kHIDUsage_PD_UPS: sprintf (cstrName, "Uninterruptible Power Supply"); break;
645 case kHIDUsage_PD_PowerSupply: sprintf (cstrName, "Power Supply"); break;
647 case kHIDUsage_PD_BatterySystem: sprintf (cstrName, "Battery System Power Module"); break;
648 case kHIDUsage_PD_BatterySystemID: sprintf (cstrName, "Battery System ID"); break;
649 case kHIDUsage_PD_Battery: sprintf (cstrName, "Battery"); break;
650 case kHIDUsage_PD_BatteryID: sprintf (cstrName, "Battery ID"); break;
651 case kHIDUsage_PD_Charger: sprintf (cstrName, "Charger"); break;
652 case kHIDUsage_PD_ChargerID: sprintf (cstrName, "Charger ID"); break;
653 case kHIDUsage_PD_PowerConverter: sprintf (cstrName, "Power Converter Power Module"); break;
654 case kHIDUsage_PD_PowerConverterID: sprintf (cstrName, "Power Converter ID"); break;
655 case kHIDUsage_PD_OutletSystem: sprintf (cstrName, "Outlet System power module"); break;
656 case kHIDUsage_PD_OutletSystemID: sprintf (cstrName, "Outlet System ID"); break;
657 case kHIDUsage_PD_Input: sprintf (cstrName, "Power Device Input"); break;
658 case kHIDUsage_PD_InputID: sprintf (cstrName, "Power Device Input ID"); break;
659 case kHIDUsage_PD_Output: sprintf (cstrName, "Power Device Output"); break;
660 case kHIDUsage_PD_OutputID: sprintf (cstrName, "Power Device Output ID"); break;
661 case kHIDUsage_PD_Flow: sprintf (cstrName, "Power Device Flow"); break;
662 case kHIDUsage_PD_FlowID: sprintf (cstrName, "Power Device Flow ID"); break;
663 case kHIDUsage_PD_Outlet: sprintf (cstrName, "Power Device Outlet"); break;
664 case kHIDUsage_PD_OutletID: sprintf (cstrName, "Power Device Outlet ID"); break;
665 case kHIDUsage_PD_Gang: sprintf (cstrName, "Power Device Gang"); break;
666 case kHIDUsage_PD_GangID: sprintf (cstrName, "Power Device Gang ID"); break;
667 case kHIDUsage_PD_PowerSummary: sprintf (cstrName, "Power Device Power Summary"); break;
668 case kHIDUsage_PD_PowerSummaryID: sprintf (cstrName, "Power Device Power Summary ID"); break;
670 case kHIDUsage_PD_Voltage: sprintf (cstrName, "Power Device Voltage"); break;
671 case kHIDUsage_PD_Current: sprintf (cstrName, "Power Device Current"); break;
672 case kHIDUsage_PD_Frequency: sprintf (cstrName, "Power Device Frequency"); break;
673 case kHIDUsage_PD_ApparentPower: sprintf (cstrName, "Power Device Apparent Power"); break;
674 case kHIDUsage_PD_ActivePower: sprintf (cstrName, "Power Device RMS Power"); break;
675 case kHIDUsage_PD_PercentLoad: sprintf (cstrName, "Power Device Percent Load"); break;
676 case kHIDUsage_PD_Temperature: sprintf (cstrName, "Power Device Temperature"); break;
677 case kHIDUsage_PD_Humidity: sprintf (cstrName, "Power Device Humidity"); break;
678 case kHIDUsage_PD_BadCount: sprintf (cstrName, "Power Device Bad Condition Count"); break;
680 case kHIDUsage_PD_ConfigVoltage: sprintf (cstrName, "Power Device Nominal Voltage"); break;
681 case kHIDUsage_PD_ConfigCurrent: sprintf (cstrName, "Power Device Nominal Current"); break;
682 case kHIDUsage_PD_ConfigFrequency: sprintf (cstrName, "Power Device Nominal Frequency"); break;
683 case kHIDUsage_PD_ConfigApparentPower: sprintf (cstrName, "Power Device Nominal Apparent Power"); break;
684 case kHIDUsage_PD_ConfigActivePower: sprintf (cstrName, "Power Device Nominal RMS Power"); break;
685 case kHIDUsage_PD_ConfigPercentLoad: sprintf (cstrName, "Power Device Nominal Percent Load"); break;
686 case kHIDUsage_PD_ConfigTemperature: sprintf (cstrName, "Power Device Nominal Temperature"); break;
688 case kHIDUsage_PD_ConfigHumidity: sprintf (cstrName, "Power Device Nominal Humidity"); break;
689 case kHIDUsage_PD_SwitchOnControl: sprintf (cstrName, "Power Device Switch On Control"); break;
690 case kHIDUsage_PD_SwitchOffControl: sprintf (cstrName, "Power Device Switch Off Control"); break;
691 case kHIDUsage_PD_ToggleControl: sprintf (cstrName, "Power Device Toogle Sequence Control"); break;
692 case kHIDUsage_PD_LowVoltageTransfer: sprintf (cstrName, "Power Device Min Transfer Voltage"); break;
693 case kHIDUsage_PD_HighVoltageTransfer: sprintf (cstrName, "Power Device Max Transfer Voltage"); break;
694 case kHIDUsage_PD_DelayBeforeReboot: sprintf (cstrName, "Power Device Delay Before Reboot"); break;
695 case kHIDUsage_PD_DelayBeforeStartup: sprintf (cstrName, "Power Device Delay Before Startup"); break;
696 case kHIDUsage_PD_DelayBeforeShutdown: sprintf (cstrName, "Power Device Delay Before Shutdown"); break;
697 case kHIDUsage_PD_Test: sprintf (cstrName, "Power Device Test Request/Result"); break;
698 case kHIDUsage_PD_ModuleReset: sprintf (cstrName, "Power Device Reset Request/Result"); break;
699 case kHIDUsage_PD_AudibleAlarmControl: sprintf (cstrName, "Power Device Audible Alarm Control"); break;
701 case kHIDUsage_PD_Present: sprintf (cstrName, "Power Device Present"); break;
702 case kHIDUsage_PD_Good: sprintf (cstrName, "Power Device Good"); break;
703 case kHIDUsage_PD_InternalFailure: sprintf (cstrName, "Power Device Internal Failure"); break;
704 case kHIDUsage_PD_VoltageOutOfRange: sprintf (cstrName, "Power Device Voltage Out Of Range"); break;
705 case kHIDUsage_PD_FrequencyOutOfRange: sprintf (cstrName, "Power Device Frequency Out Of Range"); break;
706 case kHIDUsage_PD_Overload: sprintf (cstrName, "Power Device Overload"); break;
707 case kHIDUsage_PD_OverCharged: sprintf (cstrName, "Power Device Over Charged"); break;
708 case kHIDUsage_PD_OverTemperature: sprintf (cstrName, "Power Device Over Temperature"); break;
709 case kHIDUsage_PD_ShutdownRequested: sprintf (cstrName, "Power Device Shutdown Requested"); break;
711 case kHIDUsage_PD_ShutdownImminent: sprintf (cstrName, "Power Device Shutdown Imminent"); break;
712 case kHIDUsage_PD_SwitchOnOff: sprintf (cstrName, "Power Device On/Off Switch Status"); break;
713 case kHIDUsage_PD_Switchable: sprintf (cstrName, "Power Device Switchable"); break;
714 case kHIDUsage_PD_Used: sprintf (cstrName, "Power Device Used"); break;
715 case kHIDUsage_PD_Boost: sprintf (cstrName, "Power Device Boosted"); break;
716 case kHIDUsage_PD_Buck: sprintf (cstrName, "Power Device Bucked"); break;
717 case kHIDUsage_PD_Initialized: sprintf (cstrName, "Power Device Initialized"); break;
718 case kHIDUsage_PD_Tested: sprintf (cstrName, "Power Device Tested"); break;
719 case kHIDUsage_PD_AwaitingPower: sprintf (cstrName, "Power Device Awaiting Power"); break;
720 case kHIDUsage_PD_CommunicationLost: sprintf (cstrName, "Power Device Communication Lost"); break;
722 case kHIDUsage_PD_iManufacturer: sprintf (cstrName, "Power Device Manufacturer String Index"); break;
723 case kHIDUsage_PD_iProduct: sprintf (cstrName, "Power Device Product String Index"); break;
724 case kHIDUsage_PD_iserialNumber: sprintf (cstrName, "Power Device Serial Number String Index"); break;
725 default: sprintf (cstrName, "Power Device Usage 0x%lx", valueUsage); break;
727 break;
728 case kHIDPage_BatterySystem:
729 if (((valueUsage >= 0x0A) && (valueUsage <= 0x0F)) || ((valueUsage >= 0x1E) && (valueUsage <= 0x27)) ||
730 ((valueUsage >= 0x30) && (valueUsage <= 0x3F)) || ((valueUsage >= 0x4C) && (valueUsage <= 0x5F)) ||
731 ((valueUsage >= 0x6C) && (valueUsage <= 0x7F)) || ((valueUsage >= 0x90) && (valueUsage <= 0xBF)) ||
732 ((valueUsage >= 0xC3) && (valueUsage <= 0xCF)) || ((valueUsage >= 0xDD) && (valueUsage <= 0xEF)) ||
733 ((valueUsage >= 0xF2) && (valueUsage <= 0xFF)))
734 sprintf (cstrName, "Power Device Reserved");
735 else
736 switch (valueUsage)
738 case kHIDUsage_BS_Undefined: sprintf (cstrName, "Battery System Undefined"); break;
739 case kHIDUsage_BS_SMBBatteryMode: sprintf (cstrName, "SMB Mode"); break;
740 case kHIDUsage_BS_SMBBatteryStatus: sprintf (cstrName, "SMB Status"); break;
741 case kHIDUsage_BS_SMBAlarmWarning: sprintf (cstrName, "SMB Alarm Warning"); break;
742 case kHIDUsage_BS_SMBChargerMode: sprintf (cstrName, "SMB Charger Mode"); break;
743 case kHIDUsage_BS_SMBChargerStatus: sprintf (cstrName, "SMB Charger Status"); break;
744 case kHIDUsage_BS_SMBChargerSpecInfo: sprintf (cstrName, "SMB Charger Extended Status"); break;
745 case kHIDUsage_BS_SMBSelectorState: sprintf (cstrName, "SMB Selector State"); break;
746 case kHIDUsage_BS_SMBSelectorPresets: sprintf (cstrName, "SMB Selector Presets"); break;
747 case kHIDUsage_BS_SMBSelectorInfo: sprintf (cstrName, "SMB Selector Info"); break;
748 case kHIDUsage_BS_OptionalMfgFunction1: sprintf (cstrName, "Battery System Optional SMB Mfg Function 1"); break;
749 case kHIDUsage_BS_OptionalMfgFunction2: sprintf (cstrName, "Battery System Optional SMB Mfg Function 2"); break;
750 case kHIDUsage_BS_OptionalMfgFunction3: sprintf (cstrName, "Battery System Optional SMB Mfg Function 3"); break;
751 case kHIDUsage_BS_OptionalMfgFunction4: sprintf (cstrName, "Battery System Optional SMB Mfg Function 4"); break;
752 case kHIDUsage_BS_OptionalMfgFunction5: sprintf (cstrName, "Battery System Optional SMB Mfg Function 5"); break;
753 case kHIDUsage_BS_ConnectionToSMBus: sprintf (cstrName, "Battery System Connection To System Management Bus"); break;
754 case kHIDUsage_BS_OutputConnection: sprintf (cstrName, "Battery System Output Connection Status"); break;
755 case kHIDUsage_BS_ChargerConnection: sprintf (cstrName, "Battery System Charger Connection"); break;
756 case kHIDUsage_BS_BatteryInsertion: sprintf (cstrName, "Battery System Battery Insertion"); break;
757 case kHIDUsage_BS_Usenext: sprintf (cstrName, "Battery System Use Next"); break;
758 case kHIDUsage_BS_OKToUse: sprintf (cstrName, "Battery System OK To Use"); break;
759 case kHIDUsage_BS_BatterySupported: sprintf (cstrName, "Battery System Battery Supported"); break;
760 case kHIDUsage_BS_SelectorRevision: sprintf (cstrName, "Battery System Selector Revision"); break;
761 case kHIDUsage_BS_ChargingIndicator: sprintf (cstrName, "Battery System Charging Indicator"); break;
762 case kHIDUsage_BS_ManufacturerAccess: sprintf (cstrName, "Battery System Manufacturer Access"); break;
763 case kHIDUsage_BS_RemainingCapacityLimit: sprintf (cstrName, "Battery System Remaining Capacity Limit"); break;
764 case kHIDUsage_BS_RemainingTimeLimit: sprintf (cstrName, "Battery System Remaining Time Limit"); break;
765 case kHIDUsage_BS_AtRate: sprintf (cstrName, "Battery System At Rate..."); break;
766 case kHIDUsage_BS_CapacityMode: sprintf (cstrName, "Battery System Capacity Mode"); break;
767 case kHIDUsage_BS_BroadcastToCharger: sprintf (cstrName, "Battery System Broadcast To Charger"); break;
768 case kHIDUsage_BS_PrimaryBattery: sprintf (cstrName, "Battery System Primary Battery"); break;
769 case kHIDUsage_BS_ChargeController: sprintf (cstrName, "Battery System Charge Controller"); break;
770 case kHIDUsage_BS_TerminateCharge: sprintf (cstrName, "Battery System Terminate Charge"); break;
771 case kHIDUsage_BS_TerminateDischarge: sprintf (cstrName, "Battery System Terminate Discharge"); break;
772 case kHIDUsage_BS_BelowRemainingCapacityLimit: sprintf (cstrName, "Battery System Below Remaining Capacity Limit"); break;
773 case kHIDUsage_BS_RemainingTimeLimitExpired: sprintf (cstrName, "Battery System Remaining Time Limit Expired"); break;
774 case kHIDUsage_BS_Charging: sprintf (cstrName, "Battery System Charging"); break;
775 case kHIDUsage_BS_Discharging: sprintf (cstrName, "Battery System Discharging"); break;
776 case kHIDUsage_BS_FullyCharged: sprintf (cstrName, "Battery System Fully Charged"); break;
777 case kHIDUsage_BS_FullyDischarged: sprintf (cstrName, "Battery System Fully Discharged"); break;
778 case kHIDUsage_BS_ConditioningFlag: sprintf (cstrName, "Battery System Conditioning Flag"); break;
779 case kHIDUsage_BS_AtRateOK: sprintf (cstrName, "Battery System At Rate OK"); break;
780 case kHIDUsage_BS_SMBErrorCode: sprintf (cstrName, "Battery System SMB Error Code"); break;
781 case kHIDUsage_BS_NeedReplacement: sprintf (cstrName, "Battery System Need Replacement"); break;
782 case kHIDUsage_BS_AtRateTimeToFull: sprintf (cstrName, "Battery System At Rate Time To Full"); break;
783 case kHIDUsage_BS_AtRateTimeToEmpty: sprintf (cstrName, "Battery System At Rate Time To Empty"); break;
784 case kHIDUsage_BS_AverageCurrent: sprintf (cstrName, "Battery System Average Current"); break;
785 case kHIDUsage_BS_Maxerror: sprintf (cstrName, "Battery System Max Error"); break;
786 case kHIDUsage_BS_RelativeStateOfCharge: sprintf (cstrName, "Battery System Relative State Of Charge"); break;
787 case kHIDUsage_BS_AbsoluteStateOfCharge: sprintf (cstrName, "Battery System Absolute State Of Charge"); break;
788 case kHIDUsage_BS_RemainingCapacity: sprintf (cstrName, "Battery System Remaining Capacity"); break;
789 case kHIDUsage_BS_FullChargeCapacity: sprintf (cstrName, "Battery System Full Charge Capacity"); break;
790 case kHIDUsage_BS_RunTimeToEmpty: sprintf (cstrName, "Battery System Run Time To Empty"); break;
791 case kHIDUsage_BS_AverageTimeToEmpty: sprintf (cstrName, "Battery System Average Time To Empty"); break;
792 case kHIDUsage_BS_AverageTimeToFull: sprintf (cstrName, "Battery System Average Time To Full"); break;
793 case kHIDUsage_BS_CycleCount: sprintf (cstrName, "Battery System Cycle Count"); break;
794 case kHIDUsage_BS_BattPackModelLevel: sprintf (cstrName, "Battery System Batt Pack Model Level"); break;
795 case kHIDUsage_BS_InternalChargeController: sprintf (cstrName, "Battery System Internal Charge Controller"); break;
796 case kHIDUsage_BS_PrimaryBatterySupport: sprintf (cstrName, "Battery System Primary Battery Support"); break;
797 case kHIDUsage_BS_DesignCapacity: sprintf (cstrName, "Battery System Design Capacity"); break;
798 case kHIDUsage_BS_SpecificationInfo: sprintf (cstrName, "Battery System Specification Info"); break;
799 case kHIDUsage_BS_ManufacturerDate: sprintf (cstrName, "Battery System Manufacturer Date"); break;
800 case kHIDUsage_BS_SerialNumber: sprintf (cstrName, "Battery System Serial Number"); break;
801 case kHIDUsage_BS_iManufacturerName: sprintf (cstrName, "Battery System Manufacturer Name Index"); break;
802 case kHIDUsage_BS_iDevicename: sprintf (cstrName, "Battery System Device Name Index"); break;
803 case kHIDUsage_BS_iDeviceChemistry: sprintf (cstrName, "Battery System Device Chemistry Index"); break;
804 case kHIDUsage_BS_ManufacturerData: sprintf (cstrName, "Battery System Manufacturer Data"); break;
805 case kHIDUsage_BS_Rechargable: sprintf (cstrName, "Battery System Rechargable"); break;
806 case kHIDUsage_BS_WarningCapacityLimit: sprintf (cstrName, "Battery System Warning Capacity Limit"); break;
807 case kHIDUsage_BS_CapacityGranularity1: sprintf (cstrName, "Battery System Capacity Granularity 1"); break;
808 case kHIDUsage_BS_CapacityGranularity2: sprintf (cstrName, "Battery System Capacity Granularity 2"); break;
809 case kHIDUsage_BS_iOEMInformation: sprintf (cstrName, "Battery System OEM Information Index"); break;
810 case kHIDUsage_BS_InhibitCharge: sprintf (cstrName, "Battery System Inhibit Charge"); break;
811 case kHIDUsage_BS_EnablePolling: sprintf (cstrName, "Battery System Enable Polling"); break;
812 case kHIDUsage_BS_ResetToZero: sprintf (cstrName, "Battery System Reset To Zero"); break;
813 case kHIDUsage_BS_ACPresent: sprintf (cstrName, "Battery System AC Present"); break;
814 case kHIDUsage_BS_BatteryPresent: sprintf (cstrName, "Battery System Battery Present"); break;
815 case kHIDUsage_BS_PowerFail: sprintf (cstrName, "Battery System Power Fail"); break;
816 case kHIDUsage_BS_AlarmInhibited: sprintf (cstrName, "Battery System Alarm Inhibited"); break;
817 case kHIDUsage_BS_ThermistorUnderRange: sprintf (cstrName, "Battery System Thermistor Under Range"); break;
818 case kHIDUsage_BS_ThermistorHot: sprintf (cstrName, "Battery System Thermistor Hot"); break;
819 case kHIDUsage_BS_ThermistorCold: sprintf (cstrName, "Battery System Thermistor Cold"); break;
820 case kHIDUsage_BS_ThermistorOverRange: sprintf (cstrName, "Battery System Thermistor Over Range"); break;
821 case kHIDUsage_BS_VoltageOutOfRange: sprintf (cstrName, "Battery System Voltage Out Of Range"); break;
822 case kHIDUsage_BS_CurrentOutOfRange: sprintf (cstrName, "Battery System Current Out Of Range"); break;
823 case kHIDUsage_BS_CurrentNotRegulated: sprintf (cstrName, "Battery System Current Not Regulated"); break;
824 case kHIDUsage_BS_VoltageNotRegulated: sprintf (cstrName, "Battery System Voltage Not Regulated"); break;
825 case kHIDUsage_BS_MasterMode: sprintf (cstrName, "Battery System Master Mode"); break;
826 case kHIDUsage_BS_ChargerSelectorSupport: sprintf (cstrName, "Battery System Charger Support Selector"); break;
827 case kHIDUsage_BS_ChargerSpec: sprintf (cstrName, "attery System Charger Specification"); break;
828 case kHIDUsage_BS_Level2: sprintf (cstrName, "Battery System Charger Level 2"); break;
829 case kHIDUsage_BS_Level3: sprintf (cstrName, "Battery System Charger Level 3"); break;
830 default: sprintf (cstrName, "Battery System Usage 0x%lx", valueUsage); break;
832 break;
833 case kHIDPage_AlphanumericDisplay:
834 switch (valueUsage)
836 default: sprintf (cstrName, "Alphanumeric Display Usage 0x%lx", valueUsage); break;
838 break;
839 case kHIDPage_BarCodeScanner:
840 switch (valueUsage)
842 default: sprintf (cstrName, "Bar Code Scanner Usage 0x%lx", valueUsage); break;
844 break;
845 case kHIDPage_Scale:
846 switch (valueUsage)
848 default: sprintf (cstrName, "Scale Usage 0x%lx", valueUsage); break;
850 break;
851 case kHIDPage_CameraControl:
852 switch (valueUsage)
854 default: sprintf (cstrName, "Camera Control Usage 0x%lx", valueUsage); break;
856 break;
857 case kHIDPage_Arcade:
858 switch (valueUsage)
860 default: sprintf (cstrName, "Arcade Usage 0x%lx", valueUsage); break;
862 break;
863 default:
864 if (valueUsagePage > kHIDPage_VendorDefinedStart)
865 sprintf (cstrName, "Vendor Defined Usage 0x%lx", valueUsage);
866 else
867 sprintf (cstrName, "Page: 0x%lx, Usage: 0x%lx", valueUsagePage, valueUsage);
868 break;
872 //*************************************************************************
874 // HIDCopyUsageName( inUsagePage, inUsage )
876 // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h )
878 // Notes: returns usage page and usage values in CFString form for unknown values
880 // Inputs: inUsagePage - the usage page
881 // inUsage - the usage
883 // Returns: CFStringRef - the resultant string
886 CFStringRef HIDCopyUsageName( long inUsagePage, long inUsage )
888 static CFPropertyListRef tCFPropertyListRef = NULL;
889 CFStringRef result = NULL;
891 if ( !tCFPropertyListRef ) {
892 tCFPropertyListRef = hu_XMLLoad( CFSTR( "HID_usage_strings" ), CFSTR( "plist" ) );
895 if ( tCFPropertyListRef ) {
896 if ( CFDictionaryGetTypeID( ) == CFGetTypeID( tCFPropertyListRef ) ) {
897 CFStringRef pageKeyCFStringRef = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "0x%4.4lX" ), inUsagePage );
899 if ( pageKeyCFStringRef ) {
900 CFDictionaryRef pageCFDictionaryRef;
902 if ( CFDictionaryGetValueIfPresent( tCFPropertyListRef, pageKeyCFStringRef, ( const void** ) &pageCFDictionaryRef ) ) {
903 CFStringRef pageCFStringRef;
905 if ( CFDictionaryGetValueIfPresent( pageCFDictionaryRef, kNameKeyCFStringRef, ( const void** ) &pageCFStringRef ) ) {
906 CFStringRef usageKeyCFStringRef = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "0x%4.4lX" ), inUsage );
908 if ( usageKeyCFStringRef ) {
909 CFStringRef usageCFStringRef;
911 if ( CFDictionaryGetValueIfPresent( pageCFDictionaryRef, usageKeyCFStringRef, ( const void** ) &usageCFStringRef ) ) {
912 result = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%@ %@" ), pageCFStringRef, usageCFStringRef );
914 #if FAKE_MISSING_NAMES
915 else {
916 result = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%@ #%@" ), pageCFStringRef, usageKeyCFStringRef );
918 #endif
919 CFRelease( usageKeyCFStringRef );
921 } else {
922 // no name data for this page
924 } else {
925 // no data for this page
927 CFRelease( pageKeyCFStringRef );
930 // CFRelease( tCFPropertyListRef ); // Leak this!
931 // tCFPropertyListRef = NULL;
933 return result;
934 } // HIDCopyUsageName
938 //*****************************************************
939 #pragma mark - local ( static ) function implementations
940 //*****************************************************
941 #if 0 // currently unused
942 /*************************************************************************
944 * hu_SaveToXMLFile( inCFPRef, inCFURLRef )
946 * Purpose: save a property list into an XML file
948 * Inputs: inCFPRef - the data
949 * inCFURLRef - URL for the file
951 * Returns: SInt32 - error code ( if any )
953 static SInt32 hu_SaveToXMLFile( CFPropertyListRef inCFPRef, CFURLRef inCFURLRef )
955 CFDataRef xmlCFDataRef;
956 SInt32 error = coreFoundationUnknownErr;
958 // Convert the property list into XML data.
959 xmlCFDataRef = CFPropertyListCreateXMLData( kCFAllocatorDefault, inCFPRef );
960 if ( xmlCFDataRef ) {
961 // Write the XML data to the file.
962 ( void ) CFURLWriteDataAndPropertiesToResource( inCFURLRef, xmlCFDataRef, NULL, &error );
964 // Release the XML data
965 CFRelease( xmlCFDataRef );
967 return error;
968 } // hu_SaveToXMLFile
969 #endif
970 /*************************************************************************
972 * hu_LoadFromXMLFile( inCFURLRef )
974 * Purpose: load a property list from an XML file
976 * Inputs: inCFURLRef - URL for the file
978 * Returns: CFPropertyListRef - the data
980 static CFPropertyListRef hu_LoadFromXMLFile( CFURLRef inCFURLRef )
982 CFDataRef xmlCFDataRef;
983 CFPropertyListRef myCFPropertyListRef = NULL;
985 // Read the XML file.
986 SInt32 error;
987 if ( CFURLCreateDataAndPropertiesFromResource( kCFAllocatorDefault, inCFURLRef, & xmlCFDataRef, NULL, NULL, & error ) ) {
988 CFStringRef errorString;
989 // Reconstitute the dictionary using the XML data.
990 myCFPropertyListRef = CFPropertyListCreateFromXMLData( kCFAllocatorDefault, xmlCFDataRef, kCFPropertyListImmutable, & errorString );
991 // Release the XML data
992 CFRelease( xmlCFDataRef );
994 return myCFPropertyListRef;
995 } // hu_LoadFromXMLFile
997 #if 0 // currently unused
998 /*************************************************************************
1000 * hu_XMLSave( inCFPropertyListRef, inResourceName, inResourceExtension )
1002 * Purpose: save a CFPropertyListRef into a resource( XML ) file
1004 * Inputs: inCFPropertyListRef - the data
1005 * inResourceName - name of the resource file
1006 * inResourceExtension - extension of the resource file
1008 * Returns: SInt32 - error code ( if any )
1010 static SInt32 hu_XMLSave( CFPropertyListRef inCFPropertyListRef, CFStringRef inResourceName, CFStringRef inResourceExtension )
1012 CFURLRef resFileCFURLRef;
1013 SInt32 error = - 1;
1015 resFileCFURLRef = CFBundleCopyResourceURL( CFBundleGetMainBundle( ), inResourceName, inResourceExtension, NULL );
1016 if ( resFileCFURLRef ) {
1017 error = hu_SaveToXMLFile( inCFPropertyListRef, resFileCFURLRef );
1018 CFRelease( resFileCFURLRef );
1020 return error;
1021 } // hu_XMLSave
1022 #endif
1023 /*************************************************************************
1025 * hu_XMLLoad( inResourceName, inResourceExtension )
1027 * Purpose: Load a resource( XML ) file into a CFPropertyListRef
1029 * Inputs: inResourceName - name of the resource file
1030 * inResourceExtension - extension of the resource file
1032 * Returns: CFPropertyListRef - the data
1034 static CFPropertyListRef hu_XMLLoad( CFStringRef inResourceName, CFStringRef inResourceExtension )
1036 CFURLRef resFileCFURLRef;
1037 CFPropertyListRef tCFPropertyListRef = NULL;
1039 resFileCFURLRef = CFBundleCopyResourceURL( CFBundleGetMainBundle( ), inResourceName, inResourceExtension, NULL );
1040 if ( resFileCFURLRef ) {
1041 tCFPropertyListRef = hu_LoadFromXMLFile( resFileCFURLRef );
1042 CFRelease( resFileCFURLRef );
1044 return tCFPropertyListRef;
1045 } // hu_XMLLoad
1047 /*************************************************************************
1049 * hu_XMLSearchForVendorNameByVendorID( inVendorID, outCStr )
1051 * Purpose: Find a vendor string in the <HID_device_usage_strings.plist> resource ( XML ) file
1053 * Inputs: inVendorID - the elements vendor ID
1054 * inProductID - the elements product ID
1055 * outCStr - address where result will be returned
1057 * Returns: Boolean - if successful
1059 static Boolean hu_XMLSearchForVendorNameByVendorID( long inVendorID, char * outCStr )
1061 Boolean results = FALSE;
1063 if ( ! gUsageCFPropertyListRef )
1064 gUsageCFPropertyListRef = hu_XMLLoad( CFSTR( "HID_device_usage_strings" ), CFSTR( "plist" ) );
1066 if ( gUsageCFPropertyListRef ) {
1067 if ( CFDictionaryGetTypeID( ) == CFGetTypeID( gUsageCFPropertyListRef ) ) {
1068 CFDictionaryRef vendorCFDictionaryRef;
1069 CFStringRef vendorKeyCFStringRef = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%ld" ), inVendorID );
1070 if ( vendorKeyCFStringRef ) {
1071 if ( CFDictionaryGetValueIfPresent( gUsageCFPropertyListRef, vendorKeyCFStringRef, ( const void ** ) & vendorCFDictionaryRef ) ) {
1072 CFStringRef vendorCFStringRef = NULL;
1073 if ( CFDictionaryGetValueIfPresent( vendorCFDictionaryRef, kNameKeyCFStringRef, ( const void ** ) & vendorCFStringRef ) && vendorCFStringRef ) {
1074 // CFShow( vendorCFStringRef );
1075 results = CFStringGetCString( vendorCFStringRef, outCStr, CFStringGetLength( vendorCFStringRef ) * sizeof( UniChar ) + 1, kCFStringEncodingUTF8 );
1078 CFRelease( vendorKeyCFStringRef );
1081 // ++ CFRelease( gUsageCFPropertyListRef ); // Leak this !
1083 return results;
1084 } // hu_XMLSearchForVendorNameByVendorID
1086 /*************************************************************************
1088 * hu_XMLSearchForProductNameByVendorProductID( inVendorID, inProductID, outCStr )
1090 * Purpose: Find an product string in the <HID_device_usage_strings.plist> resource ( XML ) file
1092 * Inputs: inVendorID - the elements vendor ID
1093 * inProductID - the elements product ID
1094 * outCStr - address where result will be returned
1096 * Returns: Boolean - if successful
1098 static Boolean hu_XMLSearchForProductNameByVendorProductID( long inVendorID, long inProductID, char * outCStr )
1100 Boolean results = FALSE;
1102 if ( ! gUsageCFPropertyListRef )
1103 gUsageCFPropertyListRef = hu_XMLLoad( CFSTR( "HID_device_usage_strings" ), CFSTR( "plist" ) );
1105 if ( gUsageCFPropertyListRef ) {
1106 if ( CFDictionaryGetTypeID( ) == CFGetTypeID( gUsageCFPropertyListRef ) ) {
1107 // first we make our vendor ID key
1108 CFStringRef vendorKeyCFStringRef = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%ld" ), inVendorID );
1109 if ( vendorKeyCFStringRef ) {
1110 // and use it to look up our vendor dictionary
1111 CFDictionaryRef vendorCFDictionaryRef;
1112 if ( CFDictionaryGetValueIfPresent( gUsageCFPropertyListRef, vendorKeyCFStringRef, ( const void ** ) & vendorCFDictionaryRef ) ) {
1113 // pull our vendor name our of that dictionary
1114 CFStringRef vendorCFStringRef = NULL;
1115 if ( CFDictionaryGetValueIfPresent( vendorCFDictionaryRef, kNameKeyCFStringRef, ( const void ** ) & vendorCFStringRef ) ) {
1116 #if FAKE_MISSING_NAMES
1117 CFRetain( vendorCFStringRef ); // so we can CFRelease it later
1118 } else {
1119 vendorCFStringRef = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "V: %@" ), vendorKeyCFStringRef );
1120 #endif
1123 // now we make our product ID key
1124 CFStringRef productKeyCFStringRef = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%ld" ), inProductID );
1125 if ( productKeyCFStringRef ) {
1126 // and use that key to look up our product dictionary in the vendor dictionary
1127 CFDictionaryRef productCFDictionaryRef;
1128 if ( CFDictionaryGetValueIfPresent( vendorCFDictionaryRef, productKeyCFStringRef, ( const void ** ) & productCFDictionaryRef ) ) {
1129 // pull our product name our of the product dictionary
1130 CFStringRef productCFStringRef = NULL;
1131 if ( CFDictionaryGetValueIfPresent( productCFDictionaryRef, kNameKeyCFStringRef, ( const void ** ) & productCFStringRef ) ) {
1132 #if FAKE_MISSING_NAMES
1133 CFRetain( productCFStringRef ); // so we can CFRelease it later
1134 } else {
1135 productCFStringRef = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "P: %@" ), kNameKeyCFStringRef );
1136 #endif
1138 CFStringRef fullCFStringRef = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%@ %@" ), vendorCFStringRef, productCFStringRef );
1139 if ( fullCFStringRef ) {
1140 // CFShow( fullCFStringRef );
1141 results = CFStringGetCString( fullCFStringRef, outCStr, CFStringGetLength( fullCFStringRef ) * sizeof( UniChar ) + 1, kCFStringEncodingUTF8 );
1142 CFRelease( fullCFStringRef );
1144 #if FAKE_MISSING_NAMES
1145 if ( productCFStringRef ) {
1146 CFRelease( productCFStringRef );
1148 #endif
1150 CFRelease( productKeyCFStringRef );
1153 #if FAKE_MISSING_NAMES
1154 if ( vendorCFStringRef ) {
1155 CFRelease( vendorCFStringRef );
1157 #endif
1159 CFRelease( vendorKeyCFStringRef );
1162 // ++ CFRelease( gUsageCFPropertyListRef ); // Leak this !
1164 return results;
1165 } // hu_XMLSearchForProductNameByVendorProductID
1167 /*************************************************************************
1169 * hu_XMLSearchForElementNameByCookie( inVendorID, inProductID, inCookie, outCStr )
1171 * Purpose: Find an element string in the <HID_cookie_strings.plist> resource( XML ) file
1173 * Inputs: inVendorID - the elements vendor ID
1174 * inProductID - the elements product ID
1175 * inCookie - the elements cookie
1176 * outCStr - address where result will be returned
1178 * Returns: Boolean - if successful
1180 static Boolean hu_XMLSearchForElementNameByCookie( long inVendorID, long inProductID, IOHIDElementCookie inCookie, char * outCStr )
1182 Boolean results = FALSE;
1184 if ( ! gCookieCFPropertyListRef )
1185 gCookieCFPropertyListRef = hu_XMLLoad( CFSTR( "HID_cookie_strings" ), CFSTR( "plist" ) );
1187 if ( gCookieCFPropertyListRef ) {
1188 if ( CFDictionaryGetTypeID( ) == CFGetTypeID( gCookieCFPropertyListRef ) ) {
1189 CFStringRef vendorKeyCFStringRef = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%ld" ), inVendorID );
1190 if ( vendorKeyCFStringRef ) {
1191 CFDictionaryRef vendorCFDictionaryRef;
1192 if ( CFDictionaryGetValueIfPresent( gCookieCFPropertyListRef, vendorKeyCFStringRef, ( const void ** ) & vendorCFDictionaryRef ) ) {
1193 CFDictionaryRef productCFDictionaryRef;
1194 CFStringRef productKeyCFStringRef;
1195 CFStringRef vendorCFStringRef;
1197 if ( CFDictionaryGetValueIfPresent( vendorCFDictionaryRef, kNameKeyCFStringRef, ( const void ** ) & vendorCFStringRef ) ) {
1198 // CFShow( vendorCFStringRef );
1200 productKeyCFStringRef = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%ld" ), inProductID );
1202 if ( CFDictionaryGetValueIfPresent( vendorCFDictionaryRef, productKeyCFStringRef, ( const void ** ) & productCFDictionaryRef ) ) {
1203 CFStringRef fullCFStringRef = NULL;
1204 CFStringRef cookieKeyCFStringRef;
1205 CFStringRef productCFStringRef;
1206 CFStringRef cookieCFStringRef;
1208 if ( CFDictionaryGetValueIfPresent( productCFDictionaryRef, kNameKeyCFStringRef, ( const void ** ) & productCFStringRef ) ) {
1209 // CFShow( productCFStringRef );
1211 cookieKeyCFStringRef = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%ld" ), inCookie );
1213 if ( CFDictionaryGetValueIfPresent( productCFDictionaryRef, cookieKeyCFStringRef, ( const void ** ) & cookieCFStringRef ) ) {
1214 #if VERBOSE_ELEMENT_NAMES
1215 fullCFStringRef = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%@ %@ %@" ), vendorCFStringRef, productCFStringRef, cookieCFStringRef );
1216 #else
1217 fullCFStringRef = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%@" ), cookieCFStringRef );
1218 #endif VERBOSE_ELEMENT_NAMES
1219 // CFShow( cookieCFStringRef );
1221 #if FAKE_MISSING_NAMES
1222 else {
1223 fullCFStringRef = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%@ %@ # %@" ), vendorCFStringRef, productCFStringRef, cookieKeyCFStringRef );
1225 #endif FAKE_MISSING_NAMES
1226 if ( fullCFStringRef ) {
1227 // CFShow( fullCFStringRef );
1228 results = CFStringGetCString( fullCFStringRef, outCStr, CFStringGetLength( fullCFStringRef ) * sizeof( UniChar ) + 1, kCFStringEncodingUTF8 );
1229 CFRelease( fullCFStringRef );
1231 CFRelease( cookieKeyCFStringRef );
1233 CFRelease( productKeyCFStringRef );
1235 CFRelease( vendorKeyCFStringRef );
1238 // ++ CFRelease( gCookieCFPropertyListRef ); // Leak this !
1240 return results;
1241 } // hu_XMLSearchForElementNameByCookie
1243 /*************************************************************************
1245 * hu_XMLSearchForElementNameByUsage( inVendorID, inProductID, inUsagePage, inUsage, outCStr )
1247 * Purpose: Find an element string in the <HID_device_usage_strings.plist> resource( XML ) file
1249 * Inputs: inVendorID - the elements vendor ID
1250 * inProductID - the elements product ID
1251 * inUsagePage - the elements usage page
1252 * inUsage - the elements usage
1253 * outCStr - address where result will be returned
1255 * Returns: Boolean - if successful
1257 static Boolean hu_XMLSearchForElementNameByUsage( long inVendorID, long inProductID, long inUsagePage, long inUsage, char * outCStr )
1259 Boolean results = FALSE;
1261 if ( !gUsageCFPropertyListRef ) {
1262 gUsageCFPropertyListRef = hu_XMLLoad( CFSTR( "HID_device_usage_strings" ), CFSTR( "plist" ) );
1265 if ( gUsageCFPropertyListRef ) {
1266 if ( CFDictionaryGetTypeID( ) == CFGetTypeID( gUsageCFPropertyListRef ) ) {
1267 CFStringRef vendorKeyCFStringRef = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%ld" ), inVendorID );
1269 if ( vendorKeyCFStringRef ) {
1270 CFDictionaryRef vendorCFDictionaryRef;
1272 if ( CFDictionaryGetValueIfPresent( gUsageCFPropertyListRef, vendorKeyCFStringRef, ( const void ** ) &vendorCFDictionaryRef ) ) {
1273 CFStringRef vendorCFStringRef = NULL;
1275 if ( CFDictionaryGetValueIfPresent( vendorCFDictionaryRef, kNameKeyCFStringRef, ( const void ** ) &vendorCFStringRef ) ) {
1276 vendorCFStringRef = CFStringCreateCopy( kCFAllocatorDefault, vendorCFStringRef );
1277 } else {
1278 vendorCFStringRef = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "v: %ld" ), inVendorID );
1279 // CFShow( vendorCFStringRef );
1281 CFStringRef productKeyCFStringRef = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%ld" ), inProductID );
1283 CFDictionaryRef productCFDictionaryRef;
1284 if ( CFDictionaryGetValueIfPresent( vendorCFDictionaryRef, productKeyCFStringRef, ( const void ** ) &productCFDictionaryRef ) ) {
1285 CFStringRef fullCFStringRef = NULL;
1287 CFStringRef productCFStringRef;
1288 if ( CFDictionaryGetValueIfPresent( productCFDictionaryRef, kNameKeyCFStringRef, ( const void ** ) &productCFStringRef ) ) {
1289 // CFShow( productCFStringRef );
1291 CFStringRef usageKeyCFStringRef = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%ld:%ld" ), inUsagePage, inUsage );
1292 CFStringRef usageCFStringRef;
1293 if ( CFDictionaryGetValueIfPresent( productCFDictionaryRef, usageKeyCFStringRef, ( const void ** ) &usageCFStringRef ) ) {
1294 #if VERBOSE_ELEMENT_NAMES
1295 fullCFStringRef = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%@ %@ %@" ), vendorCFStringRef, productCFStringRef, usageCFStringRef );
1296 #else
1297 fullCFStringRef = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%@" ), usageCFStringRef );
1298 #endif VERBOSE_ELEMENT_NAMES
1299 // CFShow( usageCFStringRef );
1301 #if FAKE_MISSING_NAMES
1302 else {
1303 fullCFStringRef = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%@ %@ # %@" ), vendorCFStringRef, productCFStringRef, usageKeyCFStringRef );
1305 #endif FAKE_MISSING_NAMES
1307 if ( fullCFStringRef ) {
1308 // CFShow( fullCFStringRef );
1309 results = CFStringGetCString( fullCFStringRef, outCStr, CFStringGetLength( fullCFStringRef ) * sizeof( UniChar ) + 1, kCFStringEncodingUTF8 );
1310 CFRelease( fullCFStringRef );
1312 CFRelease( usageKeyCFStringRef );
1314 if ( vendorCFStringRef ) {
1315 CFRelease( vendorCFStringRef );
1317 CFRelease( productKeyCFStringRef );
1319 CFRelease( vendorKeyCFStringRef );
1322 // ++ CFRelease( gUsageCFPropertyListRef ); // Leak this !
1324 return results;
1325 } // hu_XMLSearchForElementNameByUsage
1327 #if 0 // currently unused
1328 /*************************************************************************
1330 * hu_AddVendorProductToCFDict( inCFMutableDictionaryRef, inVendorID, inVendorCFStringRef, inProductID, inProductCFStringRef )
1332 * Purpose: add a vendor & product to a dictionary
1334 * Inputs: inCFMutableDictionaryRef - the dictionary
1335 * inVendorID - the elements vendor ID
1336 * inProductID - the elements product ID
1337 * inProductCFStringRef - the string to be added
1339 * Returns: Boolean - if successful
1341 static Boolean hu_AddVendorProductToCFDict( CFMutableDictionaryRef inCFMutableDictionaryRef, long inVendorID, CFStringRef inVendorCFStringRef, long inProductID, CFStringRef inProductCFStringRef )
1343 Boolean results = FALSE;
1345 if ( inCFMutableDictionaryRef && ( CFDictionaryGetTypeID( ) == CFGetTypeID( inCFMutableDictionaryRef ) ) ) {
1346 CFMutableDictionaryRef vendorCFMutableDictionaryRef;
1347 CFStringRef vendorKeyCFStringRef;
1349 CFMutableDictionaryRef productCFMutableDictionaryRef;
1350 CFStringRef productKeyCFStringRef;
1352 // if the vendor dictionary doesn't exist
1353 vendorKeyCFStringRef = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%ld" ), inVendorID );
1354 if ( CFDictionaryGetValueIfPresent( inCFMutableDictionaryRef, vendorKeyCFStringRef, ( const void ** ) & vendorCFMutableDictionaryRef ) ) {
1355 // copy it.
1356 vendorCFMutableDictionaryRef = CFDictionaryCreateMutableCopy( kCFAllocatorDefault, 0, vendorCFMutableDictionaryRef );
1357 } else { // ...otherwise...
1358 // create it.
1359 vendorCFMutableDictionaryRef = CFDictionaryCreateMutable( kCFAllocatorDefault, 0, & kCFTypeDictionaryKeyCallBacks, & kCFTypeDictionaryValueCallBacks );
1360 results = TRUE;
1363 // if the vendor name key doesn't exist
1364 if ( ! CFDictionaryContainsKey( vendorCFMutableDictionaryRef, kNameKeyCFStringRef ) ) {
1365 // create it.
1366 CFDictionaryAddValue( vendorCFMutableDictionaryRef, kNameKeyCFStringRef, inVendorCFStringRef );
1367 results = TRUE;
1370 // if the product key exists in the vendor dictionary
1371 productKeyCFStringRef = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%ld" ), inProductID );
1372 if ( CFDictionaryGetValueIfPresent( vendorCFMutableDictionaryRef, productKeyCFStringRef, ( const void ** ) & productCFMutableDictionaryRef ) ) {
1373 // copy it.
1374 productCFMutableDictionaryRef = CFDictionaryCreateMutableCopy( kCFAllocatorDefault, 0, productCFMutableDictionaryRef );
1375 } else { // ...otherwise...
1376 // create it.
1377 productCFMutableDictionaryRef = CFDictionaryCreateMutable( kCFAllocatorDefault, 0, & kCFTypeDictionaryKeyCallBacks, & kCFTypeDictionaryValueCallBacks );
1378 results = TRUE;
1381 // if the product name key doesn't exist
1382 if ( ! CFDictionaryContainsKey( productCFMutableDictionaryRef, kNameKeyCFStringRef ) ) {
1383 // create it.
1384 CFDictionaryAddValue( productCFMutableDictionaryRef, kNameKeyCFStringRef, inProductCFStringRef );
1385 results = TRUE;
1388 if ( vendorCFMutableDictionaryRef ) {
1389 if ( productCFMutableDictionaryRef ) {
1390 if ( results )
1391 CFDictionarySetValue( vendorCFMutableDictionaryRef, productKeyCFStringRef, productCFMutableDictionaryRef );
1392 CFRelease( productCFMutableDictionaryRef );
1394 if ( results )
1395 CFDictionarySetValue( inCFMutableDictionaryRef, vendorKeyCFStringRef, vendorCFMutableDictionaryRef );
1396 CFRelease( vendorCFMutableDictionaryRef );
1398 if ( productKeyCFStringRef )
1399 CFRelease( productKeyCFStringRef );
1400 if ( vendorKeyCFStringRef )
1401 CFRelease( vendorKeyCFStringRef );
1403 return results;
1404 } // hu_AddVendorProductToCFDict
1406 /*************************************************************************
1408 * hu_AddDeviceElementToUsageXML( inDevice, inElement )
1410 * Purpose: add a device and it's elements to our usage( XML ) file
1412 * Inputs: inDevice - the device
1413 * inElement - the element
1415 * Returns: Boolean - if successful
1417 static Boolean hu_AddDeviceElementToUsageXML( IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHIDElementRef )
1419 Boolean results = FALSE;
1421 if ( gUsageCFPropertyListRef ) {
1422 CFRelease( gUsageCFPropertyListRef );
1425 gUsageCFPropertyListRef = hu_XMLLoad( CFSTR( "HID_device_usage_strings" ), CFSTR( "plist" ) );
1427 if ( gUsageCFPropertyListRef ) {
1428 CFMutableDictionaryRef tCFMutableDictionaryRef = CFDictionaryCreateMutableCopy( kCFAllocatorDefault, 0, gUsageCFPropertyListRef );
1430 if ( tCFMutableDictionaryRef ) {
1431 CFMutableDictionaryRef vendorCFMutableDictionaryRef;
1433 CFMutableDictionaryRef productCFMutableDictionaryRef;
1434 CFStringRef productKeyCFStringRef;
1436 CFStringRef usageKeyCFStringRef;
1438 // if the vendor dictionary exists...
1439 long vendorID = IOHIDDevice_GetVendorID( inIOHIDDeviceRef );
1440 CFStringRef vendorKeyCFStringRef = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%ld" ), vendorID );
1441 if ( vendorKeyCFStringRef ) {
1442 if ( CFDictionaryGetValueIfPresent( tCFMutableDictionaryRef, vendorKeyCFStringRef,
1443 ( const void ** ) &vendorCFMutableDictionaryRef ) ) {
1444 // ...copy it...
1445 vendorCFMutableDictionaryRef = CFDictionaryCreateMutableCopy( kCFAllocatorDefault, 0, vendorCFMutableDictionaryRef );
1446 } else { // ...otherwise...
1447 // ...create it.
1448 vendorCFMutableDictionaryRef = CFDictionaryCreateMutable( kCFAllocatorDefault,
1450 &kCFTypeDictionaryKeyCallBacks,
1451 &kCFTypeDictionaryValueCallBacks );
1452 results = TRUE;
1455 // if the vendor name key doesn't exist...
1456 if ( !CFDictionaryContainsKey( vendorCFMutableDictionaryRef, kNameKeyCFStringRef ) ) {
1457 CFStringRef manCFStringRef = IOHIDDevice_GetManufacturer( inIOHIDDeviceRef );
1458 // ...create it.
1459 CFDictionaryAddValue( vendorCFMutableDictionaryRef, kNameKeyCFStringRef, manCFStringRef );
1460 results = TRUE;
1463 // if the product key exists in the vendor dictionary...
1464 long productID = IOHIDDevice_GetProductID( inIOHIDDeviceRef );
1465 productKeyCFStringRef = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%ld" ), productID );
1467 if ( CFDictionaryGetValueIfPresent( vendorCFMutableDictionaryRef, productKeyCFStringRef,
1468 ( const void ** ) &productCFMutableDictionaryRef ) ) {
1469 // ...copy it...
1470 productCFMutableDictionaryRef = CFDictionaryCreateMutableCopy( kCFAllocatorDefault, 0, productCFMutableDictionaryRef );
1471 } else { // ...otherwise...
1472 // ...create it.
1473 productCFMutableDictionaryRef = CFDictionaryCreateMutable( kCFAllocatorDefault,
1475 &kCFTypeDictionaryKeyCallBacks,
1476 &kCFTypeDictionaryValueCallBacks );
1477 results = TRUE;
1480 // if the product name key doesn't exist...
1481 if ( !CFDictionaryContainsKey( productCFMutableDictionaryRef, kNameKeyCFStringRef ) ) {
1482 CFStringRef productCFStringRef = IOHIDDevice_GetProduct( inIOHIDDeviceRef );
1483 // ...create it.
1484 CFDictionaryAddValue( productCFMutableDictionaryRef, kNameKeyCFStringRef, productCFStringRef );
1485 results = TRUE;
1488 // if the usage key doesn't exist in the product dictionary...
1489 uint32_t usagePage = IOHIDElementGetUsagePage( inIOHIDElementRef );
1490 uint32_t usage = IOHIDElementGetUsagePage( inIOHIDElementRef );
1491 usageKeyCFStringRef = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%ld:%ld" ), usagePage, usage );
1493 if ( usageKeyCFStringRef ) {
1494 if ( !CFDictionaryContainsKey( productCFMutableDictionaryRef, usageKeyCFStringRef ) ) {
1495 // find it's generic name
1496 CFStringRef usageCFStringRef = HIDCopyUsageName( usagePage, usage );
1498 if ( usageCFStringRef ) {
1499 // and add that.
1500 CFDictionaryAddValue( productCFMutableDictionaryRef, usageKeyCFStringRef, usageCFStringRef );
1501 results = TRUE;
1502 CFRelease( usageCFStringRef );
1505 CFRelease( usageKeyCFStringRef );
1508 if ( vendorCFMutableDictionaryRef ) {
1509 if ( productCFMutableDictionaryRef ) {
1510 if ( results ) {
1511 CFDictionarySetValue( vendorCFMutableDictionaryRef, productKeyCFStringRef, productCFMutableDictionaryRef );
1513 CFRelease( productCFMutableDictionaryRef );
1516 if ( results ) {
1517 CFDictionarySetValue( tCFMutableDictionaryRef, vendorKeyCFStringRef, vendorCFMutableDictionaryRef );
1519 CFRelease( vendorCFMutableDictionaryRef );
1521 CFRelease( vendorKeyCFStringRef );
1524 if ( productKeyCFStringRef ) {
1525 CFRelease( productKeyCFStringRef );
1528 if ( results ) {
1529 hu_XMLSave( tCFMutableDictionaryRef, CFSTR( "HID_device_usage_strings" ), CFSTR( "plist" ) );
1531 CFRelease( tCFMutableDictionaryRef );
1534 return results;
1535 } // hu_AddDeviceElementToUsageXML
1536 #endif