// ************************************************************************* // // IOHIDElement_SetupCalibration(inIOHIDElementRef) // // Purpose: set default values for the element calibration parameters // // Inputs: inIOHIDElementRef - the IOHIDElementRef for this element // // Returns: nothing // void IOHIDElement_SetupCalibration(IOHIDElementRef inIOHIDElementRef) { // these are the min/max values returned by IOHIDValueGetScaledValue(v, kIOHIDValueScaleTypeCalibrated); IOHIDElement_SetCalibrationMin(inIOHIDElementRef, IOHIDElementGetLogicalMin(inIOHIDElementRef)); IOHIDElement_SetCalibrationMax(inIOHIDElementRef, IOHIDElementGetLogicalMax(inIOHIDElementRef)); CFIndex phyMin = IOHIDElementGetPhysicalMin(inIOHIDElementRef); CFIndex phyMax = IOHIDElementGetPhysicalMax(inIOHIDElementRef); CFIndex phyRange = phyMax - phyMin; // calculate the middle physical value we would expect from this element double phyMid = (phyMin + phyMax) / 2.f; // this is the granularity of the values returned by IOHIDValueGetScaledValue(v, kIOHIDValueScaleTypeCalibrated); // for example if set to 0.1 the values returned will be multiples of 0.1 (0.1, 0.2, 0.3, etc.) IOHIDElement_SetCalibrationGranularity(inIOHIDElementRef, 0.); Boolean isRelative = IOHIDElementIsRelative(inIOHIDElementRef); Boolean hasPreferredState = IOHIDElementHasPreferredState(inIOHIDElementRef); // define the dead zone (like in the middle of joystick axis) if (!isRelative && hasPreferredState && (phyRange > 3)) { IOHIDElement_SetCalibrationDeadZoneMin(inIOHIDElementRef, phyMid - 1.0); IOHIDElement_SetCalibrationDeadZoneMax(inIOHIDElementRef, phyMid + 1.0); } else { IOHIDElement_SetCalibrationDeadZoneMin(inIOHIDElementRef, 0.); IOHIDElement_SetCalibrationDeadZoneMax(inIOHIDElementRef, 0.); } // get the current value of this element double phyValue = IOHIDElement_GetValue(inIOHIDElementRef, kIOHIDValueScaleTypePhysical); #if true // use that that value to determine the min/max saturation values used for calibration IOHIDElement_SetCalibrationSaturationMin(inIOHIDElementRef, phyValue); IOHIDElement_SetCalibrationSaturationMax(inIOHIDElementRef, phyValue); #else // if 1 #if true // this value determines the min/max values that have been recieved from the device element IOHIDElement_SetCalibrationSaturationMin(inIOHIDElementRef, (phyMin + phyMid) / 2.f); IOHIDElement_SetCalibrationSaturationMax(inIOHIDElementRef, (phyMid + phyMax) / 2.f); #else // if 1 // use it as our min/max saturation // this value determines the min/max values that have been recieved from the device element IOHIDElement_SetCalibrationSaturationMin(inIOHIDElementRef, phyMid); IOHIDElement_SetCalibrationSaturationMax(inIOHIDElementRef, phyMid); #endif // if 1 // and the current value to adjust the current saturation values if it's outside their range if (phyValue < IOHIDElement_GetCalibrationSaturationMin(inIOHIDElementRef)) { IOHIDElement_SetCalibrationSaturationMin(inIOHIDElementRef, phyValue); } if (phyValue > IOHIDElement_GetCalibrationSaturationMax(inIOHIDElementRef)) { IOHIDElement_SetCalibrationSaturationMax(inIOHIDElementRef, phyValue); } #endif // if 1 } // IOHIDElement_SetupCalibration
//************************************************************************* // // IOHIDElement_SetupCalibration( inElementRef ) // // Purpose: set default values for the element calibration parameters // // Inputs: inElementRef - the IOHIDElementRef for this element // // Returns: nothing // void IOHIDElement_SetupCalibration( IOHIDElementRef inIOHIDElementRef ) { // these are the min/max values returned by IOHIDValueGetScaledValue( v, kIOHIDValueScaleTypeCalibrated ); IOHIDElement_SetCalibrationMin( inIOHIDElementRef, IOHIDElementGetLogicalMin( inIOHIDElementRef ) ); IOHIDElement_SetCalibrationMax( inIOHIDElementRef, IOHIDElementGetLogicalMax( inIOHIDElementRef ) ); // this is the granularity of the values returned by IOHIDValueGetScaledValue( v, kIOHIDValueScaleTypeCalibrated ); // for example if set to 0.1 the values returned will be multiples of 0.1 ( 0.1, 0.2, 0.3, etc. ) IOHIDElement_SetCalibrationGranularity( inIOHIDElementRef, 0. ); // these define the dead zone (like in the middel of joystick axis) IOHIDElement_SetCalibrationDeadZoneMin( inIOHIDElementRef, 0 ); IOHIDElement_SetCalibrationDeadZoneMax( inIOHIDElementRef, 0 ); #if 1 // get the current value of this element double value = IOHIDElement_GetValue( inIOHIDElementRef, kIOHIDValueScaleTypePhysical ); // use it as our min/mas saturation IOHIDElement_SetCalibrationSaturationMin( inIOHIDElementRef, value ); IOHIDElement_SetCalibrationSaturationMax( inIOHIDElementRef, value ); #else // calculate the middle physical value we would expect from this element CFIndex valueMin = IOHIDElementGetPhysicalMin( inIOHIDElementRef ); CFIndex valueMax = IOHIDElementGetPhysicalMax( inIOHIDElementRef ); CFIndex valueMid = ( valueMin + valueMax ) / 2; // use it as our min/mas saturation // this value determines the min/max values that have been recieved from the device element IOHIDElement_SetCalibrationSaturationMin( inIOHIDElementRef, valueMid ); IOHIDElement_SetCalibrationSaturationMax( inIOHIDElementRef, valueMid ); // get the current value of this element double value = IOHIDElement_GetValue( inIOHIDElementRef, kIOHIDValueScaleTypePhysical ); // and use it to adjust the current saturation values if it's outside their range if ( value < IOHIDElement_GetCalibrationSaturationMin( inIOHIDElementRef ) ) { IOHIDElement_SetCalibrationSaturationMin( inIOHIDElementRef, value ); } if ( value > IOHIDElement_GetCalibrationSaturationMax( inIOHIDElementRef ) ) { IOHIDElement_SetCalibrationSaturationMax( inIOHIDElementRef, value ); } #endif } // IOHIDElement_SetupCalibration
// Get matching element from config record // takes a pre-allocated and filled out config record // search for matching device // return IOHIDDeviceRef, IOHIDElementRef and cookie for action IOHIDElementCookie HIDGetElementConfig(HID_info_ptr inHIDInfoPtr, IOHIDDeviceRef * outIOHIDDeviceRef, IOHIDElementRef *outIOHIDElementRef) { if (!inHIDInfoPtr->device.locID && !inHIDInfoPtr->device.vendorID && !inHIDInfoPtr->device.productID && !inHIDInfoPtr->device.usage && !inHIDInfoPtr->device.usagePage) // { // // early out *outIOHIDDeviceRef = NULL; *outIOHIDElementRef = NULL; return (inHIDInfoPtr->actionCookie); } IOHIDDeviceRef tIOHIDDeviceRef = NULL, foundIOHIDDeviceRef = NULL; IOHIDElementRef tIOHIDElementRef = NULL, foundIOHIDElementRef = NULL; CFIndex devIdx, devCnt, idx, cnt; // compare to current device list for matches // look for device if (inHIDInfoPtr->device.locID && inHIDInfoPtr->device.vendorID && inHIDInfoPtr->device.productID) // look for specific { // device // type plug in to same // port devCnt = CFArrayGetCount(gDeviceCFArrayRef); for (devIdx = 0; devIdx < devCnt; devIdx++) { tIOHIDDeviceRef = (IOHIDDeviceRef) CFArrayGetValueAtIndex(gDeviceCFArrayRef, devIdx); if (!tIOHIDDeviceRef) { continue; // skip this device } uint32_t locID = IOHIDDevice_GetLocationID(tIOHIDDeviceRef); uint32_t vendorID = IOHIDDevice_GetVendorID(tIOHIDDeviceRef); uint32_t productID = IOHIDDevice_GetProductID(tIOHIDDeviceRef); if ((inHIDInfoPtr->device.locID == locID) && (inHIDInfoPtr->device.vendorID == vendorID) && (inHIDInfoPtr->device.productID == productID)) { foundIOHIDDeviceRef = tIOHIDDeviceRef; } if (foundIOHIDDeviceRef) { break; } } // next devIdx if (foundIOHIDDeviceRef) { CFArrayRef elementCFArrayRef = IOHIDDeviceCopyMatchingElements(foundIOHIDDeviceRef, NULL, kIOHIDOptionsTypeNone); if (elementCFArrayRef) { cnt = CFArrayGetCount(elementCFArrayRef); for (idx = 0; idx < cnt; idx++) { tIOHIDElementRef = (IOHIDElementRef) CFArrayGetValueAtIndex(elementCFArrayRef, idx); if (!tIOHIDElementRef) { continue; // skip this element } IOHIDElementCookie cookie = IOHIDElementGetCookie(tIOHIDElementRef); if (inHIDInfoPtr->element.cookie == cookie) { foundIOHIDElementRef = tIOHIDElementRef; } if (foundIOHIDElementRef) { break; } } if (!foundIOHIDElementRef) { cnt = CFArrayGetCount(elementCFArrayRef); for (idx = 0; idx < cnt; idx++) { tIOHIDElementRef = (IOHIDElementRef) CFArrayGetValueAtIndex(elementCFArrayRef, idx); if (!tIOHIDElementRef) { continue; // skip this element } uint32_t usagePage = IOHIDElementGetUsagePage(tIOHIDElementRef); uint32_t usage = IOHIDElementGetUsage(tIOHIDElementRef); if ((inHIDInfoPtr->element.usage == usage) && (inHIDInfoPtr->element.usagePage == usagePage)) { foundIOHIDElementRef = tIOHIDElementRef; } if (foundIOHIDElementRef) { break; } } // next idx } // if (!foundIOHIDElementRef) if (foundIOHIDElementRef) { // if same device // setup the calibration IOHIDElement_SetupCalibration(tIOHIDElementRef); IOHIDElement_SetCalibrationSaturationMin(tIOHIDElementRef, inHIDInfoPtr->element.minReport); IOHIDElement_SetCalibrationSaturationMax(tIOHIDElementRef, inHIDInfoPtr->element.maxReport); } CFRelease(elementCFArrayRef); } // if (elementCFArrayRef) } // if (foundIOHIDDeviceRef) // if we have not found a match, look at just vendor // and product if ((!foundIOHIDDeviceRef) && (inHIDInfoPtr->device.vendorID && inHIDInfoPtr->device.productID)) { devCnt = CFArrayGetCount(gDeviceCFArrayRef); for (devIdx = 0; devIdx < devCnt; devIdx++) { tIOHIDDeviceRef = (IOHIDDeviceRef) CFArrayGetValueAtIndex(gDeviceCFArrayRef, devIdx); if (!tIOHIDDeviceRef) { continue; // skip this device } uint32_t vendorID = IOHIDDevice_GetVendorID(tIOHIDDeviceRef); uint32_t productID = IOHIDDevice_GetProductID(tIOHIDDeviceRef); if ((inHIDInfoPtr->device.vendorID == vendorID) && (inHIDInfoPtr->device.productID == productID)) { foundIOHIDDeviceRef = tIOHIDDeviceRef; } if (foundIOHIDDeviceRef) { break; } } // match elements by cookie since same device type if (foundIOHIDDeviceRef) { CFArrayRef elementCFArrayRef = IOHIDDeviceCopyMatchingElements(foundIOHIDDeviceRef, NULL, kIOHIDOptionsTypeNone); if (elementCFArrayRef) { cnt = CFArrayGetCount(elementCFArrayRef); for (idx = 0; idx < cnt; idx++) { tIOHIDElementRef = (IOHIDElementRef) CFArrayGetValueAtIndex(elementCFArrayRef, idx); if (!tIOHIDElementRef) { continue; // skip this element } IOHIDElementCookie cookie = IOHIDElementGetCookie(tIOHIDElementRef); if (inHIDInfoPtr->element.cookie == cookie) { foundIOHIDElementRef = tIOHIDElementRef; } if (foundIOHIDElementRef) { break; } } // if no cookie match (should NOT occur) match on usage if (!foundIOHIDElementRef) { cnt = CFArrayGetCount(elementCFArrayRef); for (idx = 0; idx < cnt; idx++) { tIOHIDElementRef = (IOHIDElementRef) CFArrayGetValueAtIndex(elementCFArrayRef, idx); if (!tIOHIDElementRef) { continue; // skip this element } uint32_t usagePage = IOHIDElementGetUsagePage(tIOHIDElementRef); uint32_t usage = IOHIDElementGetUsage(tIOHIDElementRef); if ((inHIDInfoPtr->element.usage == usage) && (inHIDInfoPtr->element.usagePage == usagePage)) { foundIOHIDElementRef = tIOHIDElementRef; } if (foundIOHIDElementRef) { break; } } // next idx } // if (!foundIOHIDElementRef) if (foundIOHIDElementRef) { // if same device // setup the calibration IOHIDElement_SetupCalibration(tIOHIDElementRef); IOHIDElement_SetCalibrationSaturationMin(tIOHIDElementRef, inHIDInfoPtr->element.minReport); IOHIDElement_SetCalibrationSaturationMax(tIOHIDElementRef, inHIDInfoPtr->element.maxReport); } CFRelease(elementCFArrayRef); } // if (elementCFArrayRef) } // if (foundIOHIDDeviceRef) } // if (device not found & vendorID & productID) } // if (inHIDInfoPtr->locID && // inHIDInfoPtr->device.vendorID && // inHIDInfoPtr->device.productID) // can't find matching device return NULL, do not // return first device if ((!foundIOHIDDeviceRef) || (!foundIOHIDElementRef)) { // no HID device *outIOHIDDeviceRef = NULL; *outIOHIDElementRef = NULL; return (inHIDInfoPtr->actionCookie); } else { // HID device *outIOHIDDeviceRef = foundIOHIDDeviceRef; *outIOHIDElementRef = foundIOHIDElementRef; return (inHIDInfoPtr->actionCookie); } } // HIDGetElementConfig