// utility routine to dump element info void HIDDumpElementInfo(IOHIDElementRef inIOHIDElementRef) { if (inIOHIDElementRef) { printf(" Element: %p = { ", inIOHIDElementRef); #if false IOHIDDeviceRef tIOHIDDeviceRef = IOHIDElementGetDevice(inIOHIDElementRef); printf("Device: %p, ", tIOHIDDeviceRef); #endif // if 0 IOHIDElementRef parentIOHIDElementRef = IOHIDElementGetParent(inIOHIDElementRef); printf("parent: %p, ", parentIOHIDElementRef); #if false CFArrayRef childrenCFArrayRef = IOHIDElementGetChildren(inIOHIDElementRef); printf("children: %p: { ", childrenCFArrayRef); fflush(stdout); CFShow(childrenCFArrayRef); fflush(stdout); printf(" }, "); #endif // if 0 IOHIDElementCookie tIOHIDElementCookie = IOHIDElementGetCookie(inIOHIDElementRef); printf("cookie: 0x%08lX, ", (long unsigned int) tIOHIDElementCookie); IOHIDElementType tIOHIDElementType = IOHIDElementGetType(inIOHIDElementRef); switch (tIOHIDElementType) { case kIOHIDElementTypeInput_Misc: { printf("type: Misc, "); break; } case kIOHIDElementTypeInput_Button: { printf("type: Button, "); break; } case kIOHIDElementTypeInput_Axis: { printf("type: Axis, "); break; } case kIOHIDElementTypeInput_ScanCodes: { printf("type: ScanCodes, "); break; } case kIOHIDElementTypeOutput: { printf("type: Output, "); break; } case kIOHIDElementTypeFeature: { printf("type: Feature, "); break; } case kIOHIDElementTypeCollection: { IOHIDElementCollectionType tIOHIDElementCollectionType = IOHIDElementGetCollectionType(inIOHIDElementRef); switch (tIOHIDElementCollectionType) { case kIOHIDElementCollectionTypePhysical: { printf("type: Physical Collection, "); break; } case kIOHIDElementCollectionTypeApplication: { printf("type: Application Collection, "); break; } case kIOHIDElementCollectionTypeLogical: { printf("type: Logical Collection, "); break; } case kIOHIDElementCollectionTypeReport: { printf("type: Report Collection, "); break; } case kIOHIDElementCollectionTypeNamedArray: { printf("type: Named Array Collection, "); break; } case kIOHIDElementCollectionTypeUsageSwitch: { printf("type: Usage Switch Collection, "); break; } case kIOHIDElementCollectionTypeUsageModifier: { printf("type: Usage Modifier Collection, "); break; } default: { printf("type: %p Collection, ", (void *) tIOHIDElementCollectionType); break; } } // switch break; } default: { printf("type: %p, ", (void *) tIOHIDElementType); break; } } /* switch */ uint32_t usagePage = IOHIDElementGetUsagePage(inIOHIDElementRef); uint32_t usage = IOHIDElementGetUsage(inIOHIDElementRef); printf("usage: 0x%04lX:0x%04lX, ", (long unsigned int) usagePage, (long unsigned int) usage); CFStringRef tCFStringRef = HIDCopyUsageName(usagePage, usage); if (tCFStringRef) { char usageString[256] = ""; (void) CFStringGetCString(tCFStringRef, usageString, sizeof(usageString), kCFStringEncodingUTF8); printf("\"%s\", ", usageString); CFRelease(tCFStringRef); } CFStringRef nameCFStringRef = IOHIDElementGetName(inIOHIDElementRef); char buffer[256]; if ( nameCFStringRef && CFStringGetCString(nameCFStringRef, buffer, sizeof(buffer), kCFStringEncodingUTF8) ) { printf("name: %s, ", buffer); } uint32_t reportID = IOHIDElementGetReportID(inIOHIDElementRef); uint32_t reportSize = IOHIDElementGetReportSize(inIOHIDElementRef); uint32_t reportCount = IOHIDElementGetReportCount(inIOHIDElementRef); printf("report: { ID: %lu, Size: %lu, Count: %lu }, ", (long unsigned int) reportID, (long unsigned int) reportSize, (long unsigned int) reportCount); uint32_t unit = IOHIDElementGetUnit(inIOHIDElementRef); uint32_t unitExp = IOHIDElementGetUnitExponent(inIOHIDElementRef); if (unit || unitExp) { printf("unit: %lu * 10^%lu, ", (long unsigned int) unit, (long unsigned int) unitExp); } CFIndex logicalMin = IOHIDElementGetLogicalMin(inIOHIDElementRef); CFIndex logicalMax = IOHIDElementGetLogicalMax(inIOHIDElementRef); if (logicalMin != logicalMax) { printf("logical: {min: %ld, max: %ld}, ", logicalMin, logicalMax); } CFIndex physicalMin = IOHIDElementGetPhysicalMin(inIOHIDElementRef); CFIndex physicalMax = IOHIDElementGetPhysicalMax(inIOHIDElementRef); if (physicalMin != physicalMax) { printf("physical: {min: %ld, max: %ld}, ", physicalMin, physicalMax); } Boolean isVirtual = IOHIDElementIsVirtual(inIOHIDElementRef); if (isVirtual) { printf("isVirtual, "); } Boolean isRelative = IOHIDElementIsRelative(inIOHIDElementRef); if (isRelative) { printf("isRelative, "); } Boolean isWrapping = IOHIDElementIsWrapping(inIOHIDElementRef); if (isWrapping) { printf("isWrapping, "); } Boolean isArray = IOHIDElementIsArray(inIOHIDElementRef); if (isArray) { printf("isArray, "); } Boolean isNonLinear = IOHIDElementIsNonLinear(inIOHIDElementRef); if (isNonLinear) { printf("isNonLinear, "); } Boolean hasPreferredState = IOHIDElementHasPreferredState(inIOHIDElementRef); if (hasPreferredState) { printf("hasPreferredState, "); } Boolean hasNullState = IOHIDElementHasNullState(inIOHIDElementRef); if (hasNullState) { printf("hasNullState, "); } printf(" }\n"); } } // HIDDumpElementInfo
// utility routine to dump device info void HIDDumpDeviceInfo(IOHIDDeviceRef inIOHIDDeviceRef) { char cstring[256]; printf("Device: %p = { ", inIOHIDDeviceRef); char manufacturer[256] = ""; // name of manufacturer CFStringRef tCFStringRef = IOHIDDevice_GetManufacturer(inIOHIDDeviceRef); if (tCFStringRef) { (void) CFStringGetCString(tCFStringRef, manufacturer, sizeof(manufacturer), kCFStringEncodingUTF8); } char product[256] = ""; // name of product tCFStringRef = IOHIDDevice_GetProduct(inIOHIDDeviceRef); if (tCFStringRef) { (void) CFStringGetCString(tCFStringRef, product, sizeof(product), kCFStringEncodingUTF8); } printf("%s - %s, ", manufacturer, product); long vendorID = IOHIDDevice_GetVendorID(inIOHIDDeviceRef); if (vendorID) { if ( HIDGetVendorNameFromVendorID(vendorID, cstring) ) { printf(" vendorID: 0x%04lX (\"%s\"), ", vendorID, cstring); } else { printf(" vendorID: 0x%04lX, ", vendorID); } } long productID = IOHIDDevice_GetProductID(inIOHIDDeviceRef); if (productID) { if ( HIDGetProductNameFromVendorProductID(vendorID, productID, cstring) ) { printf(" productID: 0x%04lX (\"%s\"), ", productID, cstring); } else { printf(" productID: 0x%04lX, ", productID); } } uint32_t usagePage = IOHIDDevice_GetUsagePage(inIOHIDDeviceRef); uint32_t usage = IOHIDDevice_GetUsage(inIOHIDDeviceRef); if (!usagePage || !usage) { usagePage = IOHIDDevice_GetPrimaryUsagePage(inIOHIDDeviceRef); usage = IOHIDDevice_GetPrimaryUsage(inIOHIDDeviceRef); } printf("usage: 0x%04lX:0x%04lX, ", (long unsigned int) usagePage, (long unsigned int) usage); tCFStringRef = HIDCopyUsageName(usagePage, usage); if (tCFStringRef) { (void) CFStringGetCString(tCFStringRef, cstring, sizeof(cstring), kCFStringEncodingUTF8); printf("\"%s\", ", cstring); CFRelease(tCFStringRef); } tCFStringRef = IOHIDDevice_GetTransport(inIOHIDDeviceRef); if (tCFStringRef) { (void) CFStringGetCString(tCFStringRef, cstring, sizeof(cstring), kCFStringEncodingUTF8); printf("Transport: \"%s\", ", cstring); } long vendorIDSource = IOHIDDevice_GetVendorIDSource(inIOHIDDeviceRef); if (vendorIDSource) { printf("VendorIDSource: %ld, ", vendorIDSource); } long version = IOHIDDevice_GetVersionNumber(inIOHIDDeviceRef); if (version) { printf("version: %ld, ", version); } tCFStringRef = IOHIDDevice_GetSerialNumber(inIOHIDDeviceRef); if (tCFStringRef) { (void) CFStringGetCString(tCFStringRef, cstring, sizeof(cstring), kCFStringEncodingUTF8); printf("SerialNumber: \"%s\", ", cstring); } long country = IOHIDDevice_GetCountryCode(inIOHIDDeviceRef); if (country) { printf("CountryCode: %ld, ", country); } long locationID = IOHIDDevice_GetLocationID(inIOHIDDeviceRef); if (locationID) { printf("locationID: 0x%08lX, ", locationID); } #if false CFArrayRef pairs = IOHIDDevice_GetUsagePairs(inIOHIDDeviceRef); if (pairs) { CFIndex idx, cnt = CFArrayGetCount(pairs); for (idx = 0; idx < cnt; idx++) { const void * pair = CFArrayGetValueAtIndex(pairs, idx); CFShow(pair); } } #endif // if false long maxInputReportSize = IOHIDDevice_GetMaxInputReportSize(inIOHIDDeviceRef); if (maxInputReportSize) { printf("MaxInputReportSize: %ld, ", maxInputReportSize); } long maxOutputReportSize = IOHIDDevice_GetMaxOutputReportSize(inIOHIDDeviceRef); if (maxOutputReportSize) { printf("MaxOutputReportSize: %ld, ", maxOutputReportSize); } long maxFeatureReportSize = IOHIDDevice_GetMaxFeatureReportSize(inIOHIDDeviceRef); if (maxFeatureReportSize) { printf("MaxFeatureReportSize: %ld, ", maxOutputReportSize); } long reportInterval = IOHIDDevice_GetReportInterval(inIOHIDDeviceRef); if (reportInterval) { printf("ReportInterval: %ld, ", reportInterval); } IOHIDQueueRef queueRef = IOHIDDevice_GetQueue(inIOHIDDeviceRef); if (queueRef) { printf("queue: %p, ", queueRef); } IOHIDTransactionRef transactionRef = IOHIDDevice_GetTransaction(inIOHIDDeviceRef); if (transactionRef) { printf("transaction: %p, ", transactionRef); } printf("}\n"); fflush(stdout); } // HIDDumpDeviceInfo
/************************************************************************* * * hu_AddDeviceElementToUsageXML( inDevice, inElement ) * * Purpose: add a device and it's elements to our usage( XML ) file * * Inputs: inDevice - the device * inElement - the element * * Returns: Boolean - if successful */ static Boolean hu_AddDeviceElementToUsageXML(IOHIDDeviceRef inIOHIDDeviceRef, IOHIDElementRef inIOHIDElementRef) { Boolean results = FALSE; if ( gUsageCFPropertyListRef ) { CFRelease(gUsageCFPropertyListRef); } gUsageCFPropertyListRef = hu_XMLLoad( CFSTR( "HID_device_usage_strings"), CFSTR("plist") ); if ( gUsageCFPropertyListRef ) { CFMutableDictionaryRef tCFMutableDictionaryRef = CFDictionaryCreateMutableCopy( kCFAllocatorDefault, 0, gUsageCFPropertyListRef); if ( tCFMutableDictionaryRef ) { CFMutableDictionaryRef vendorCFMutableDictionaryRef; CFMutableDictionaryRef productCFMutableDictionaryRef; CFStringRef productKeyCFStringRef; CFStringRef usageKeyCFStringRef; // if the vendor dictionary exists... long vendorID = IOHIDDevice_GetVendorID(inIOHIDDeviceRef); CFStringRef vendorKeyCFStringRef = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%ld"), vendorID); if ( vendorKeyCFStringRef ) { if ( CFDictionaryGetValueIfPresent(tCFMutableDictionaryRef, vendorKeyCFStringRef, (const void **) &vendorCFMutableDictionaryRef) ) { // ...copy it... vendorCFMutableDictionaryRef = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, vendorCFMutableDictionaryRef); } else { // ...otherwise... // ...create it. vendorCFMutableDictionaryRef = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); results = TRUE; } // if the vendor name key doesn't exist... if ( !CFDictionaryContainsKey(vendorCFMutableDictionaryRef, kNameKeyCFStringRef) ) { CFStringRef manCFStringRef = IOHIDDevice_GetManufacturer(inIOHIDDeviceRef); // ...create it. CFDictionaryAddValue(vendorCFMutableDictionaryRef, kNameKeyCFStringRef, manCFStringRef); results = TRUE; } // if the product key exists in the vendor dictionary... long productID = IOHIDDevice_GetProductID(inIOHIDDeviceRef); productKeyCFStringRef = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%ld"), productID); if ( CFDictionaryGetValueIfPresent(vendorCFMutableDictionaryRef, productKeyCFStringRef, (const void **) &productCFMutableDictionaryRef) ) { // ...copy it... productCFMutableDictionaryRef = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, productCFMutableDictionaryRef); } else { // ...otherwise... // ...create it. productCFMutableDictionaryRef = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); results = TRUE; } // if the product name key doesn't exist... if ( !CFDictionaryContainsKey(productCFMutableDictionaryRef, kNameKeyCFStringRef) ) { CFStringRef productCFStringRef = IOHIDDevice_GetProduct(inIOHIDDeviceRef); // ...create it. CFDictionaryAddValue(productCFMutableDictionaryRef, kNameKeyCFStringRef, productCFStringRef); results = TRUE; } // if the usage key doesn't exist in the product dictionary... uint32_t usagePage = IOHIDElementGetUsagePage(inIOHIDElementRef); uint32_t usage = IOHIDElementGetUsagePage(inIOHIDElementRef); usageKeyCFStringRef = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%ld:%ld"), usagePage, usage); if ( usageKeyCFStringRef ) { if ( !CFDictionaryContainsKey(productCFMutableDictionaryRef, usageKeyCFStringRef) ) { // find it's generic name CFStringRef usageCFStringRef = HIDCopyUsageName(usagePage, usage); if ( usageCFStringRef ) { // and add that. CFDictionaryAddValue(productCFMutableDictionaryRef, usageKeyCFStringRef, usageCFStringRef); results = TRUE; CFRelease(usageCFStringRef); } } CFRelease(usageKeyCFStringRef); } if ( vendorCFMutableDictionaryRef ) { if ( productCFMutableDictionaryRef ) { if ( results ) { CFDictionarySetValue(vendorCFMutableDictionaryRef, productKeyCFStringRef, productCFMutableDictionaryRef); } CFRelease(productCFMutableDictionaryRef); } if ( results ) { CFDictionarySetValue(tCFMutableDictionaryRef, vendorKeyCFStringRef, vendorCFMutableDictionaryRef); } CFRelease(vendorCFMutableDictionaryRef); } CFRelease(vendorKeyCFStringRef); } if ( productKeyCFStringRef ) { CFRelease(productKeyCFStringRef); } if ( results ) { hu_XMLSave( tCFMutableDictionaryRef, CFSTR( "HID_device_usage_strings"), CFSTR("plist") ); } CFRelease( tCFMutableDictionaryRef); } } return (results); } // hu_AddDeviceElementToUsageXML