[v1 2/2] winejoystick.drv/joystick_osx.c: sorts devices by location ID

David Lawrie david.dljunk at gmail.com
Fri Jun 24 20:33:17 CDT 2016


Fixes https://bugs.winehq.org/show_bug.cgi?id=38997
for winmm joysticks

Note: if multiple virtual joysticks have the same location ID, they will
still be unordered

Tested on OS X 10.10.5.

Signed-off-by: David Lawrie <david.dljunk at gmail.com>
---
 dlls/winejoystick.drv/joystick_osx.c | 46 +++++++++++++++++++++++++++---------
 1 file changed, 35 insertions(+), 11 deletions(-)

diff --git a/dlls/winejoystick.drv/joystick_osx.c b/dlls/winejoystick.drv/joystick_osx.c
index 4ef30cc..b7f35fb 100644
--- a/dlls/winejoystick.drv/joystick_osx.c
+++ b/dlls/winejoystick.drv/joystick_osx.c
@@ -321,6 +321,34 @@ static CFIndex find_top_level(IOHIDDeviceRef hid_device, CFMutableArrayRef main_
 /**************************************************************************
  *                              find_osx_devices
  */
+
+/*
+ * Helper to sort array by location ID since they are consistent across boots & launches
+ */
+static CFComparisonResult CFDeviceArrayComparatorFunction(const void *val1, const void *val2, void *context)
+{
+#pragma unused(context)
+    CFComparisonResult result = kCFCompareEqualTo;
+
+    long loc1 = IOHIDDevice_GetLocationID((IOHIDDeviceRef)val1);
+    long loc2 = IOHIDDevice_GetLocationID((IOHIDDeviceRef)val2);
+
+    if (loc1 < loc2) {
+        result = kCFCompareLessThan;
+    } else if (loc1 > loc2) {
+        result = kCFCompareGreaterThan;
+    }
+    return result;
+}
+
+/*
+ * Helper to copy the CFSet to a CFArray
+ */
+static void CFSetApplierFunctionCopyToCFArray(const void *value, void *context)
+{
+    CFArrayAppendValue((CFMutableArrayRef)context, value);
+}
+
 static int find_osx_devices(void)
 {
     IOHIDManagerRef hid_manager;
@@ -363,20 +391,16 @@ static int find_osx_devices(void)
     if (devset)
     {
         CFIndex num_devices, num_main_elements;
-        const void** refs;
-        CFArrayRef devices;
+        CFMutableArrayRef devices;
 
         num_devices = CFSetGetCount(devset);
-        refs = HeapAlloc(GetProcessHeap(), 0, num_devices * sizeof(*refs));
-        if (!refs)
-        {
-            CFRelease(devset);
-            goto fail;
-        }
 
-        CFSetGetValues(devset, refs);
-        devices = CFArrayCreate(NULL, refs, num_devices, &kCFTypeArrayCallBacks);
-        HeapFree(GetProcessHeap(), 0, refs);
+        devices = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
+        /* copy devices from (unordered) set to array */
+        CFSetApplyFunction(devset, CFSetApplierFunctionCopyToCFArray, (void *)devices);
+        /* now sort the array by location ID's */
+        CFArraySortValues(devices, CFRangeMake(0, num_devices), CFDeviceArrayComparatorFunction, NULL);
+
         CFRelease(devset);
         if (!devices)
             goto fail;
-- 
1.7.12.4 (Apple Git-37)




More information about the wine-patches mailing list