Added GUIDs for Bluetooth devices, using the same algorithm as the Linux code.
authorSam Lantinga <slouken@libsdl.org>
Mon, 25 Mar 2013 11:38:30 -0700
changeset 7026 bc089599bd82
parent 7025 4eb8ac58642c
child 7027 b1c25fd3907f
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.
src/joystick/darwin/SDL_sysjoystick.c
--- a/src/joystick/darwin/SDL_sysjoystick.c	Sun Mar 24 10:37:16 2013 -0700
+++ b/src/joystick/darwin/SDL_sysjoystick.c	Mon Mar 25 11:38:30 2013 -0700
@@ -463,98 +463,92 @@
     /* 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));
+            if (refCF) {
+                if (!CFNumberGetValue(refCF, kCFNumberLongType, &pDevice->guid.data[0])) {
+                    SDL_SetError("CFNumberGetValue error retrieving pDevice->guid[0]");
+                }
             }
 
-			refCF =
-			CFDictionaryGetValue(hidProperties,
-								 CFSTR(kIOHIDVendorIDKey));
+			refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDProductIDKey));
             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[8])) {
+                    SDL_SetError("CFNumberGetValue error retrieving pDevice->guid[8]");
+                }
             }
 
-			
-            if (NULL == refCF) {        /* get top level element HID usage page or usage */
+            /* 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 @@
 }
 
 #endif /* SDL_JOYSTICK_IOKIT */
+
 /* vi: set ts=4 sw=4 expandtab: */