Sample Code
OSX Driver and Kext Samples/ HID_Utilities/ HID_Utilities/ build/ Release/ HID Utilities.framework/ Versions/ A/ Headers/ HID_Utilities_External.h/
// File: HID_Utilities_External.h //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // Abstract: External interface for HID Utilities, can be used with either library or source. //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // Version: 2.0 //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // Inc. ("Apple") in consideration of your agreement to the following //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // terms, and your use, installation, modification or redistribution of //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // this Apple software constitutes acceptance of these terms. If you do //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // not agree with these terms, please do not use, install, modify or //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // redistribute this Apple software. //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // In consideration of your agreement to abide by the following terms, and //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // subject to these terms, Apple grants you a personal, non-exclusive //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // license, under Apple's copyrights in this original Apple software (the //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // "Apple Software"), to use, reproduce, modify and redistribute the Apple //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // Software, with or without modifications, in source and/or binary forms; //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // provided that if you redistribute the Apple Software in its entirety and //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // without modifications, you must retain this notice and the following //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // text and disclaimers in all such redistributions of the Apple Software. //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // Neither the name, trademarks, service marks or logos of Apple Inc. may //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // be used to endorse or promote products derived from the Apple Software //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // without specific prior written permission from Apple. Except as //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // expressly stated in this notice, no other rights or licenses, express or //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // implied, are granted by Apple herein, including but not limited to any //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // patent rights that may be infringed by your derivative works or by other //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // works in which the Apple Software may be incorporated. //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // The Apple Software is provided by Apple on an "AS IS" basis. APPLE //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // POSSIBILITY OF SUCH DAMAGE. //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // Copyright (C) 2009 Apple Inc. All Rights Reserved. //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_ // //***************************************************** #ifndef _HID_Utilities_External_h_ #define _HID_Utilities_External_h_ // ================================== #ifdef __cplusplus extern "C" { #endif // ================================== //includes #include <stdio.h> #include "IOHIDLib_.h" // ================================== #ifndef _IOKIT_HID_IOHIDKEYS_H_ /*! @typedef IOHIDElementCookie @abstract Abstract data type used as a unique identifier for an element. */ #ifdef __LP64__ typedef uint32_t IOHIDElementCookie; #else typedef void *IOHIDElementCookie; #endif #endif // Device and Element Interfaces enum HIDElementTypeMask { kHIDElementTypeInput = 1 << 1, kHIDElementTypeOutput = 1 << 2, kHIDElementTypeFeature = 1 << 3, kHIDElementTypeCollection = 1 << 4, kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature, kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection }; typedef enum HIDElementTypeMask HIDElementTypeMask; // ================================== //***************************************************** #pragma mark - exported globals //----------------------------------------------------- extern IOHIDManagerRef gIOHIDManagerRef; extern CFMutableArrayRef gDeviceCFArrayRef; extern CFArrayRef gElementCFArrayRef; //************************************************************************* // // HIDBuildMultiDeviceList( inUsagePages, inUsages, inNumDeviceTypes ) // // Purpose: builds list of devices with elements (allocates memory and captures devices) in which // the devices could be of different types/usages list is allocated internally within HID // Utilites and can be accessed via accessor functions structures within list are considered // flat and user accessable, but not user modifiable can be called again to rebuild list to // account for new devices (will do the right thing in case of disposing existing list) // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if succesful // // Inputs: inUsagePages - inNumDeviceTypes sized array of matching usage pages // inUsages - inNumDeviceTypes sized array of matching usages // inNumDeviceTypes - number of usage pages & usages // // Returns: Boolean - if successful // extern Boolean HIDBuildMultiDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // same as above but this uses a single usagePage and usage extern Boolean HIDBuildDeviceList(UInt32 usagePage, UInt32 usage); // updates the current device list for any new/removed devices // if this is called before HIDBuildDeviceList the it functions like HIDBuildMultiDeviceList // usagePage, usage are each a numDeviceTypes sized array of matching usage and usage pages // returns true if successful which means if any device were added or removed (the device config changed) extern Boolean HIDUpdateDeviceList(const UInt32 *inUsagePages, const UInt32 *inUsages, int inNumDeviceTypes); // release list built by above function // MUST be called prior to application exit to properly release devices // if not called (or app crashes) devices can be recovered by pluging into different location in USB chain extern void HIDReleaseDeviceList(void); //************************************************************************* // // HIDRebuildDevices( ) // // Purpose: rebuilds the (internal) list of devices // // Inputs: none // // Returns: none // extern void HIDRebuildDevices(void); // does a device list exist extern unsigned char HIDHaveDeviceList(void); // how many HID devices have been found // returns 0 if no device list exist extern UInt32 HIDCountDevices(void); // how many elements does a specific device have // returns 0 if device is invalid or NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern UInt32 HIDCountDeviceElements(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get the first device in the device list // returns NULL if no list exists extern IOHIDDeviceRef HIDGetFirstDevice(void); // get next device in list given current device as parameter // returns NULL if end of list extern IOHIDDeviceRef HIDGetNextDevice(IOHIDDeviceRef inIOHIDDeviceRef); // get the first element of device passed in as parameter // returns NULL if no list exists or device does not exists or is NULL // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetFirstDeviceElement functionality extern IOHIDElementRef HIDGetFirstDeviceElement(IOHIDDeviceRef inIOHIDDeviceRef, HIDElementTypeMask typeMask); // get next element of given device in list given current element as parameter // will walk down each collection then to next element or collection (depthwise traverse) // returns NULL if end of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get previous HIDGetNextDeviceElement functionality extern IOHIDElementRef HIDGetNextDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // get previous element of given device in list given current element as parameter // this walks directly up the tree to the top element and does not search at each level // returns NULL if beginning of list // uses mask of HIDElementTypeMask to restrict element found // use kHIDElementTypeIO to get non-collection elements extern IOHIDElementRef HIDGetPreviousDeviceElement(IOHIDElementRef inIOHidElementRef, HIDElementTypeMask typeMask); // returns C string type name given a type enumeration passed in as parameter( see IOHIDKeys.h ) // returns empty string for invalid types extern void HIDGetTypeName(IOHIDElementType inIOHIDElementType, char *outCStrName); //************************************************************************* // // HIDCopyUsageName( inUsagePage, inUsage ) // // Purpose: return a CFStringRef string for a given usage page & usage( see IOUSBHIDParser.h ) // // Notes: returns usage page and usage values in CFString form for unknown values // // Inputs: inUsagePage - the usage page // inUsage - the usage // // Returns: CFStringRef - the resultant string // extern CFStringRef HIDCopyUsageName(long inUsagePage, long inUsage); // ================================== // Element Event Queue and Value Interfaces enum { kDefaultUserMin = 0, // default user min and max used for scaling kDefaultUserMax = 255 }; enum { kDeviceQueueSize = 50 // this is wired kernel memory so should be set to as small as possible // but should account for the maximum possible events in the queue // USB updates will likely occur at 100 Hz so one must account for this rate of // if states change quickly (updates are only posted on state changes) }; // ================================== // queues specific element, performing any device queue set up required extern int HIDQueueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // adds all elements to queue, performing any device queue set up required extern int HIDQueueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // removes element for queue, if last element in queue will release queue and device extern int HIDDequeueElement(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef); // completely removes all elements from queue and releases queue and device extern int HIDDequeueDevice(IOHIDDeviceRef inIOHIDDeviceRef); // releases all device queues for quit or rebuild (must be called) extern int HIDReleaseAllDeviceQueues(void); // returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise // pHIDEvent is a poiner to a IOHIDEventStruct, using void here for compatibility, users can cast a required extern unsigned char HIDGetEvent(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDValueRef *pIOHIDValueRef); // ================================== // Conguration and Save Interfaces enum { kPercentMove = 10 // precent of overall range a element must move to register }; typedef struct HID_info_struct { int actionCookie; // device // need to add serial number when I have a test case struct { int vendorID, productID; int locID; uint32_t usagePage, usage; } device; // elements struct { uint32_t usagePage, usage; int minReport, maxReport; IOHIDElementCookie cookie; // always 32 bits } element; }HID_info_rec, *HID_info_ptr; // get vendor name from vendor ID extern Boolean HIDGetVendorNameFromVendorID(long inVendorID, char *outCStrName); // get product name from vendor/product ID extern Boolean HIDGetProductNameFromVendorProductID(long inVendorID, long inProductID, char *outCStrName); // get element name from vendor id/product id look up ( using element cookie ) extern Boolean HIDGetElementNameFromVendorProductCookie(int inVendorID, int inProductID, IOHIDElementCookie inCookie, char * outCStrName); // get element name from vendor id/product id look up ( using element usage page & usage ) extern Boolean HIDGetElementNameFromVendorProductUsage(long inVendorID, long inProductID, long inUsagePage, long inUsage, char *inCStrName); // utility routines to dump device or element info extern void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef); extern void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef); extern void HIDDumpElementCalibrationInfo(IOHIDElementRef inIOHIDElementRef); // polls single device's elements for a change greater than kPercentMove. Times out after given time // returns 1 and pointer to element if found // returns 0 and NULL for both parameters if not found extern unsigned char HIDConfigureSingleDeviceAction(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef, float timeout); //************************************************************************* // // HIDConfigureAction( outDeviceRef, outElementRef, inTimeout ) // // Purpose: polls all devices and elements for a change greater than kPercentMove. // Times out after given time returns 1 and pointer to device and element // if found; returns 0 and NULL for both parameters if not found // // Inputs: outDeviceRef - address where to store the device // outElementRef - address where to store the element // inTimeout - the timeout // Returns: Boolean - TRUE if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDConfigureAction(IOHIDDeviceRef *outDeviceRef, IOHIDElementRef *outElementRef, float inTimeout); //************************************************************************* // // HIDSaveElementPref( inKeyCFStringRef, inAppCFStringRef, inDeviceRef, inElementRef ) // // Purpose: Save the device & element values into the specified key in the specified applications preferences // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // inDeviceRef - the device // inElementRef - the element // Returns: Boolean - if successful // extern Boolean HIDSaveElementPref(const CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef inDeviceRef, IOHIDElementRef inElementRef); //************************************************************************* // // HIDRestoreElementPref( inKeyCFStringRef, inAppCFStringRef, outDeviceRef, outElementRef ) // // Purpose: Find the specified preference in the specified application // // Inputs: inKeyCFStringRef - the preference key // inAppCFStringRef - the application identifier // outDeviceRef - address where to restore the device // outElementRef - address where to restore the element // Returns: Boolean - if successful // outDeviceRef - the device // outElementRef - the element // extern Boolean HIDRestoreElementPref(CFStringRef inKeyCFStringRef, CFStringRef inAppCFStringRef, IOHIDDeviceRef * outDeviceRef, IOHIDElementRef *outElementRef); //************************************************************************* // // HIDFindDeviceAndElement( inSearchInfo, outFoundDevice, outFoundElement ) // // Purpose: find the closest matching device and element for this action // // Notes: matches device: serial, vendorID, productID, location, inUsagePage, usage // matches element: cookie, inUsagePage, usage, // // Inputs: inSearchInfo - the device & element info we searching for // outFoundDevice - the address of the best matching device // outFoundElement - the address of the best matching element // // Returns: Boolean - TRUE if we find a match // outFoundDevice - the best matching device // outFoundElement - the best matching element // extern Boolean HIDFindDeviceAndElement(const HID_info_rec *inSearchInfo, IOHIDDeviceRef * outFoundDevice, IOHIDElementRef * outFoundElement); // -- These are routines to use if the applcationwants HID Utilities to do the file handling -- // Note: the FILE * is a MachO posix FILE and will not likely work directly with MW MSL FILE * type. // take input records, save required info // assume file is open and at correct position. void HIDSaveElementConfig(FILE *fileRef, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // takes a file, reads one record (assume file position is correct and file is open) // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDRestoreElementConfig(FILE *fileRef, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // -- These are routines to use if the client wants to use their own file handling -- // Set up a config record for saving // takes an input records, returns record user can save as they want // Note: the save rec must be pre-allocated by the calling app and will be filled out void HIDSetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHidElementRef, int actionCookie); // Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return tIOHIDDeviceRef, tIOHIDElementRef and cookie for action int HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef *outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef); // ================================== // Error reporter, can be set to report however the application desires extern void HIDReportError(const char *strError); // Error with numeric code reporter, can be set to report however the application desires extern void HIDReportErrorNum(const char *strError, int numError); #ifdef __cplusplus } #endif #endif // _HID_Utilities_External_h_
Our Services
-
What our customers say about us?
Read our customer testimonials to find out why our clients keep returning for their projects.
View Testimonials