From c0cf43d9e8b028a899af16a16e81dfe4729b6c95 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 4 Nov 2004 17:24:18 +0000 Subject: cleaned up Darwin side after Linux work; laid out Darwin structure and got device opening working svn path=/trunk/externals/hcs/hid/; revision=2206 --- TODO | 136 ++++++++++ doc/hid-help.pd | 70 ++--- hid.c | 38 +-- hid.h | 9 +- hid_darwin.c | 826 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 5 files changed, 962 insertions(+), 117 deletions(-) create mode 100644 TODO diff --git a/TODO b/TODO new file mode 100644 index 0000000..b924514 --- /dev/null +++ b/TODO @@ -0,0 +1,136 @@ +============================================================================== += define generic event struct (probably Pd-ized input_event ) + something like: + +struct input_event { + struct timeval time; + t_int type; + t_int code; + t_int value; +}; + + +The question is whether the timeval is needed at all. Linux and Darwin +support it. Currently, I can only think of UPS PWR events actually using +timevals. + + + +=============================================================================== += HID Manager Type/Usage/UsagePage -> Linux Type/Code mapping + + UsagePage + + +Misc Input/Generic Desktop X == ev_rel/rel_x +Button Input/Button #1 == ev_key/btn_left + + +LED UsagePage => ev_led +LED Usages == Linux ev_led codes + + + +============================================================================== += device selection + +by # (1,2,...), generic name (mouse1, joystick2, tablet3...), or device name +("Trackpad", "Microsoft 5-button Mouse with IntelliEye(TM)", etc.) + + first get # working, that's probably the easiest + +by # +------------------------------ +GNU/Linux + sprintf(x_devname->s_name,"/dev/input/event%d",deviceNum + 1); + +Darwin + prHIDBuildDeviceList(); + currentHIDDevice = discoveredDevices[gNumberOfHIDDevices]; + + +============================================================================== += figure out how to store device ID in obj struct + +(in SC_HID.c its locID and cookie) + +it should probably just store the Pd arguments + + + +============================================================================== += raw values vs. calibrated + +- relative axes should probably be raw data, since its pixel data, but then + this causes problems with sensitivity across different mice. The mouse + sensitivity would probably best translate as resolution, ie calibrated data, + rather than sensitivity, ie raw data. + +- absolute axes should be calibrated, so that the same positions on different + devices map to the same value + +- but then, I could just create an [autocal] object in Pd, and have [hid] + output only raw values. This would probably be best in keeping with the + idea of having [hid] giving as low level access as possible, then using + [mouse], [joystick], [tablet], etc. objects providing a nice, consistent + interface to the respective devices. + + + +============================================================================== += pollfn for mouse-like devices + +- determine whether using a pollfn is actually better than using a t_clock + +- any device that acts like a system mouse can be used with a pollfn, since + the mouse data will go thru Pd's network port, triggering the pollfn. + +- this is probably unnecessary since the t_clock seems to run well at 1ms delay + + + +============================================================================== += make generic functions for the basic actions + + releaseDevices() + buildDeviceList() + buildElementList() + getEvent() + + - make Darwin HID Manager -> Linux input event convertor functions + + + +============================================================================== += [close( message might be totally frivolous. + +- what does Max's [hi] do with that? + +- when would you need to close a device, yet still have the object there? + [open( closes the previous device anyway. + + + +============================================================================== += function return values + +- most functions probably do not need return values + +- return (1) seems to be the default on many functions + + +============================================================================== += control input messages + +- the [delay( message should be replaced by the [poll( msg + +- should [poll( also start things, or should it just set polling time? + +- are [start( and [stop( needed? is 0/1 enough? + + + + + + + diff --git a/doc/hid-help.pd b/doc/hid-help.pd index d6d546f..c0f664a 100644 --- a/doc/hid-help.pd +++ b/doc/hid-help.pd @@ -1,18 +1,18 @@ -#N canvas 124 73 923 591 10; +#N canvas 124 73 912 605 10; #X msg 390 265 ev_key btn_left 0 1.09868e+09; #X obj 390 244 prepend set; #X obj 149 473 route rel_x rel_y; #X floatatom 149 493 5 0 0 0 - - -; #X floatatom 206 493 5 0 0 0 - - -; #X msg 148 77 start; -#X msg 167 96 stop; +#X msg 174 96 stop; #X floatatom 494 384 12 0 0 1 time - -; #X obj 401 364 unpack s s f f; -#X msg 229 25 open 0; -#X msg 237 48 open 1; -#X msg 253 70 open 2; -#X msg 265 91 open 3; -#X msg 277 111 open 4; +#X msg 241 29 open 0; +#X msg 248 47 open 1; +#X msg 255 65 open 2; +#X msg 261 83 open 3; +#X msg 267 101 open 4; #X floatatom 206 454 7 0 0 0 - - -; #X floatatom 264 454 7 0 0 0 - - -; #X obj 206 433 route abs_x abs_y; @@ -26,8 +26,8 @@ #X floatatom 243 537 5 0 0 0 - - -; #X obj 61 219 bng 35 250 50 0 empty empty event_received 38 18 1 8 -225280 -1 -1; -#X obj 2 2 cnv 15 900 20 empty empty hid 2 11 1 18 -233017 -66577 0 -; +#X obj 2 2 cnv 15 900 20 empty empty [hid] 2 11 1 18 -233017 -66577 +0; #X text 362 287 outlet message format:; #X text 386 301 eventtype eventcode value timestamp; #X obj 742 104 ev-list; @@ -51,28 +51,35 @@ #X floatatom 289 398 5 0 0 1 ev_syn - -; #X obj 262 397 +; #X msg 262 377 1; -#X obj 248 209 hid 4; -#X msg 295 142 close; -#X msg 374 171 delay 20; -#X msg 312 170 delay 2; -#X msg 441 171 delay 200; +#X msg 317 149 close; +#X msg 374 178 delay 20; +#X msg 312 177 delay 2; +#X msg 441 178 delay 200; +#X text 383 40 new possibilities:; +#X msg 391 62 poll; +#X msg 431 62 poll 20; +#X msg 499 61 nopoll; +#X text 361 149 probably not needed; +#X msg 282 127 refresh; +#X text 343 125 refresh device list; +#X obj 248 209 hid 2; #X connect 1 0 0 0; #X connect 2 0 3 0; #X connect 2 1 4 0; -#X connect 5 0 49 0; -#X connect 6 0 49 0; +#X connect 5 0 60 0; +#X connect 6 0 60 0; #X connect 8 0 20 0; #X connect 8 1 19 0; #X connect 8 2 18 0; #X connect 8 3 7 0; -#X connect 9 0 49 0; -#X connect 10 0 49 0; -#X connect 11 0 49 0; -#X connect 12 0 49 0; -#X connect 13 0 49 0; +#X connect 9 0 60 0; +#X connect 10 0 60 0; +#X connect 11 0 60 0; +#X connect 12 0 60 0; +#X connect 13 0 60 0; #X connect 16 0 14 0; #X connect 16 1 15 0; -#X connect 17 0 49 0; +#X connect 17 0 60 0; #X connect 23 0 21 0; #X connect 23 1 22 0; #X connect 23 2 24 0; @@ -85,12 +92,13 @@ #X connect 46 0 47 1; #X connect 47 0 46 0; #X connect 48 0 47 0; -#X connect 49 0 43 0; -#X connect 49 0 25 0; -#X connect 49 0 45 0; -#X connect 49 0 1 0; -#X connect 49 0 8 0; -#X connect 50 0 49 0; -#X connect 51 0 49 0; -#X connect 52 0 49 0; -#X connect 53 0 49 0; +#X connect 49 0 60 0; +#X connect 50 0 60 0; +#X connect 51 0 60 0; +#X connect 52 0 60 0; +#X connect 58 0 60 0; +#X connect 60 0 43 0; +#X connect 60 0 25 0; +#X connect 60 0 45 0; +#X connect 60 0 1 0; +#X connect 60 0 8 0; diff --git a/hid.c b/hid.c index 41e1c9c..47938a8 100644 --- a/hid.c +++ b/hid.c @@ -25,7 +25,6 @@ #include "hid.h" - /*------------------------------------------------------------------------------ * LOCAL DEFINES */ @@ -33,13 +32,14 @@ //#define DEBUG(x) #define DEBUG(x) x -#define DEFAULT_DELAY 500 +#define DEFAULT_DELAY 5 /*------------------------------------------------------------------------------ * IMPLEMENTATION */ -void hid_stop(t_hid *x) +/* stop polling the device */ +void hid_stop(t_hid* x) { DEBUG(post("hid_stop");); @@ -49,11 +49,9 @@ void hid_stop(t_hid *x) post("[hid] polling stopped"); x->x_started = 0; } - - hid_devicelist_refresh(x); } - +/* close the device */ t_int hid_close(t_hid *x) { DEBUG(post("hid_close");); @@ -79,19 +77,16 @@ t_int hid_open(t_hid *x, t_float f) if (f > 0) x->x_device_number = f; else - x->x_device_number = 1; - + x->x_device_number = 0; + if (hid_open_device(x,x->x_device_number)) { error("[hid] can not open device %d",x->x_device_number); + post("\\================================ [hid] ================================/\n"); return (1); } - post("\nWARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING"); - post("This object is under development! The interface could change at anytime!"); - post("As I write cross-platform versions, the interface might have to change."); - post("WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING"); - post("================================= [hid] =================================\n"); + post("\\================================ [hid] ================================/\n"); return (0); } @@ -156,13 +151,14 @@ static void hid_free(t_hid* x) clock_free(x->x_clock); } +/* create a new instance of this class */ static void *hid_new(t_float f) { t_hid *x = (t_hid *)pd_new(hid_class); DEBUG(post("hid_new");); - post("================================= [hid] ================================="); + post("/================================ [hid] ================================\\"); post("[hid] %s, written by Hans-Christoph Steiner ",version); #if !defined(__linux__) && !defined(__APPLE__) error(" !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!"); @@ -179,11 +175,16 @@ static void *hid_new(t_float f) /* create anything outlet used for HID data */ outlet_new(&x->x_obj, 0); - - /* Open the device and save settings */ - if (hid_open(x,f)) - error("[hid] device %d did not open",(t_int)f); + /* find and report the list of devices */ + hid_devicelist_refresh(x); + + /* Open the device and save settings. If there is an error, return the object + * anyway, so that the inlets and outlets are created, thus not breaking the + * patch. */ +/* if (hid_open(x,f)) */ +/* error("[hid] device %d did not open",(t_int)f); */ + return (x); } @@ -204,6 +205,7 @@ void hid_setup(void) /* add inlet message methods */ class_addmethod(hid_class,(t_method) hid_delay,gensym("delay"),A_DEFFLOAT,0); class_addmethod(hid_class,(t_method) hid_open,gensym("open"),A_DEFFLOAT,0); + class_addmethod(hid_class,(t_method) hid_devicelist_refresh,gensym("refresh"),0); class_addmethod(hid_class,(t_method) hid_close,gensym("close"),0); class_addmethod(hid_class,(t_method) hid_start,gensym("start"),0); class_addmethod(hid_class,(t_method) hid_start,gensym("poll"),0); diff --git a/hid.h b/hid.h index c719552..9637830 100644 --- a/hid.h +++ b/hid.h @@ -11,7 +11,7 @@ */ #include "input_arrays.h" -static char *version = "$Revision: 1.4 $"; +static char *version = "$Revision: 1.5 $"; /*------------------------------------------------------------------------------ * CLASS DEF @@ -28,9 +28,10 @@ typedef struct _hid t_int x_read_ok; t_int x_started; t_int x_delay; - t_int x_vendorID; - t_int x_productID; - t_int x_locID; + long x_locID; +/* these two are probably unnecessary */ + long x_vendorID; + long x_productID; } t_hid; diff --git a/hid_darwin.c b/hid_darwin.c index b4fc292..a7d3bef 100644 --- a/hid_darwin.c +++ b/hid_darwin.c @@ -2,7 +2,7 @@ /* * Apple Darwin HID Manager support for Pd [hid] object * - * based on SC_HID.cpp from SuperCollider3 by Jan Truetzschler v. Falkenstein + * some code from SuperCollider3's SC_HID.cpp by Jan Truetzschler v. Falkenstein * * Copyright (c) 2004 Hans-Christoph All rights reserved. * @@ -43,6 +43,7 @@ #include #include "HID_Utilities_External.h" +#include "HID_Error_Handler.h" /* #include @@ -77,7 +78,178 @@ pRecDevice discoveredDevices[256]; EventLoopTimerRef gTimer = NULL; /*============================================================================== - * FUNCTIONS + * FUNCTION PROTOTYPES + *============================================================================== + */ +char *convertEventsFromDarwinToLinux(pRecElement element); + +/*============================================================================== + * EVENT TYPE/CODE CONVERSION FUNCTIONS + *============================================================================== + */ + +char *convertDarwinToLinuxType(IOHIDElementType type) +{ + char *returnType = ""; + + switch (type) + { + case kIOHIDElementTypeInput_Misc: + sprintf(returnType, "ev_msc"); + break; + case kIOHIDElementTypeInput_Button: + sprintf(returnType, "ev_key"); + break; + case kIOHIDElementTypeInput_Axis: + sprintf(returnType, "ev_abs"); + break; + case kIOHIDElementTypeInput_ScanCodes: + sprintf(returnType, "undefined"); + break; + case kIOHIDElementTypeOutput: + sprintf(returnType, "undefined"); + break; + case kIOHIDElementTypeFeature: + sprintf(returnType, "undefined"); + break; + case kIOHIDElementTypeCollection: + sprintf(returnType, "undefined"); + break; + default: + HIDReportErrorNum("Unknown element type : ", type); + sprintf(returnType, "unknown"); + } + + return(returnType); +} + + +/* ============================================================================== */ +/* Pd [hid] FUNCTIONS */ +/* ============================================================================== */ + +t_int hid_output_events(t_hid *x) +{ + DEBUG(post("hid_output_events");); + + SInt32 value; + pRecDevice pCurrentHIDDevice; + pRecElement pCurrentHIDElement; +// char *type = ""; +// char *code = ""; + t_atom event_data[4]; + + // look for the right device: + pCurrentHIDDevice = HIDGetFirstDevice (); + while (pCurrentHIDDevice && (pCurrentHIDDevice->locID !=x->x_locID)) + pCurrentHIDDevice = HIDGetNextDevice (pCurrentHIDDevice); + if(!pCurrentHIDDevice) return (1); + + + /* get the first element */ + pCurrentHIDElement = HIDGetFirstDeviceElement (pCurrentHIDDevice, kHIDElementTypeIO); + /* cycle thru all elements */ + while (pCurrentHIDElement) + { + value = HIDGetElementValue (pCurrentHIDDevice, pCurrentHIDElement); + + if (pCurrentHIDElement) + { + value = HIDGetElementValue (pCurrentHIDDevice, pCurrentHIDElement); + // if it's not a button and it's not a hatswitch then calibrate +/* if(( pCurrentHIDElement->type != kIOHIDElementTypeInput_Button ) && */ +/* ( pCurrentHIDElement->usagePage == 0x01 && pCurrentHIDElement->usage != kHIDUsage_GD_Hatswitch)) */ +/* value = HIDCalibrateValue ( value, pCurrentHIDElement ); */ + + /* type */ +// HIDGetTypeName(pCurrentHIDElement->type,type); +// SETSYMBOL(event_data, gensym(type)); + /* code */ +// HIDGetUsageName(pCurrentHIDElement->usagePage, pCurrentHIDElement->usage, code); +// SETSYMBOL(event_data + 1, gensym(code)); + /* value */ +// SETFLOAT(event_data + 2, (t_float)value); + /* time */ + // TODO temp space filler for testing, got to find where I get the event time +// SETFLOAT(event_data + 3, (t_float)value); +// SETFLOAT(event_data + 3, (t_float)(hid_input_event.time).tv_sec); +// outlet_anything(x->x_obj.te_outlet,atom_gensym(event_data),3,event_data+1); + } + pCurrentHIDElement = HIDGetNextDeviceElement (pCurrentHIDElement, kHIDElementTypeIO); + } + return (0); +} + + + +t_int hid_open_device(t_hid *x, t_int device_number) +{ + DEBUG(post("hid_open_device");); + + t_int i,err,result; + pRecDevice currentDevice = NULL; + + result = HIDBuildDeviceList (NULL, NULL); + // returns false if no device found + if(result) error("[hid]: no HID devices found\n"); + +/* + * If the specified device is greater than the total number of devices, return + * an error. + */ + int numdevs = HIDCountDevices(); + gNumberOfHIDDevices = numdevs; + if (device_number >= numdevs) { + error("[hid]: no such device, \"%d\", only %d devices found\n",device_number,numdevs); + return (1); + } + + currentDevice = HIDGetFirstDevice(); + +/* + * The most recently discovered HID is the first element of the list here. I + * want the oldest to be number 0 rather than the newest, so I use (numdevs - + * device_number - 1). + */ + for(i=0; i < numdevs - device_number - 1; ++i) + currentDevice = HIDGetNextDevice(currentDevice); + + x->x_locID = currentDevice->locID; +// TODO: buildElementList(), outputting text to console +// TODO: queue all elements except absolute axes + + post("[hid] opened device %d: %s %s", + device_number, currentDevice->manufacturer, currentDevice->product); + + return (0); +} + + +t_int hid_close_device(t_hid *x) +{ + DEBUG(post("hid_close_device");); + + post("close_device %d",x->x_device_number); + releaseHIDDevices(); + + return (0); +} + +t_int hid_devicelist_refresh(t_hid *x) +{ + DEBUG(post("hid_devicelist_refresh");); + + /* the device list should be refreshed here */ + if ( (prHIDBuildDeviceList()) && (prHIDBuildElementList()) ) + return (0); + else + return (1); +} + + + +/*============================================================================== + * HID UTILIES FUNCTIONS *============================================================================== */ @@ -152,10 +324,10 @@ int prHIDBuildDeviceList(void) //pass in usage & usagepage //kHIDUsage_GD_Joystick kHIDUsage_GD_GamePad - usagePage = kHIDPage_GenericDesktop; - usage = NULL; + //usagePage = kHIDPage_GenericDesktop; + //usage = NULL; - Boolean result = HIDBuildDeviceList (usagePage, usage); + Boolean result = HIDBuildDeviceList (NULL, NULL); // returns false if no device found if(result) error("[hid]: no HID devices found\n"); @@ -169,13 +341,13 @@ int prHIDBuildDeviceList(void) char cstrDeviceName [256]; pCurrentHIDDevice = HIDGetFirstDevice(); - for(i=0; i= 0; --i) { - post("'%s' '%s' version %d", + post("Device %d: '%s' '%s' version %d",i, pCurrentHIDDevice->manufacturer,pCurrentHIDDevice->product,pCurrentHIDDevice->version); //usage HIDGetUsageName (pCurrentHIDDevice->usagePage, pCurrentHIDDevice->usage, cstrDeviceName); - post("vendorID: %d productID: %d locID: %d", + post(" vendorID: %d productID: %d locID: %d", pCurrentHIDDevice->vendorID,pCurrentHIDDevice->productID,pCurrentHIDDevice->locID); pCurrentHIDDevice = HIDGetNextDevice (pCurrentHIDDevice); } @@ -189,7 +361,7 @@ int prHIDBuildDeviceList(void) int prHIDGetValue(void) { - DEBUG(post("prHIDGetValue");); + DEBUG(post("hid_output_events");); int locID = NULL; int cookieNum = NULL; @@ -198,6 +370,7 @@ int prHIDGetValue(void) PyrSlot *a = g->sp - 2; //class PyrSlot *b = g->sp - 1; //locID device PyrSlot *c = g->sp; //element cookie + int locID, cookieNum; int err = slotIntVal(b, &locID); if (err) return err; err = slotIntVal(c, &cookieNum); @@ -209,11 +382,14 @@ int prHIDGetValue(void) while (pCurrentHIDDevice && (pCurrentHIDDevice->locID !=locID)) pCurrentHIDDevice = HIDGetNextDevice (pCurrentHIDDevice); if(!pCurrentHIDDevice) return (1); + + // look for the right element: pRecElement pCurrentHIDElement = HIDGetFirstDeviceElement (pCurrentHIDDevice, kHIDElementTypeIO); // use gElementCookie to find current element while (pCurrentHIDElement && (pCurrentHIDElement->cookie != cookie)) pCurrentHIDElement = HIDGetNextDeviceElement (pCurrentHIDElement, kHIDElementTypeIO); + if (pCurrentHIDElement) { @@ -306,13 +482,13 @@ void PushQueueEvents_CalibratedValue(void) } -static pascal void IdleTimer(EventLoopTimerRef inTimer, void* userData) -{ - DEBUG(post("IdleTimer");); +/* static pascal void IdleTimer(EventLoopTimerRef inTimer, void* userData) */ +/* { */ +/* DEBUG(post("IdleTimer");); */ - #pragma unused (inTimer, userData) - PushQueueEvents_CalibratedValue (); -} +/* #pragma unused (inTimer, userData) */ +/* PushQueueEvents_CalibratedValue (); */ +/* } */ int prHIDReleaseDeviceList(void) @@ -324,17 +500,18 @@ int prHIDReleaseDeviceList(void) } -static EventLoopTimerUPP GetTimerUPP(void) -{ - DEBUG(post("GetTimerUPP");); - - static EventLoopTimerUPP sTimerUPP = NULL; +/* static EventLoopTimerUPP GetTimerUPP(void) */ +/* { */ +/* DEBUG(post("GetTimerUPP");); */ - if (sTimerUPP == NULL) - sTimerUPP = NewEventLoopTimerUPP(IdleTimer); +/* static EventLoopTimerUPP sTimerUPP = NULL; */ +/* if (sTimerUPP == NULL) */ +/* sTimerUPP = NewEventLoopTimerUPP(IdleTimer); */ - return sTimerUPP; -} +/* return sTimerUPP; */ +/* } */ + + /* typedef void (*IOHIDCallbackFunction) (void * target, IOReturn result, void * refcon, void * sender); @@ -347,17 +524,17 @@ void callback (void * target, IOReturn result, void * refcon, void * sender) } */ -int prHIDRunEventLoop(void) -{ - DEBUG(post("prHIDRunEventLoop");); +/* int prHIDRunEventLoop(void) */ +/* { */ +/* DEBUG(post("prHIDRunEventLoop");); */ - //PyrSlot *a = g->sp - 1; //class +/* //PyrSlot *a = g->sp - 1; //class */ - InstallEventLoopTimer(GetCurrentEventLoop(), 0, 0.001, GetTimerUPP (), 0, &gTimer); +/* InstallEventLoopTimer(GetCurrentEventLoop(), 0, 0.001, GetTimerUPP (), 0, &gTimer); */ - //HIDSetQueueCallback(pCurrentHIDDevice, callback); - return (0); -} +/* //HIDSetQueueCallback(pCurrentHIDDevice, callback); */ +/* return (0); */ +/* } */ int prHIDQueueDevice(void) @@ -465,39 +642,15 @@ int prHIDDequeueDevice(void) } -int prHIDStopEventLoop(void) -{ - DEBUG(post("prHIDStopEventLoop");); - - if (gTimer) - RemoveEventLoopTimer(gTimer); - gTimer = NULL; - return (0); -} - - -t_int hid_open_device(t_hid *x, t_int device_number) -{ - post("open_device %d",device_number); - - return (1); -} - -t_int hid_open_device(t_hid *x) -{ - return (0); -} - - -t_int hid_devicelist_refresh(t_hid *x) -{ - /* the device list should be refreshed here */ - if ( (prHIDBuildDeviceList()) && (prHIDBuildElementList()) ) - return (0); - else - return (1); -} +/* int prHIDStopEventLoop(void) */ +/* { */ +/* DEBUG(post("prHIDStopEventLoop");); */ +/* if (gTimer) */ +/* RemoveEventLoopTimer(gTimer); */ +/* gTimer = NULL; */ +/* return (0); */ +/* } */ /* this is just a rough sketch */ @@ -515,6 +668,551 @@ t_int hid_devicelist_refresh(t_hid *x) /* } */ +//void HIDGetUsageName (const long valueUsagePage, const long valueUsage, char * cstrName) +char *convertEventsFromDarwinToLinux(pRecElement element) +{ + char *cstrName = ""; +// this allows these definitions to exist in an XML .plist file +/* if (xml_GetUsageName(valueUsagePage, valueUsage, cstrName)) */ +/* return; */ + + switch (element->usagePage) + { + case kHIDPage_Undefined: + switch (element->usage) + { + default: sprintf (cstrName, "Undefined Page, Usage 0x%lx", element->usage); break; + } + break; + case kHIDPage_GenericDesktop: + switch (element->usage) + { + case kHIDUsage_GD_Pointer: sprintf (cstrName, "Pointer"); break; + case kHIDUsage_GD_Mouse: sprintf (cstrName, "Mouse"); break; + case kHIDUsage_GD_Joystick: sprintf (cstrName, "Joystick"); break; + case kHIDUsage_GD_GamePad: sprintf (cstrName, "GamePad"); break; + case kHIDUsage_GD_Keyboard: sprintf (cstrName, "Keyboard"); break; + case kHIDUsage_GD_Keypad: sprintf (cstrName, "Keypad"); break; + case kHIDUsage_GD_MultiAxisController: sprintf (cstrName, "Multi-Axis Controller"); break; + + case kHIDUsage_GD_X: sprintf (cstrName, "X-Axis"); break; + case kHIDUsage_GD_Y: sprintf (cstrName, "Y-Axis"); break; + case kHIDUsage_GD_Z: sprintf (cstrName, "Z-Axis"); break; + case kHIDUsage_GD_Rx: sprintf (cstrName, "X-Rotation"); break; + case kHIDUsage_GD_Ry: sprintf (cstrName, "Y-Rotation"); break; + case kHIDUsage_GD_Rz: sprintf (cstrName, "Z-Rotation"); break; + case kHIDUsage_GD_Slider: sprintf (cstrName, "Slider"); break; + case kHIDUsage_GD_Dial: sprintf (cstrName, "Dial"); break; + case kHIDUsage_GD_Wheel: sprintf (cstrName, "Wheel"); break; + case kHIDUsage_GD_Hatswitch: sprintf (cstrName, "Hatswitch"); break; + case kHIDUsage_GD_CountedBuffer: sprintf (cstrName, "Counted Buffer"); break; + case kHIDUsage_GD_ByteCount: sprintf (cstrName, "Byte Count"); break; + case kHIDUsage_GD_MotionWakeup: sprintf (cstrName, "Motion Wakeup"); break; + case kHIDUsage_GD_Start: sprintf (cstrName, "Start"); break; + case kHIDUsage_GD_Select: sprintf (cstrName, "Select"); break; + + case kHIDUsage_GD_Vx: sprintf (cstrName, "X-Velocity"); break; + case kHIDUsage_GD_Vy: sprintf (cstrName, "Y-Velocity"); break; + case kHIDUsage_GD_Vz: sprintf (cstrName, "Z-Velocity"); break; + case kHIDUsage_GD_Vbrx: sprintf (cstrName, "X-Rotation Velocity"); break; + case kHIDUsage_GD_Vbry: sprintf (cstrName, "Y-Rotation Velocity"); break; + case kHIDUsage_GD_Vbrz: sprintf (cstrName, "Z-Rotation Velocity"); break; + case kHIDUsage_GD_Vno: sprintf (cstrName, "Vno"); break; + + case kHIDUsage_GD_SystemControl: sprintf (cstrName, "System Control"); break; + case kHIDUsage_GD_SystemPowerDown: sprintf (cstrName, "System Power Down"); break; + case kHIDUsage_GD_SystemSleep: sprintf (cstrName, "System Sleep"); break; + case kHIDUsage_GD_SystemWakeUp: sprintf (cstrName, "System Wake Up"); break; + case kHIDUsage_GD_SystemContextMenu: sprintf (cstrName, "System Context Menu"); break; + case kHIDUsage_GD_SystemMainMenu: sprintf (cstrName, "System Main Menu"); break; + case kHIDUsage_GD_SystemAppMenu: sprintf (cstrName, "System App Menu"); break; + case kHIDUsage_GD_SystemMenuHelp: sprintf (cstrName, "System Menu Help"); break; + case kHIDUsage_GD_SystemMenuExit: sprintf (cstrName, "System Menu Exit"); break; + case kHIDUsage_GD_SystemMenu: sprintf (cstrName, "System Menu"); break; + case kHIDUsage_GD_SystemMenuRight: sprintf (cstrName, "System Menu Right"); break; + case kHIDUsage_GD_SystemMenuLeft: sprintf (cstrName, "System Menu Left"); break; + case kHIDUsage_GD_SystemMenuUp: sprintf (cstrName, "System Menu Up"); break; + case kHIDUsage_GD_SystemMenuDown: sprintf (cstrName, "System Menu Down"); break; + + case kHIDUsage_GD_DPadUp: sprintf (cstrName, "DPad Up"); break; + case kHIDUsage_GD_DPadDown: sprintf (cstrName, "DPad Down"); break; + case kHIDUsage_GD_DPadRight: sprintf (cstrName, "DPad Right"); break; + case kHIDUsage_GD_DPadLeft: sprintf (cstrName, "DPad Left"); break; + + case kHIDUsage_GD_Reserved: sprintf (cstrName, "Reserved"); break; + + default: sprintf (cstrName, "Generic Desktop Usage 0x%lx", element->usage); break; + } + break; + case kHIDPage_Simulation: + switch (element->usage) + { + default: sprintf (cstrName, "Simulation Usage 0x%lx", element->usage); break; + } + break; + case kHIDPage_VR: + switch (element->usage) + { + default: sprintf (cstrName, "VR Usage 0x%lx", element->usage); break; + } + break; + case kHIDPage_Sport: + switch (element->usage) + { + default: sprintf (cstrName, "Sport Usage 0x%lx", element->usage); break; + } + break; + case kHIDPage_Game: + switch (element->usage) + { + default: sprintf (cstrName, "Game Usage 0x%lx", element->usage); break; + } + break; + case kHIDPage_KeyboardOrKeypad: + switch (element->usage) + { + default: sprintf (cstrName, "Keyboard Usage 0x%lx", element->usage); break; + } + break; + case kHIDPage_LEDs: + switch (element->usage) + { + // some LED usages + case kHIDUsage_LED_IndicatorRed: sprintf (cstrName, "Red LED"); break; + case kHIDUsage_LED_IndicatorGreen: sprintf (cstrName, "Green LED"); break; + case kHIDUsage_LED_IndicatorAmber: sprintf (cstrName, "Amber LED"); break; + case kHIDUsage_LED_GenericIndicator: sprintf (cstrName, "Generic LED"); break; + case kHIDUsage_LED_SystemSuspend: sprintf (cstrName, "System Suspend LED"); break; + case kHIDUsage_LED_ExternalPowerConnected: sprintf (cstrName, "External Power LED"); break; + default: sprintf (cstrName, "LED Usage 0x%lx", element->usage); break; + } + break; + case kHIDPage_Button: + switch (element->usage) + { + default: sprintf (cstrName, "Button #%ld", element->usage); break; + } + break; + case kHIDPage_Ordinal: + switch (element->usage) + { + default: sprintf (cstrName, "Ordinal Instance %lx", element->usage); break; + } + break; + case kHIDPage_Telephony: + switch (element->usage) + { + default: sprintf (cstrName, "Telephony Usage 0x%lx", element->usage); break; + } + break; + case kHIDPage_Consumer: + switch (element->usage) + { + default: sprintf (cstrName, "Consumer Usage 0x%lx", element->usage); break; + } + break; + case kHIDPage_Digitizer: + switch (element->usage) + { + default: sprintf (cstrName, "Digitizer Usage 0x%lx", element->usage); break; + } + break; + case kHIDPage_PID: + if (((element->usage >= 0x02) && (element->usage <= 0x1F)) || ((element->usage >= 0x29) && (element->usage <= 0x2F)) || + ((element->usage >= 0x35) && (element->usage <= 0x3F)) || ((element->usage >= 0x44) && (element->usage <= 0x4F)) || + (element->usage == 0x8A) || (element->usage == 0x93) || ((element->usage >= 0x9D) && (element->usage <= 0x9E)) || + ((element->usage >= 0xA1) && (element->usage <= 0xA3)) || ((element->usage >= 0xAD) && (element->usage <= 0xFFFF))) + sprintf (cstrName, "PID Reserved"); + else + switch (element->usage) + { + case 0x00: sprintf (cstrName, "PID Undefined Usage"); break; + case kHIDUsage_PID_PhysicalInterfaceDevice: sprintf (cstrName, "Physical Interface Device"); break; + case kHIDUsage_PID_Normal: sprintf (cstrName, "Normal Force"); break; + + case kHIDUsage_PID_SetEffectReport: sprintf (cstrName, "Set Effect Report"); break; + case kHIDUsage_PID_EffectBlockIndex: sprintf (cstrName, "Effect Block Index"); break; + case kHIDUsage_PID_ParamBlockOffset: sprintf (cstrName, "Parameter Block Offset"); break; + case kHIDUsage_PID_ROM_Flag: sprintf (cstrName, "ROM Flag"); break; + + case kHIDUsage_PID_EffectType: sprintf (cstrName, "Effect Type"); break; + case kHIDUsage_PID_ET_ConstantForce: sprintf (cstrName, "Effect Type Constant Force"); break; + case kHIDUsage_PID_ET_Ramp: sprintf (cstrName, "Effect Type Ramp"); break; + case kHIDUsage_PID_ET_CustomForceData: sprintf (cstrName, "Effect Type Custom Force Data"); break; + case kHIDUsage_PID_ET_Square: sprintf (cstrName, "Effect Type Square"); break; + case kHIDUsage_PID_ET_Sine: sprintf (cstrName, "Effect Type Sine"); break; + case kHIDUsage_PID_ET_Triangle: sprintf (cstrName, "Effect Type Triangle"); break; + case kHIDUsage_PID_ET_SawtoothUp: sprintf (cstrName, "Effect Type Sawtooth Up"); break; + case kHIDUsage_PID_ET_SawtoothDown: sprintf (cstrName, "Effect Type Sawtooth Down"); break; + case kHIDUsage_PID_ET_Spring: sprintf (cstrName, "Effect Type Spring"); break; + case kHIDUsage_PID_ET_Damper: sprintf (cstrName, "Effect Type Damper"); break; + case kHIDUsage_PID_ET_Inertia: sprintf (cstrName, "Effect Type Inertia"); break; + case kHIDUsage_PID_ET_Friction: sprintf (cstrName, "Effect Type Friction"); break; + case kHIDUsage_PID_Duration: sprintf (cstrName, "Effect Duration"); break; + case kHIDUsage_PID_SamplePeriod: sprintf (cstrName, "Effect Sample Period"); break; + case kHIDUsage_PID_Gain: sprintf (cstrName, "Effect Gain"); break; + case kHIDUsage_PID_TriggerButton: sprintf (cstrName, "Effect Trigger Button"); break; + case kHIDUsage_PID_TriggerRepeatInterval: sprintf (cstrName, "Effect Trigger Repeat Interval"); break; + + case kHIDUsage_PID_AxesEnable: sprintf (cstrName, "Axis Enable"); break; + case kHIDUsage_PID_DirectionEnable: sprintf (cstrName, "Direction Enable"); break; + + case kHIDUsage_PID_Direction: sprintf (cstrName, "Direction"); break; + + case kHIDUsage_PID_TypeSpecificBlockOffset: sprintf (cstrName, "Type Specific Block Offset"); break; + + case kHIDUsage_PID_BlockType: sprintf (cstrName, "Block Type"); break; + + case kHIDUsage_PID_SetEnvelopeReport: sprintf (cstrName, "Set Envelope Report"); break; + case kHIDUsage_PID_AttackLevel: sprintf (cstrName, "Envelope Attack Level"); break; + case kHIDUsage_PID_AttackTime: sprintf (cstrName, "Envelope Attack Time"); break; + case kHIDUsage_PID_FadeLevel: sprintf (cstrName, "Envelope Fade Level"); break; + case kHIDUsage_PID_FadeTime: sprintf (cstrName, "Envelope Fade Time"); break; + + case kHIDUsage_PID_SetConditionReport: sprintf (cstrName, "Set Condition Report"); break; + case kHIDUsage_PID_CP_Offset: sprintf (cstrName, "Condition CP Offset"); break; + case kHIDUsage_PID_PositiveCoefficient: sprintf (cstrName, "Condition Positive Coefficient"); break; + case kHIDUsage_PID_NegativeCoefficient: sprintf (cstrName, "Condition Negative Coefficient"); break; + case kHIDUsage_PID_PositiveSaturation: sprintf (cstrName, "Condition Positive Saturation"); break; + case kHIDUsage_PID_NegativeSaturation: sprintf (cstrName, "Condition Negative Saturation"); break; + case kHIDUsage_PID_DeadBand: sprintf (cstrName, "Condition Dead Band"); break; + + case kHIDUsage_PID_DownloadForceSample: sprintf (cstrName, "Download Force Sample"); break; + case kHIDUsage_PID_IsochCustomForceEnable: sprintf (cstrName, "Isoch Custom Force Enable"); break; + + case kHIDUsage_PID_CustomForceDataReport: sprintf (cstrName, "Custom Force Data Report"); break; + case kHIDUsage_PID_CustomForceData: sprintf (cstrName, "Custom Force Data"); break; + + case kHIDUsage_PID_CustomForceVendorDefinedData: sprintf (cstrName, "Custom Force Vendor Defined Data"); break; + case kHIDUsage_PID_SetCustomForceReport: sprintf (cstrName, "Set Custom Force Report"); break; + case kHIDUsage_PID_CustomForceDataOffset: sprintf (cstrName, "Custom Force Data Offset"); break; + case kHIDUsage_PID_SampleCount: sprintf (cstrName, "Custom Force Sample Count"); break; + + case kHIDUsage_PID_SetPeriodicReport: sprintf (cstrName, "Set Periodic Report"); break; + case kHIDUsage_PID_Offset: sprintf (cstrName, "Periodic Offset"); break; + case kHIDUsage_PID_Magnitude: sprintf (cstrName, "Periodic Magnitude"); break; + case kHIDUsage_PID_Phase: sprintf (cstrName, "Periodic Phase"); break; + case kHIDUsage_PID_Period: sprintf (cstrName, "Periodic Period"); break; + + case kHIDUsage_PID_SetConstantForceReport: sprintf (cstrName, "Set Constant Force Report"); break; + + case kHIDUsage_PID_SetRampForceReport: sprintf (cstrName, "Set Ramp Force Report"); break; + case kHIDUsage_PID_RampStart: sprintf (cstrName, "Ramp Start"); break; + case kHIDUsage_PID_RampEnd: sprintf (cstrName, "Ramp End"); break; + + case kHIDUsage_PID_EffectOperationReport: sprintf (cstrName, "Effect Operation Report"); break; + + case kHIDUsage_PID_EffectOperation: sprintf (cstrName, "Effect Operation"); break; + case kHIDUsage_PID_OpEffectStart: sprintf (cstrName, "Op Effect Start"); break; + case kHIDUsage_PID_OpEffectStartSolo: sprintf (cstrName, "Op Effect Start Solo"); break; + case kHIDUsage_PID_OpEffectStop: sprintf (cstrName, "Op Effect Stop"); break; + case kHIDUsage_PID_LoopCount: sprintf (cstrName, "Op Effect Loop Count"); break; + + case kHIDUsage_PID_DeviceGainReport: sprintf (cstrName, "Device Gain Report"); break; + case kHIDUsage_PID_DeviceGain: sprintf (cstrName, "Device Gain"); break; + + case kHIDUsage_PID_PoolReport: sprintf (cstrName, "PID Pool Report"); break; + case kHIDUsage_PID_RAM_PoolSize: sprintf (cstrName, "RAM Pool Size"); break; + case kHIDUsage_PID_ROM_PoolSize: sprintf (cstrName, "ROM Pool Size"); break; + case kHIDUsage_PID_ROM_EffectBlockCount: sprintf (cstrName, "ROM Effect Block Count"); break; + case kHIDUsage_PID_SimultaneousEffectsMax: sprintf (cstrName, "Simultaneous Effects Max"); break; + case kHIDUsage_PID_PoolAlignment: sprintf (cstrName, "Pool Alignment"); break; + + case kHIDUsage_PID_PoolMoveReport: sprintf (cstrName, "PID Pool Move Report"); break; + case kHIDUsage_PID_MoveSource: sprintf (cstrName, "Move Source"); break; + case kHIDUsage_PID_MoveDestination: sprintf (cstrName, "Move Destination"); break; + case kHIDUsage_PID_MoveLength: sprintf (cstrName, "Move Length"); break; + + case kHIDUsage_PID_BlockLoadReport: sprintf (cstrName, "PID Block Load Report"); break; + + case kHIDUsage_PID_BlockLoadStatus: sprintf (cstrName, "Block Load Status"); break; + case kHIDUsage_PID_BlockLoadSuccess: sprintf (cstrName, "Block Load Success"); break; + case kHIDUsage_PID_BlockLoadFull: sprintf (cstrName, "Block Load Full"); break; + case kHIDUsage_PID_BlockLoadError: sprintf (cstrName, "Block Load Error"); break; + case kHIDUsage_PID_BlockHandle: sprintf (cstrName, "Block Handle"); break; + + case kHIDUsage_PID_BlockFreeReport: sprintf (cstrName, "PID Block Free Report"); break; + + case kHIDUsage_PID_TypeSpecificBlockHandle: sprintf (cstrName, "Type Specific Block Handle"); break; + + case kHIDUsage_PID_StateReport: sprintf (cstrName, "PID State Report"); break; + case kHIDUsage_PID_EffectPlaying: sprintf (cstrName, "Effect Playing"); break; + + case kHIDUsage_PID_DeviceControlReport: sprintf (cstrName, "PID Device Control Report"); break; + + case kHIDUsage_PID_DeviceControl: sprintf (cstrName, "PID Device Control"); break; + case kHIDUsage_PID_DC_EnableActuators: sprintf (cstrName, "Device Control Enable Actuators"); break; + case kHIDUsage_PID_DC_DisableActuators: sprintf (cstrName, "Device Control Disable Actuators"); break; + case kHIDUsage_PID_DC_StopAllEffects: sprintf (cstrName, "Device Control Stop All Effects"); break; + case kHIDUsage_PID_DC_DeviceReset: sprintf (cstrName, "Device Control Reset"); break; + case kHIDUsage_PID_DC_DevicePause: sprintf (cstrName, "Device Control Pause"); break; + case kHIDUsage_PID_DC_DeviceContinue: sprintf (cstrName, "Device Control Continue"); break; + case kHIDUsage_PID_DevicePaused: sprintf (cstrName, "Device Paused"); break; + case kHIDUsage_PID_ActuatorsEnabled: sprintf (cstrName, "Actuators Enabled"); break; + case kHIDUsage_PID_SafetySwitch: sprintf (cstrName, "Safety Switch"); break; + case kHIDUsage_PID_ActuatorOverrideSwitch: sprintf (cstrName, "Actuator Override Switch"); break; + case kHIDUsage_PID_ActuatorPower: sprintf (cstrName, "Actuator Power"); break; + case kHIDUsage_PID_StartDelay: sprintf (cstrName, "Start Delay"); break; + + case kHIDUsage_PID_ParameterBlockSize: sprintf (cstrName, "Parameter Block Size"); break; + case kHIDUsage_PID_DeviceManagedPool: sprintf (cstrName, "Device Managed Pool"); break; + case kHIDUsage_PID_SharedParameterBlocks: sprintf (cstrName, "Shared Parameter Blocks"); break; + + case kHIDUsage_PID_CreateNewEffectReport: sprintf (cstrName, "Create New Effect Report"); break; + case kHIDUsage_PID_RAM_PoolAvailable: sprintf (cstrName, "RAM Pool Available"); break; + default: sprintf (cstrName, "PID Usage 0x%lx", element->usage); break; + } + break; + case kHIDPage_Unicode: + switch (element->usage) + { + default: sprintf (cstrName, "Unicode Usage 0x%lx", element->usage); break; + } + break; + case kHIDPage_PowerDevice: + if (((element->usage >= 0x06) && (element->usage <= 0x0F)) || ((element->usage >= 0x26) && (element->usage <= 0x2F)) || + ((element->usage >= 0x39) && (element->usage <= 0x3F)) || ((element->usage >= 0x48) && (element->usage <= 0x4F)) || + ((element->usage >= 0x58) && (element->usage <= 0x5F)) || (element->usage == 0x6A) || + ((element->usage >= 0x74) && (element->usage <= 0xFC))) + sprintf (cstrName, "Power Device Reserved"); + else + switch (element->usage) + { + case kHIDUsage_PD_Undefined: sprintf (cstrName, "Power Device Undefined Usage"); break; + case kHIDUsage_PD_iName: sprintf (cstrName, "Power Device Name Index"); break; + case kHIDUsage_PD_PresentStatus: sprintf (cstrName, "Power Device Present Status"); break; + case kHIDUsage_PD_ChangedStatus: sprintf (cstrName, "Power Device Changed Status"); break; + case kHIDUsage_PD_UPS: sprintf (cstrName, "Uninterruptible Power Supply"); break; + case kHIDUsage_PD_PowerSupply: sprintf (cstrName, "Power Supply"); break; + + case kHIDUsage_PD_BatterySystem: sprintf (cstrName, "Battery System Power Module"); break; + case kHIDUsage_PD_BatterySystemID: sprintf (cstrName, "Battery System ID"); break; + case kHIDUsage_PD_Battery: sprintf (cstrName, "Battery"); break; + case kHIDUsage_PD_BatteryID: sprintf (cstrName, "Battery ID"); break; + case kHIDUsage_PD_Charger: sprintf (cstrName, "Charger"); break; + case kHIDUsage_PD_ChargerID: sprintf (cstrName, "Charger ID"); break; + case kHIDUsage_PD_PowerConverter: sprintf (cstrName, "Power Converter Power Module"); break; + case kHIDUsage_PD_PowerConverterID: sprintf (cstrName, "Power Converter ID"); break; + case kHIDUsage_PD_OutletSystem: sprintf (cstrName, "Outlet System power module"); break; + case kHIDUsage_PD_OutletSystemID: sprintf (cstrName, "Outlet System ID"); break; + case kHIDUsage_PD_Input: sprintf (cstrName, "Power Device Input"); break; + case kHIDUsage_PD_InputID: sprintf (cstrName, "Power Device Input ID"); break; + case kHIDUsage_PD_Output: sprintf (cstrName, "Power Device Output"); break; + case kHIDUsage_PD_OutputID: sprintf (cstrName, "Power Device Output ID"); break; + case kHIDUsage_PD_Flow: sprintf (cstrName, "Power Device Flow"); break; + case kHIDUsage_PD_FlowID: sprintf (cstrName, "Power Device Flow ID"); break; + case kHIDUsage_PD_Outlet: sprintf (cstrName, "Power Device Outlet"); break; + case kHIDUsage_PD_OutletID: sprintf (cstrName, "Power Device Outlet ID"); break; + case kHIDUsage_PD_Gang: sprintf (cstrName, "Power Device Gang"); break; + case kHIDUsage_PD_GangID: sprintf (cstrName, "Power Device Gang ID"); break; + case kHIDUsage_PD_PowerSummary: sprintf (cstrName, "Power Device Power Summary"); break; + case kHIDUsage_PD_PowerSummaryID: sprintf (cstrName, "Power Device Power Summary ID"); break; + + case kHIDUsage_PD_Voltage: sprintf (cstrName, "Power Device Voltage"); break; + case kHIDUsage_PD_Current: sprintf (cstrName, "Power Device Current"); break; + case kHIDUsage_PD_Frequency: sprintf (cstrName, "Power Device Frequency"); break; + case kHIDUsage_PD_ApparentPower: sprintf (cstrName, "Power Device Apparent Power"); break; + case kHIDUsage_PD_ActivePower: sprintf (cstrName, "Power Device RMS Power"); break; + case kHIDUsage_PD_PercentLoad: sprintf (cstrName, "Power Device Percent Load"); break; + case kHIDUsage_PD_Temperature: sprintf (cstrName, "Power Device Temperature"); break; + case kHIDUsage_PD_Humidity: sprintf (cstrName, "Power Device Humidity"); break; + case kHIDUsage_PD_BadCount: sprintf (cstrName, "Power Device Bad Condition Count"); break; + + case kHIDUsage_PD_ConfigVoltage: sprintf (cstrName, "Power Device Nominal Voltage"); break; + case kHIDUsage_PD_ConfigCurrent: sprintf (cstrName, "Power Device Nominal Current"); break; + case kHIDUsage_PD_ConfigFrequency: sprintf (cstrName, "Power Device Nominal Frequency"); break; + case kHIDUsage_PD_ConfigApparentPower: sprintf (cstrName, "Power Device Nominal Apparent Power"); break; + case kHIDUsage_PD_ConfigActivePower: sprintf (cstrName, "Power Device Nominal RMS Power"); break; + case kHIDUsage_PD_ConfigPercentLoad: sprintf (cstrName, "Power Device Nominal Percent Load"); break; + case kHIDUsage_PD_ConfigTemperature: sprintf (cstrName, "Power Device Nominal Temperature"); break; + + case kHIDUsage_PD_ConfigHumidity: sprintf (cstrName, "Power Device Nominal Humidity"); break; + case kHIDUsage_PD_SwitchOnControl: sprintf (cstrName, "Power Device Switch On Control"); break; + case kHIDUsage_PD_SwitchOffControl: sprintf (cstrName, "Power Device Switch Off Control"); break; + case kHIDUsage_PD_ToggleControl: sprintf (cstrName, "Power Device Toogle Sequence Control"); break; + case kHIDUsage_PD_LowVoltageTransfer: sprintf (cstrName, "Power Device Min Transfer Voltage"); break; + case kHIDUsage_PD_HighVoltageTransfer: sprintf (cstrName, "Power Device Max Transfer Voltage"); break; + case kHIDUsage_PD_DelayBeforeReboot: sprintf (cstrName, "Power Device Delay Before Reboot"); break; + case kHIDUsage_PD_DelayBeforeStartup: sprintf (cstrName, "Power Device Delay Before Startup"); break; + case kHIDUsage_PD_DelayBeforeShutdown: sprintf (cstrName, "Power Device Delay Before Shutdown"); break; + case kHIDUsage_PD_Test: sprintf (cstrName, "Power Device Test Request/Result"); break; + case kHIDUsage_PD_ModuleReset: sprintf (cstrName, "Power Device Reset Request/Result"); break; + case kHIDUsage_PD_AudibleAlarmControl: sprintf (cstrName, "Power Device Audible Alarm Control"); break; + + case kHIDUsage_PD_Present: sprintf (cstrName, "Power Device Present"); break; + case kHIDUsage_PD_Good: sprintf (cstrName, "Power Device Good"); break; + case kHIDUsage_PD_InternalFailure: sprintf (cstrName, "Power Device Internal Failure"); break; + case kHIDUsage_PD_VoltageOutOfRange: sprintf (cstrName, "Power Device Voltage Out Of Range"); break; + case kHIDUsage_PD_FrequencyOutOfRange: sprintf (cstrName, "Power Device Frequency Out Of Range"); break; + case kHIDUsage_PD_Overload: sprintf (cstrName, "Power Device Overload"); break; + case kHIDUsage_PD_OverCharged: sprintf (cstrName, "Power Device Over Charged"); break; + case kHIDUsage_PD_OverTemperature: sprintf (cstrName, "Power Device Over Temperature"); break; + case kHIDUsage_PD_ShutdownRequested: sprintf (cstrName, "Power Device Shutdown Requested"); break; + + case kHIDUsage_PD_ShutdownImminent: sprintf (cstrName, "Power Device Shutdown Imminent"); break; + case kHIDUsage_PD_SwitchOnOff: sprintf (cstrName, "Power Device On/Off Switch Status"); break; + case kHIDUsage_PD_Switchable: sprintf (cstrName, "Power Device Switchable"); break; + case kHIDUsage_PD_Used: sprintf (cstrName, "Power Device Used"); break; + case kHIDUsage_PD_Boost: sprintf (cstrName, "Power Device Boosted"); break; + case kHIDUsage_PD_Buck: sprintf (cstrName, "Power Device Bucked"); break; + case kHIDUsage_PD_Initialized: sprintf (cstrName, "Power Device Initialized"); break; + case kHIDUsage_PD_Tested: sprintf (cstrName, "Power Device Tested"); break; + case kHIDUsage_PD_AwaitingPower: sprintf (cstrName, "Power Device Awaiting Power"); break; + case kHIDUsage_PD_CommunicationLost: sprintf (cstrName, "Power Device Communication Lost"); break; + + case kHIDUsage_PD_iManufacturer: sprintf (cstrName, "Power Device Manufacturer String Index"); break; + case kHIDUsage_PD_iProduct: sprintf (cstrName, "Power Device Product String Index"); break; + case kHIDUsage_PD_iserialNumber: sprintf (cstrName, "Power Device Serial Number String Index"); break; + default: sprintf (cstrName, "Power Device Usage 0x%lx", element->usage); break; + } + break; + case kHIDPage_BatterySystem: + if (((element->usage >= 0x0A) && (element->usage <= 0x0F)) || ((element->usage >= 0x1E) && (element->usage <= 0x27)) || + ((element->usage >= 0x30) && (element->usage <= 0x3F)) || ((element->usage >= 0x4C) && (element->usage <= 0x5F)) || + ((element->usage >= 0x6C) && (element->usage <= 0x7F)) || ((element->usage >= 0x90) && (element->usage <= 0xBF)) || + ((element->usage >= 0xC3) && (element->usage <= 0xCF)) || ((element->usage >= 0xDD) && (element->usage <= 0xEF)) || + ((element->usage >= 0xF2) && (element->usage <= 0xFF))) + sprintf (cstrName, "Power Device Reserved"); + else + switch (element->usage) + { + case kHIDUsage_BS_Undefined: sprintf (cstrName, "Battery System Undefined"); break; + case kHIDUsage_BS_SMBBatteryMode: sprintf (cstrName, "SMB Mode"); break; + case kHIDUsage_BS_SMBBatteryStatus: sprintf (cstrName, "SMB Status"); break; + case kHIDUsage_BS_SMBAlarmWarning: sprintf (cstrName, "SMB Alarm Warning"); break; + case kHIDUsage_BS_SMBChargerMode: sprintf (cstrName, "SMB Charger Mode"); break; + case kHIDUsage_BS_SMBChargerStatus: sprintf (cstrName, "SMB Charger Status"); break; + case kHIDUsage_BS_SMBChargerSpecInfo: sprintf (cstrName, "SMB Charger Extended Status"); break; + case kHIDUsage_BS_SMBSelectorState: sprintf (cstrName, "SMB Selector State"); break; + case kHIDUsage_BS_SMBSelectorPresets: sprintf (cstrName, "SMB Selector Presets"); break; + case kHIDUsage_BS_SMBSelectorInfo: sprintf (cstrName, "SMB Selector Info"); break; + case kHIDUsage_BS_OptionalMfgFunction1: sprintf (cstrName, "Battery System Optional SMB Mfg Function 1"); break; + case kHIDUsage_BS_OptionalMfgFunction2: sprintf (cstrName, "Battery System Optional SMB Mfg Function 2"); break; + case kHIDUsage_BS_OptionalMfgFunction3: sprintf (cstrName, "Battery System Optional SMB Mfg Function 3"); break; + case kHIDUsage_BS_OptionalMfgFunction4: sprintf (cstrName, "Battery System Optional SMB Mfg Function 4"); break; + case kHIDUsage_BS_OptionalMfgFunction5: sprintf (cstrName, "Battery System Optional SMB Mfg Function 5"); break; + case kHIDUsage_BS_ConnectionToSMBus: sprintf (cstrName, "Battery System Connection To System Management Bus"); break; + case kHIDUsage_BS_OutputConnection: sprintf (cstrName, "Battery System Output Connection Status"); break; + case kHIDUsage_BS_ChargerConnection: sprintf (cstrName, "Battery System Charger Connection"); break; + case kHIDUsage_BS_BatteryInsertion: sprintf (cstrName, "Battery System Battery Insertion"); break; + case kHIDUsage_BS_Usenext: sprintf (cstrName, "Battery System Use Next"); break; + case kHIDUsage_BS_OKToUse: sprintf (cstrName, "Battery System OK To Use"); break; + case kHIDUsage_BS_BatterySupported: sprintf (cstrName, "Battery System Battery Supported"); break; + case kHIDUsage_BS_SelectorRevision: sprintf (cstrName, "Battery System Selector Revision"); break; + case kHIDUsage_BS_ChargingIndicator: sprintf (cstrName, "Battery System Charging Indicator"); break; + case kHIDUsage_BS_ManufacturerAccess: sprintf (cstrName, "Battery System Manufacturer Access"); break; + case kHIDUsage_BS_RemainingCapacityLimit: sprintf (cstrName, "Battery System Remaining Capacity Limit"); break; + case kHIDUsage_BS_RemainingTimeLimit: sprintf (cstrName, "Battery System Remaining Time Limit"); break; + case kHIDUsage_BS_AtRate: sprintf (cstrName, "Battery System At Rate..."); break; + case kHIDUsage_BS_CapacityMode: sprintf (cstrName, "Battery System Capacity Mode"); break; + case kHIDUsage_BS_BroadcastToCharger: sprintf (cstrName, "Battery System Broadcast To Charger"); break; + case kHIDUsage_BS_PrimaryBattery: sprintf (cstrName, "Battery System Primary Battery"); break; + case kHIDUsage_BS_ChargeController: sprintf (cstrName, "Battery System Charge Controller"); break; + case kHIDUsage_BS_TerminateCharge: sprintf (cstrName, "Battery System Terminate Charge"); break; + case kHIDUsage_BS_TerminateDischarge: sprintf (cstrName, "Battery System Terminate Discharge"); break; + case kHIDUsage_BS_BelowRemainingCapacityLimit: sprintf (cstrName, "Battery System Below Remaining Capacity Limit"); break; + case kHIDUsage_BS_RemainingTimeLimitExpired: sprintf (cstrName, "Battery System Remaining Time Limit Expired"); break; + case kHIDUsage_BS_Charging: sprintf (cstrName, "Battery System Charging"); break; + case kHIDUsage_BS_Discharging: sprintf (cstrName, "Battery System Discharging"); break; + case kHIDUsage_BS_FullyCharged: sprintf (cstrName, "Battery System Fully Charged"); break; + case kHIDUsage_BS_FullyDischarged: sprintf (cstrName, "Battery System Fully Discharged"); break; + case kHIDUsage_BS_ConditioningFlag: sprintf (cstrName, "Battery System Conditioning Flag"); break; + case kHIDUsage_BS_AtRateOK: sprintf (cstrName, "Battery System At Rate OK"); break; + case kHIDUsage_BS_SMBErrorCode: sprintf (cstrName, "Battery System SMB Error Code"); break; + case kHIDUsage_BS_NeedReplacement: sprintf (cstrName, "Battery System Need Replacement"); break; + case kHIDUsage_BS_AtRateTimeToFull: sprintf (cstrName, "Battery System At Rate Time To Full"); break; + case kHIDUsage_BS_AtRateTimeToEmpty: sprintf (cstrName, "Battery System At Rate Time To Empty"); break; + case kHIDUsage_BS_AverageCurrent: sprintf (cstrName, "Battery System Average Current"); break; + case kHIDUsage_BS_Maxerror: sprintf (cstrName, "Battery System Max Error"); break; + case kHIDUsage_BS_RelativeStateOfCharge: sprintf (cstrName, "Battery System Relative State Of Charge"); break; + case kHIDUsage_BS_AbsoluteStateOfCharge: sprintf (cstrName, "Battery System Absolute State Of Charge"); break; + case kHIDUsage_BS_RemainingCapacity: sprintf (cstrName, "Battery System Remaining Capacity"); break; + case kHIDUsage_BS_FullChargeCapacity: sprintf (cstrName, "Battery System Full Charge Capacity"); break; + case kHIDUsage_BS_RunTimeToEmpty: sprintf (cstrName, "Battery System Run Time To Empty"); break; + case kHIDUsage_BS_AverageTimeToEmpty: sprintf (cstrName, "Battery System Average Time To Empty"); break; + case kHIDUsage_BS_AverageTimeToFull: sprintf (cstrName, "Battery System Average Time To Full"); break; + case kHIDUsage_BS_CycleCount: sprintf (cstrName, "Battery System Cycle Count"); break; + case kHIDUsage_BS_BattPackModelLevel: sprintf (cstrName, "Battery System Batt Pack Model Level"); break; + case kHIDUsage_BS_InternalChargeController: sprintf (cstrName, "Battery System Internal Charge Controller"); break; + case kHIDUsage_BS_PrimaryBatterySupport: sprintf (cstrName, "Battery System Primary Battery Support"); break; + case kHIDUsage_BS_DesignCapacity: sprintf (cstrName, "Battery System Design Capacity"); break; + case kHIDUsage_BS_SpecificationInfo: sprintf (cstrName, "Battery System Specification Info"); break; + case kHIDUsage_BS_ManufacturerDate: sprintf (cstrName, "Battery System Manufacturer Date"); break; + case kHIDUsage_BS_SerialNumber: sprintf (cstrName, "Battery System Serial Number"); break; + case kHIDUsage_BS_iManufacturerName: sprintf (cstrName, "Battery System Manufacturer Name Index"); break; + case kHIDUsage_BS_iDevicename: sprintf (cstrName, "Battery System Device Name Index"); break; + case kHIDUsage_BS_iDeviceChemistry: sprintf (cstrName, "Battery System Device Chemistry Index"); break; + case kHIDUsage_BS_ManufacturerData: sprintf (cstrName, "Battery System Manufacturer Data"); break; + case kHIDUsage_BS_Rechargable: sprintf (cstrName, "Battery System Rechargable"); break; + case kHIDUsage_BS_WarningCapacityLimit: sprintf (cstrName, "Battery System Warning Capacity Limit"); break; + case kHIDUsage_BS_CapacityGranularity1: sprintf (cstrName, "Battery System Capacity Granularity 1"); break; + case kHIDUsage_BS_CapacityGranularity2: sprintf (cstrName, "Battery System Capacity Granularity 2"); break; + case kHIDUsage_BS_iOEMInformation: sprintf (cstrName, "Battery System OEM Information Index"); break; + case kHIDUsage_BS_InhibitCharge: sprintf (cstrName, "Battery System Inhibit Charge"); break; + case kHIDUsage_BS_EnablePolling: sprintf (cstrName, "Battery System Enable Polling"); break; + case kHIDUsage_BS_ResetToZero: sprintf (cstrName, "Battery System Reset To Zero"); break; + case kHIDUsage_BS_ACPresent: sprintf (cstrName, "Battery System AC Present"); break; + case kHIDUsage_BS_BatteryPresent: sprintf (cstrName, "Battery System Battery Present"); break; + case kHIDUsage_BS_PowerFail: sprintf (cstrName, "Battery System Power Fail"); break; + case kHIDUsage_BS_AlarmInhibited: sprintf (cstrName, "Battery System Alarm Inhibited"); break; + case kHIDUsage_BS_ThermistorUnderRange: sprintf (cstrName, "Battery System Thermistor Under Range"); break; + case kHIDUsage_BS_ThermistorHot: sprintf (cstrName, "Battery System Thermistor Hot"); break; + case kHIDUsage_BS_ThermistorCold: sprintf (cstrName, "Battery System Thermistor Cold"); break; + case kHIDUsage_BS_ThermistorOverRange: sprintf (cstrName, "Battery System Thermistor Over Range"); break; + case kHIDUsage_BS_VoltageOutOfRange: sprintf (cstrName, "Battery System Voltage Out Of Range"); break; + case kHIDUsage_BS_CurrentOutOfRange: sprintf (cstrName, "Battery System Current Out Of Range"); break; + case kHIDUsage_BS_CurrentNotRegulated: sprintf (cstrName, "Battery System Current Not Regulated"); break; + case kHIDUsage_BS_VoltageNotRegulated: sprintf (cstrName, "Battery System Voltage Not Regulated"); break; + case kHIDUsage_BS_MasterMode: sprintf (cstrName, "Battery System Master Mode"); break; + case kHIDUsage_BS_ChargerSelectorSupport: sprintf (cstrName, "Battery System Charger Support Selector"); break; + case kHIDUsage_BS_ChargerSpec: sprintf (cstrName, "attery System Charger Specification"); break; + case kHIDUsage_BS_Level2: sprintf (cstrName, "Battery System Charger Level 2"); break; + case kHIDUsage_BS_Level3: sprintf (cstrName, "Battery System Charger Level 3"); break; + default: sprintf (cstrName, "Battery System Usage 0x%lx", element->usage); break; + } + break; + case kHIDPage_AlphanumericDisplay: + switch (element->usage) + { + default: sprintf (cstrName, "Alphanumeric Display Usage 0x%lx", element->usage); break; + } + break; + case kHIDPage_BarCodeScanner: + switch (element->usage) + { + default: sprintf (cstrName, "Bar Code Scanner Usage 0x%lx", element->usage); break; + } + break; + case kHIDPage_Scale: + switch (element->usage) + { + default: sprintf (cstrName, "Scale Usage 0x%lx", element->usage); break; + } + break; + case kHIDPage_CameraControl: + switch (element->usage) + { + default: sprintf (cstrName, "Camera Control Usage 0x%lx", element->usage); break; + } + break; + case kHIDPage_Arcade: + switch (element->usage) + { + default: sprintf (cstrName, "Arcade Usage 0x%lx", element->usage); break; + } + break; + default: + if (element->usagePage > kHIDPage_VendorDefinedStart) + sprintf (cstrName, "Vendor Defined Usage 0x%lx", element->usage); + else + sprintf (cstrName, "Page: 0x%lx, Usage: 0x%lx", element->usagePage, element->usage); + break; + } + + return(cstrName); +} + + #endif /* #ifdef __APPLE__ */ -- cgit v1.2.1