On Jul 16, 2016, at 3:15 AM, David Lawrie david.dljunk@gmail.com wrote:
Tested on OS X 10.10.5.
Signed-off-by: David Lawrie david.dljunk@gmail.com
dlls/dinput/joystick_osx.c | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-)
diff --git a/dlls/dinput/joystick_osx.c b/dlls/dinput/joystick_osx.c index 637692b..22bdc4f 100644 --- a/dlls/dinput/joystick_osx.c +++ b/dlls/dinput/joystick_osx.c @@ -193,6 +193,26 @@ static long get_device_property_long(IOHIDDeviceRef device, CFStringRef key) return result; }
+static CFStringRef get_device_name(IOHIDDeviceRef device) +{
- CFTypeRef ref;
- CFStringRef name = CFSTR("Default Name");
You can probably do better for a fallback. For example, you can format the vendor ID and product ID into a string. For an extreme take on this, see the Copy_DeviceName() function in Apple's HID Calibrator sample code: https://developer.apple.com/library/mac/samplecode/HID_Calibrator/Listings/H...
- if(device)
- {
assert(IOHIDDeviceGetTypeID() == CFGetTypeID(device));
ref = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
if (ref && CFStringGetTypeID() == CFGetTypeID(ref))
name = ref;
else if (ref)
name = CFCopyDescription(ref);
This introduces a memory-management problem, a.k.a. a leak. This copy is never released.
If you follow my suggestion above for formatting a string as a fallback if the product name isn't available, you'd also have to release that.
So, you would change this function's name to copy_device_name() and make sure all code paths return an owned reference to the caller, which the caller has to release. Basically, in the case where IOHIDDeviceGetProperty() gives you a string, you'd have to copy it to match the other code paths. Of course, you'd have to make sure the callers do, in fact, release the references.
- }
- return name;
+}
static long get_device_location_ID(IOHIDDeviceRef device) { return get_device_property_long(device, CFSTR(kIOHIDLocationIDKey)); @@ -203,7 +223,15 @@ static void copy_set_to_array(const void *value, void *context) CFArrayAppendValue(context, value); }
-static CFComparisonResult device_location_comparator(const void *val1, const void *val2, void *context) +static CFComparisonResult device_name_comparator(IOHIDDeviceRef device1, IOHIDDeviceRef device2) +{
- CFStringRef name1 = get_device_name(device1), name2 = get_device_name(device2);
- CFStringCompareFlags compareOptions = kCFCompareForcedOrdering | kCFCompareNumerically;
Any reason you've added this separate variable instead of just inlining the options in the call?
- return CFStringCompare(name1, name2, compareOptions);
+}
-Ken