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:
parent
8718681e49
commit
abfb78058f
1 changed files with 60 additions and 65 deletions
|
@ -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
|
||||
* get dictionary for usb properties: step up two levels and get CF dictionary for USB properties
|
||||
*/
|
||||
if ((KERN_SUCCESS ==
|
||||
IORegistryEntryGetParentEntry(hidDevice, kIOServicePlane, &parent1))
|
||||
&& (KERN_SUCCESS ==
|
||||
IORegistryEntryGetParentEntry(parent1, kIOServicePlane, &parent2))
|
||||
&& (KERN_SUCCESS ==
|
||||
IORegistryEntryCreateCFProperties(parent2, &usbProperties,
|
||||
kCFAllocatorDefault,
|
||||
kNilOptions))) {
|
||||
if ((KERN_SUCCESS == IORegistryEntryGetParentEntry(hidDevice, kIOServicePlane, &parent1))
|
||||
&& (KERN_SUCCESS == IORegistryEntryGetParentEntry(parent1, kIOServicePlane, &parent2))
|
||||
&& (KERN_SUCCESS == IORegistryEntryCreateCFProperties(parent2, &usbProperties, kCFAllocatorDefault, kNilOptions))) {
|
||||
if (usbProperties) {
|
||||
CFTypeRef refCF = 0;
|
||||
/* get device info
|
||||
* try hid dictionary first, if fail then go to usb dictionary
|
||||
*/
|
||||
|
||||
|
||||
/* get product name */
|
||||
refCF =
|
||||
CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDProductKey));
|
||||
if (!refCF)
|
||||
refCF =
|
||||
CFDictionaryGetValue(usbProperties,
|
||||
CFSTR("USB Product Name"));
|
||||
refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDProductKey));
|
||||
if (!refCF) {
|
||||
refCF = CFDictionaryGetValue(usbProperties, CFSTR("USB Product Name"));
|
||||
}
|
||||
if (refCF) {
|
||||
if (!CFStringGetCString
|
||||
(refCF, pDevice->product, 256,
|
||||
CFStringGetSystemEncoding()))
|
||||
SDL_SetError
|
||||
("CFStringGetCString error retrieving pDevice->product.");
|
||||
if (!CFStringGetCString(refCF, pDevice->product, 256, CFStringGetSystemEncoding())) {
|
||||
SDL_SetError("CFStringGetCString error retrieving pDevice->product.");
|
||||
}
|
||||
}
|
||||
|
||||
/* get usage page and usage */
|
||||
refCF =
|
||||
CFDictionaryGetValue(hidProperties,
|
||||
CFSTR(kIOHIDPrimaryUsagePageKey));
|
||||
refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDPrimaryUsagePageKey));
|
||||
if (refCF) {
|
||||
if (!CFNumberGetValue
|
||||
(refCF, kCFNumberLongType, &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.");
|
||||
if (!CFNumberGetValue (refCF, kCFNumberLongType, &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 =
|
||||
CFDictionaryGetValue(hidProperties,
|
||||
CFSTR(kIOHIDVendorIDKey));
|
||||
refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDVendorIDKey));
|
||||
if (refCF) {
|
||||
if (!CFNumberGetValue
|
||||
(refCF, kCFNumberLongType, &pDevice->guid.data[0]))
|
||||
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].");
|
||||
if (!CFNumberGetValue(refCF, kCFNumberLongType, &pDevice->guid.data[0])) {
|
||||
SDL_SetError("CFNumberGetValue error retrieving pDevice->guid[0]");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (NULL == refCF) { /* get top level element HID usage page or usage */
|
||||
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 */
|
||||
/* use top level element instead */
|
||||
CFTypeRef refCFTopElement = 0;
|
||||
refCFTopElement =
|
||||
CFDictionaryGetValue(hidProperties,
|
||||
CFSTR(kIOHIDElementKey));
|
||||
refCFTopElement = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDElementKey));
|
||||
{
|
||||
/* refCFTopElement points to an array of element dictionaries */
|
||||
CFRange range = { 0, CFArrayGetCount(refCFTopElement) };
|
||||
CFArrayApplyFunction(refCFTopElement, range,
|
||||
HIDTopLevelElementHandler, pDevice);
|
||||
CFArrayApplyFunction(refCFTopElement, range, HIDTopLevelElementHandler, pDevice);
|
||||
}
|
||||
}
|
||||
|
||||
CFRelease(usbProperties);
|
||||
} else
|
||||
SDL_SetError
|
||||
("IORegistryEntryCreateCFProperties failed to create usbProperties.");
|
||||
} else {
|
||||
SDL_SetError("IORegistryEntryCreateCFProperties failed to create usbProperties.");
|
||||
}
|
||||
|
||||
if (kIOReturnSuccess != IOObjectRelease(parent2))
|
||||
SDL_SetError("IOObjectRelease error with parent2.");
|
||||
if (kIOReturnSuccess != IOObjectRelease(parent1))
|
||||
SDL_SetError("IOObjectRelease error with parent1.");
|
||||
if (kIOReturnSuccess != IOObjectRelease(parent2)) {
|
||||
SDL_SetError("IOObjectRelease error with parent2");
|
||||
}
|
||||
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 */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue