Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
HID Support/HID_Config_Utilities.c
/* |
* HID_Config_Utilities.c |
* HID Config Save |
* |
* Created by ggs on Thu May 24 2001. |
* Copyright (c) 2001 Apple. All rights reserved. |
* |
*/ |
#include <stdlib.h> // malloc |
#include <time.h> // clock |
#include "HID_Utilities_Internal.h" |
#include "HID_Utilities_External.h" |
// --------------------------------- |
// 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 |
unsigned char HIDConfigureSingleDeviceAction (pRecDevice pDevice, pRecElement * ppElement, float timeout) |
{ |
unsigned long maxElements = 0; |
long * saveValueArray; |
pRecElement pElement = NULL; |
unsigned char found = 0, done = 0; |
clock_t start = clock (), end; |
unsigned long i; |
if (!pDevice) |
return 0; |
if (0 == HIDHaveDeviceList ()) // if we do not have a device list |
return 0; // return 0 |
// build list of device and elements to save current values |
maxElements = HIDCountDeviceElements (pDevice, kHIDElementTypeIO); |
saveValueArray = (long *) malloc (sizeof (long) * maxElements); // 2D array to save values |
for (i = 0; i <maxElements; i++) // clear array |
*(saveValueArray + i) = 0x00000000; |
// store current values |
short elementNum = 0; |
pElement = HIDGetFirstDeviceElement (pDevice, kHIDElementTypeIO); |
while (pElement) |
{ |
*(saveValueArray + elementNum) = HIDGetElementValue (pDevice, pElement); |
pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO); |
elementNum++; |
} |
// poll all devices and elements, compare current value to save +/- kPercentMove |
while ((!found) && (!done)) |
{ |
double secs; |
// are we done? |
end = clock(); |
secs = (double)(end - start) / CLOCKS_PER_SEC; |
if (secs > timeout) |
done = 1; |
short elementNum = 0; |
pElement = HIDGetFirstDeviceElement (pDevice, kHIDElementTypeIO); |
while (pElement) |
{ |
long initialValue = *(saveValueArray + elementNum); |
long value = HIDGetElementValue (pDevice, pElement); |
long delta = (float)(pElement->max - pElement->min) * kPercentMove * 0.01; |
if (((initialValue + delta) < value) || ((initialValue - delta) > value)) { |
found = 1; |
break; |
} |
pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO); |
elementNum++; |
} |
} |
// return device and element moved |
if (found) { |
*ppElement = pElement; |
return 1; |
} else { |
*ppElement = NULL; |
return 0; |
} |
} |
// --------------------------------- |
// 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 |
unsigned char HIDConfigureAction (pRecDevice * ppDevice, pRecElement * ppElement, float timeout) |
{ |
unsigned long devices, maxElements = 0; |
long * saveValueArray; |
pRecDevice pDevice = NULL; |
pRecElement pElement = NULL; |
short deviceNum = 0; |
unsigned char found = 0, done = 0; |
clock_t start = clock (), end; |
unsigned long i; |
if (0 == HIDHaveDeviceList ()) // if we do not have a device list |
if (0 == HIDBuildDeviceList (0, 0)) // if we could not build anorther list (use generic usage and page) |
return 0; // return 0 |
// build list of device and elements to save current values |
devices = HIDCountDevices (); |
pDevice = HIDGetFirstDevice (); |
while (pDevice) |
{ |
if (HIDCountDeviceElements (pDevice, kHIDElementTypeIO) > maxElements) |
maxElements = HIDCountDeviceElements (pDevice, kHIDElementTypeIO); |
pDevice = HIDGetNextDevice (pDevice); |
} |
saveValueArray = (long *) malloc (sizeof (long) * devices * maxElements); // 2D array to save values |
for (i = 0; i < devices * maxElements; i++) // clear array |
*(saveValueArray + i) = 0x00000000; |
// store current values |
deviceNum = 0; |
pDevice = HIDGetFirstDevice (); |
while (pDevice) |
{ |
short elementNum = 0; |
pElement = HIDGetFirstDeviceElement (pDevice, kHIDElementTypeIO); |
while (pElement) |
{ |
*(saveValueArray + (deviceNum * maxElements) + elementNum) = HIDGetElementValue (pDevice, pElement); |
pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO); |
elementNum++; |
} |
pDevice = HIDGetNextDevice (pDevice); |
deviceNum++; |
} |
// poll all devices and elements, compare current value to save +/- kPercentMove |
while ((!found) && (!done)) |
{ |
double secs; |
// are we done? |
end = clock(); |
secs = (double)(end - start) / CLOCKS_PER_SEC; |
if (secs > timeout) |
done = 1; |
deviceNum = 0; |
pDevice = HIDGetFirstDevice (); |
while (pDevice) |
{ |
short elementNum = 0; |
pElement = HIDGetFirstDeviceElement (pDevice, kHIDElementTypeIO); |
while (pElement) |
{ |
long initialValue = *(saveValueArray + (deviceNum * maxElements) + elementNum); |
long value = HIDGetElementValue (pDevice, pElement); |
long delta = (float)(pElement->max - pElement->min) * kPercentMove * 0.01; |
if (((initialValue + delta) < value) || ((initialValue - delta) > value)) |
{ |
found = 1; |
break; |
} |
pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO); |
elementNum++; |
} |
if (found) |
break; |
pDevice = HIDGetNextDevice (pDevice); |
deviceNum++; |
} |
} |
// return device and element moved |
if (found) |
{ |
*ppDevice = pDevice; |
*ppElement = pElement; |
return 1; |
} |
else |
{ |
*ppDevice = NULL; |
*ppElement = NULL; |
return 0; |
} |
} |
// --------------------------------- |
// takes input records, save required info |
// assume file is open and at correct position. |
// will always write to file (if file exists) size of recSaveHID, even if device and or element is bad |
void HIDSaveElementConfig (FILE * fileRef, pRecDevice pDevice, pRecElement pElement, long actionCookie) |
{ |
// must save: |
// actionCookie |
// Device: serial,vendorID, productID, location, usagePage, usage |
// Element: cookie, usagePage, usage, |
recSaveHID saveRec; |
HIDSetElementConfig (&saveRec, pDevice, pElement, actionCookie); |
// write to file |
if (fileRef) |
fwrite ((void *)&saveRec, sizeof (recSaveHID), 1, fileRef); |
} |
// --------------------------------- |
// take file, read one record (assume file position is correct and file is open) |
// search for matching device |
// return pDevice, pElement and cookie for action |
long HIDRestoreElementConfig (FILE * fileRef, pRecDevice * ppDevice, pRecElement * ppElement) |
{ |
// Device: serial,vendorID, productID, location, usagePage, usage |
// Element: cookie, usagePage, usage, |
recSaveHID restoreRec; |
fread ((void *) &restoreRec, 1, sizeof (recSaveHID), fileRef); |
return HIDGetElementConfig (&restoreRec, ppDevice, ppElement); |
} |
// --------------------------------- |
// 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 (pRecSaveHID pConfigRec, pRecDevice pDevice, pRecElement pElement, long actionCookie) |
{ |
// must save: |
// actionCookie |
// Device: serial,vendorID, productID, location, usagePage, usage |
// Element: cookie, usagePage, usage, |
pConfigRec->actionCookie = actionCookie; |
// device |
// need to add serial number when I have a test case |
if (pDevice && pElement) { |
pConfigRec->vendorID = pDevice->vendorID; |
pConfigRec->productID = pDevice->productID; |
pConfigRec->locID = pDevice->locID; |
pConfigRec->usage = pDevice->usage; |
pConfigRec->usagePage = pDevice->usagePage; |
pConfigRec->usagePageE = pElement->usagePage; |
pConfigRec->usageE = pElement->usage; |
pConfigRec->minReport = pElement->minReport; |
pConfigRec->maxReport = pElement->maxReport; |
pConfigRec->cookie = pElement->cookie; |
} else { |
pConfigRec->vendorID = 0; |
pConfigRec->productID = 0; |
pConfigRec->locID = 0; |
pConfigRec->usage = 0; |
pConfigRec->usagePage = 0; |
pConfigRec->usagePageE = 0; |
pConfigRec->usageE = 0; |
pConfigRec->minReport = 0; |
pConfigRec->maxReport = 0; |
pConfigRec->cookie = 0; |
} |
} |
// --------------------------------- |
#if 0 |
void HIDDumpConfig (pRecSaveHID pConfigRec) |
{ |
printf ("Config Record for action: %ld\n vendor: %ld product: %ld location: %ld\n usage: %ld usagePage: %ld\n usagePageE: %ld usageE: %ld\n minReport: %ld maxReport: %ld\n cookie: %ld\n", pConfigRec->actionCookie, pConfigRec->vendorID, pConfigRec->productID, pConfigRec->locID, pConfigRec->usage, pConfigRec->usagePage, pConfigRec->usagePageE, pConfigRec->usageE, pConfigRec->minReport, pConfigRec->maxReport, pConfigRec->cookie); |
} |
#endif // 0 |
// --------------------------------- |
// Get matching element from config record |
// takes a pre-allocated and filled out config record |
// search for matching device |
// return pDevice, pElement and cookie for action |
long HIDGetElementConfig (pRecSaveHID pConfigRec, pRecDevice * ppDevice, pRecElement * ppElement) |
{ |
if (!pConfigRec->locID && !pConfigRec->vendorID && !pConfigRec->productID && !pConfigRec->usage && !pConfigRec->usagePage) { // early out |
*ppDevice = NULL; |
*ppElement = NULL; |
return pConfigRec->actionCookie; |
} |
pRecDevice pDevice, pFoundDevice = NULL; |
pRecElement pElement, pFoundElement = NULL; |
// compare to current device list for matches |
// look for device |
if (pConfigRec->locID && pConfigRec->vendorID && pConfigRec->productID) |
{ // look for specific device type plug in to same port |
pDevice = HIDGetFirstDevice (); |
while (pDevice) |
{ |
if ((pConfigRec->locID == pDevice->locID) && |
(pConfigRec->vendorID == pDevice->vendorID) && |
(pConfigRec->productID == pDevice->productID)) |
pFoundDevice = pDevice; |
if (pFoundDevice) |
break; |
pDevice = HIDGetNextDevice (pDevice); |
} |
if (pFoundDevice) |
{ |
pElement = HIDGetFirstDeviceElement (pFoundDevice, kHIDElementTypeIO); |
while (pElement) |
{ |
if (pConfigRec->cookie == pElement->cookie) |
pFoundElement = pElement; |
if (pFoundElement) |
break; |
pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO); |
} |
// if no cookie match (should NOT occur) match on usage |
pElement = HIDGetFirstDeviceElement (pFoundDevice, kHIDElementTypeIO); |
while (pElement) |
{ |
if ((pConfigRec->usageE == pElement->usage) && |
(pConfigRec->usagePageE == pElement->usagePage)) |
pFoundElement = pElement; |
if (pFoundElement) |
break; |
pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO); |
} |
if (pElement) { |
// set min and max values if same device |
pElement->minReport = pConfigRec->minReport; |
pElement->maxReport = pConfigRec->maxReport; |
} |
} |
} |
// if we have not found a match, look at just vendor and product |
if ((NULL == pFoundDevice) && (pConfigRec->vendorID && pConfigRec->productID)) |
{ |
pDevice = HIDGetFirstDevice (); |
while (pDevice) |
{ |
if ((pConfigRec->vendorID == pDevice->vendorID) && |
(pConfigRec->productID == pDevice->productID)) |
pFoundDevice = pDevice; |
if (pFoundDevice) |
break; |
pDevice = HIDGetNextDevice (pDevice); |
} |
// match elements by cookie since same device type |
if (pFoundDevice) |
{ |
pElement = HIDGetFirstDeviceElement (pFoundDevice, kHIDElementTypeIO); |
while (pElement) |
{ |
if (pConfigRec->cookie == pElement->cookie) |
pFoundElement = pElement; |
if (pFoundElement) |
break; |
pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO); |
} |
// if no cookie match (should NOT occur) match on usage |
pElement = HIDGetFirstDeviceElement (pFoundDevice, kHIDElementTypeIO); |
while (pElement) |
{ |
if ((pConfigRec->usageE == pElement->usage) && |
(pConfigRec->usagePageE == pElement->usagePage)) |
pFoundElement = pElement; |
if (pFoundElement) |
break; |
pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO); |
} |
if (pElement) { |
// set min and max values if same device |
pElement->minReport = pConfigRec->minReport; |
pElement->maxReport = pConfigRec->maxReport; |
} |
} |
} |
// can't find matching device return NULL, do not return first device |
if ((NULL == pFoundDevice) || (NULL == pFoundElement)) |
{ |
// no HID device |
*ppDevice = NULL; |
*ppElement = NULL; |
return pConfigRec->actionCookie; |
} |
else |
{ |
// HID device |
*ppDevice = pFoundDevice; |
*ppElement = pFoundElement; |
return pConfigRec->actionCookie; |
} |
} |
Copyright © 2004 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2004-03-26