Added GUIDs for Bluetooth devices, using the same algorithm as the Linux code.

Reformatted the code so it was easier to step through using gdb.
This commit is contained in:
Sam Lantinga 2013-03-25 11:38:30 -07:00
parent 8718681e49
commit abfb78058f

View file

@ -463,98 +463,92 @@ HIDGetDeviceInfo(io_object_t hidDevice, CFMutableDictionaryRef hidProperties,
/* Mac OS X currently is not mirroring all USB properties to HID page so need to look at USB device page also /* Mac OS X currently is not mirroring all USB properties to HID page so need to look at USB device page also
* get dictionary for usb properties: step up two levels and get CF dictionary for USB properties * get dictionary for usb properties: step up two levels and get CF dictionary for USB properties
*/ */
if ((KERN_SUCCESS == if ((KERN_SUCCESS == IORegistryEntryGetParentEntry(hidDevice, kIOServicePlane, &parent1))
IORegistryEntryGetParentEntry(hidDevice, kIOServicePlane, &parent1)) && (KERN_SUCCESS == IORegistryEntryGetParentEntry(parent1, kIOServicePlane, &parent2))
&& (KERN_SUCCESS == && (KERN_SUCCESS == IORegistryEntryCreateCFProperties(parent2, &usbProperties, kCFAllocatorDefault, kNilOptions))) {
IORegistryEntryGetParentEntry(parent1, kIOServicePlane, &parent2))
&& (KERN_SUCCESS ==
IORegistryEntryCreateCFProperties(parent2, &usbProperties,
kCFAllocatorDefault,
kNilOptions))) {
if (usbProperties) { if (usbProperties) {
CFTypeRef refCF = 0; CFTypeRef refCF = 0;
/* get device info /* get device info
* try hid dictionary first, if fail then go to usb dictionary * try hid dictionary first, if fail then go to usb dictionary
*/ */
/* get product name */ /* get product name */
refCF = refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDProductKey));
CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDProductKey)); if (!refCF) {
if (!refCF) refCF = CFDictionaryGetValue(usbProperties, CFSTR("USB Product Name"));
refCF = }
CFDictionaryGetValue(usbProperties,
CFSTR("USB Product Name"));
if (refCF) { if (refCF) {
if (!CFStringGetCString if (!CFStringGetCString(refCF, pDevice->product, 256, CFStringGetSystemEncoding())) {
(refCF, pDevice->product, 256, SDL_SetError("CFStringGetCString error retrieving pDevice->product.");
CFStringGetSystemEncoding())) }
SDL_SetError
("CFStringGetCString error retrieving pDevice->product.");
} }
/* get usage page and usage */ /* get usage page and usage */
refCF = refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDPrimaryUsagePageKey));
CFDictionaryGetValue(hidProperties,
CFSTR(kIOHIDPrimaryUsagePageKey));
if (refCF) { if (refCF) {
if (!CFNumberGetValue if (!CFNumberGetValue (refCF, kCFNumberLongType, &pDevice->usagePage)) {
(refCF, kCFNumberLongType, &pDevice->usagePage)) SDL_SetError("CFNumberGetValue error retrieving pDevice->usagePage.");
SDL_SetError
("CFNumberGetValue error retrieving pDevice->usagePage.");
refCF =
CFDictionaryGetValue(hidProperties,
CFSTR(kIOHIDPrimaryUsageKey));
if (refCF)
if (!CFNumberGetValue
(refCF, kCFNumberLongType, &pDevice->usage))
SDL_SetError
("CFNumberGetValue error retrieving pDevice->usage.");
} }
refCF = refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDPrimaryUsageKey));
CFDictionaryGetValue(hidProperties,
CFSTR(kIOHIDVendorIDKey));
if (refCF) { if (refCF) {
if (!CFNumberGetValue if (!CFNumberGetValue (refCF, kCFNumberLongType, &pDevice->usage)) {
(refCF, kCFNumberLongType, &pDevice->guid.data[0])) SDL_SetError("CFNumberGetValue error retrieving pDevice->usage.");
SDL_SetError }
("CFNumberGetValue error retrieving pDevice->guid.");
} }
refCF =
CFDictionaryGetValue(hidProperties,
CFSTR(kIOHIDProductIDKey));
if (refCF) {
if (!CFNumberGetValue
(refCF, kCFNumberLongType, &pDevice->guid.data[8]))
SDL_SetError
("CFNumberGetValue error retrieving pDevice->guid[8].");
} }
refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDVendorIDKey));
if (refCF) {
if (!CFNumberGetValue(refCF, kCFNumberLongType, &pDevice->guid.data[0])) {
SDL_SetError("CFNumberGetValue error retrieving pDevice->guid[0]");
}
}
refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDProductIDKey));
if (refCF) {
if (!CFNumberGetValue(refCF, kCFNumberLongType, &pDevice->guid.data[8])) {
SDL_SetError("CFNumberGetValue error retrieving pDevice->guid[8]");
}
}
/* Check to make sure we have a vendor and product ID
If we don't, use the same algorithm as the Linux code for Bluetooth devices */
{
Uint32 *guid32 = (Uint32*)pDevice->guid.data;
if (!guid32[0] && !guid32[1]) {
const Uint16 BUS_BLUETOOTH = 0x05;
Uint16 *guid16 = (Uint16 *)guid32;
*guid16++ = BUS_BLUETOOTH;
*guid16++ = 0;
SDL_strlcpy((char*)guid16, pDevice->product, sizeof(pDevice->guid.data) - 4);
}
}
/* If we don't have a vendor and product ID this is probably a Bluetooth device */
if (NULL == refCF) { /* get top level element HID usage page or usage */ if (NULL == refCF) { /* get top level element HID usage page or usage */
/* use top level element instead */ /* use top level element instead */
CFTypeRef refCFTopElement = 0; CFTypeRef refCFTopElement = 0;
refCFTopElement = refCFTopElement = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDElementKey));
CFDictionaryGetValue(hidProperties,
CFSTR(kIOHIDElementKey));
{ {
/* refCFTopElement points to an array of element dictionaries */ /* refCFTopElement points to an array of element dictionaries */
CFRange range = { 0, CFArrayGetCount(refCFTopElement) }; CFRange range = { 0, CFArrayGetCount(refCFTopElement) };
CFArrayApplyFunction(refCFTopElement, range, CFArrayApplyFunction(refCFTopElement, range, HIDTopLevelElementHandler, pDevice);
HIDTopLevelElementHandler, pDevice);
} }
} }
CFRelease(usbProperties); CFRelease(usbProperties);
} else } else {
SDL_SetError SDL_SetError("IORegistryEntryCreateCFProperties failed to create usbProperties.");
("IORegistryEntryCreateCFProperties failed to create usbProperties."); }
if (kIOReturnSuccess != IOObjectRelease(parent2)) if (kIOReturnSuccess != IOObjectRelease(parent2)) {
SDL_SetError("IOObjectRelease error with parent2."); SDL_SetError("IOObjectRelease error with parent2");
if (kIOReturnSuccess != IOObjectRelease(parent1)) }
SDL_SetError("IOObjectRelease error with parent1."); if (kIOReturnSuccess != IOObjectRelease(parent1)) {
SDL_SetError("IOObjectRelease error with parent1");
}
} }
} }
@ -1100,4 +1094,5 @@ SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick *joystick)
} }
#endif /* SDL_JOYSTICK_IOKIT */ #endif /* SDL_JOYSTICK_IOKIT */
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */