[1/3] dinput: Add top level HID Collection detection to OSX joystick driver

Zachary Smith iamsparticle at gmail.com
Sun Sep 19 16:21:29 CDT 2010


Hello-

The Problem:
I had some trouble using a gamepad adapter recently with wine on OSX. It has
two gamepads which are set up as two different, but otherwise identical, top
level collections in the HID descriptor.  The current joystick driver
doesn't take into account separate top level collections, which results in
the following issues:
1)  Buttons from each joystick with identical usage values get sorted into
identical locations during insert_sort_button().  This results in losing
track of 1/2 the buttons and the last half of the buttons pointing to memory
0, causing an unhanded page fault in get_osx_device_elements_props().
2) If the above problem is bypassed, there is still a collision of usages
for the joystick axes, which causes input to behave erratically.

The Solution:
MSDN indicated that top level HID collections are each treated as separate
devices internally.  My goal was to implement this behavior in the OSX
Joystick driver.

This Patch:
Here I add find_osx_top_level() to the file, which is designed to identify
top level HID collections.  It is independent from patch [2/3] but required
for patch [3/3]

-Zach Smith

---
 dlls/dinput/joystick_osx.c |   33 +++++++++++++++++++++++++++++++++
 1 files changed, 33 insertions(+), 0 deletions(-)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-patches/attachments/20100919/897bfaaf/attachment.htm>
-------------- next part --------------
From ba8f7b1e0a82787eb3c9c61ec86f93eb5afd0b50 Mon Sep 17 00:00:00 2001
From: Zach Smith <IAmSparticle at gmail.com>
Date: Thu, 16 Sep 2010 23:25:27 -0400
Subject: dinput: Add top level HID Collection detection to OSX joystick driver

---
 dlls/dinput/joystick_osx.c |   33 +++++++++++++++++++++++++++++++++
 1 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/dlls/dinput/joystick_osx.c b/dlls/dinput/joystick_osx.c
index bc6908b..2e30976 100644
--- a/dlls/dinput/joystick_osx.c
+++ b/dlls/dinput/joystick_osx.c
@@ -194,6 +194,39 @@ static CFMutableDictionaryRef creates_osx_device_match(int usage)
     return result;
 }
 
+static CFIndex find_top_level(IOHIDDeviceRef tIOHIDDeviceRef, CFArrayRef topLevels)
+{
+    CFArrayRef      gElementCFArrayRef;
+    CFIndex         numTops = 0;
+
+    if (!tIOHIDDeviceRef)
+        return 0;
+
+    gElementCFArrayRef = IOHIDDeviceCopyMatchingElements( tIOHIDDeviceRef, NULL, 0 );
+
+    if ( gElementCFArrayRef ) {
+        CFIndex idx, cnt = CFArrayGetCount( gElementCFArrayRef );
+        for ( idx=0; idx<cnt; idx++ ) {
+            IOHIDElementRef tIOHIDElementRef = ( IOHIDElementRef ) CFArrayGetValueAtIndex( gElementCFArrayRef, idx );
+            int eleType = IOHIDElementGetType( tIOHIDElementRef );
+
+            /* Check for top-level gaming device collections */
+            if ( eleType == kIOHIDElementTypeCollection && 
+                 IOHIDElementGetParent( tIOHIDElementRef ) == 0 ) {
+                int tUsagePage = IOHIDElementGetUsagePage( tIOHIDElementRef );
+                int tUsage = IOHIDElementGetUsage( tIOHIDElementRef );
+
+                if ( tUsagePage == kHIDPage_GenericDesktop && 
+                     ( tUsage == kHIDUsage_GD_Joystick || tUsage == kHIDUsage_GD_GamePad ) ) {
+                    CFArrayAppendValue( topLevels, tIOHIDElementRef );
+                    numTops ++;
+                }
+            }
+        }
+    }
+    return numTops;
+}
+
 static int find_osx_devices(void)
 {
     IOReturn tIOReturn;
-- 
1.7.1


More information about the wine-patches mailing list