winejoystick.drv: Don't assume the first joystick is at the first device on Linux
Bruno Jesus
00cpxxx at gmail.com
Mon Aug 15 17:01:48 CDT 2016
Related to bug https://bugs.winehq.org/show_bug.cgi?id=36850
Currently the code will always assume the joystick[0] is at
/dev/input/js0 and [1] at /dev/input/js1.
Sample output from my system which insists to map a first controller to js1:
trace:joystick:JSTCK_OpenDevice Found joystick[0] at /dev/input/js1
trace:joystick:driver_joyGetDevCaps Driver: 0x020100, Name: Microsoft
X-Box 360 pad, #Axes: 8, #Buttons: 11
trace:joystick:JSTCK_OpenDevice Found joystick[1] at /dev/input/js2
trace:joystick:driver_joyGetDevCaps Driver: 0x020100, Name: USB
GamePad STD., #Axes: 2, #Buttons: 8
Signed-off-by: Bruno Jesus <00cpxxx at gmail.com>
-------------- next part --------------
diff --git a/dlls/winejoystick.drv/joystick_linux.c b/dlls/winejoystick.drv/joystick_linux.c
index b8fda4f..289e728 100644
--- a/dlls/winejoystick.drv/joystick_linux.c
+++ b/dlls/winejoystick.drv/joystick_linux.c
@@ -126,6 +126,7 @@ LRESULT driver_open(LPSTR str, DWORD dwIntf)
return 0;
JSTCK_Data[dwIntf].joyIntf = dwIntf;
+ JSTCK_Data[dwIntf].dev = -1;
JSTCK_Data[dwIntf].in_use = TRUE;
return (LRESULT)&JSTCK_Data[dwIntf];
}
@@ -160,25 +161,43 @@ struct js_status
*/
static int JSTCK_OpenDevice(WINE_JSTCK* jstick)
{
- char buf[20];
- int flags;
+ char buf[20];
+ int flags, fd, found_ix, i;
if (jstick->dev > 0)
return jstick->dev;
- sprintf(buf, JOYDEV_NEW, jstick->joyIntf);
#ifdef HAVE_LINUX_22_JOYSTICK_API
flags = O_RDONLY | O_NONBLOCK;
#else
flags = O_RDONLY;
#endif
- if ((jstick->dev = open(buf, flags)) < 0) {
- sprintf(buf, JOYDEV_OLD, jstick->joyIntf);
- if ((jstick->dev = open(buf, flags)) < 0)
- return jstick->dev;
+
+ /* The first joystick may not be at /dev/input/js0, find the correct
+ * first or second device. For example the driver for XBOX 360 wireless
+ * receiver creates entries starting at 20.
+ */
+ for (found_ix = i = 0; i < MAXJOYSTICK; i++) {
+ sprintf(buf, JOYDEV_NEW, i);
+ if ((fd = open(buf, flags)) < 0) {
+ sprintf(buf, JOYDEV_OLD, i);
+ if ((fd = open(buf, flags)) < 0)
+ continue;
+ }
+
+ if (found_ix++ == jstick->joyIntf)
+ {
+ TRACE("Found joystick[%d] at %s\n", jstick->joyIntf, buf);
+ jstick->dev = fd;
+ break;
+ }
+
+ close(fd);
}
+
#ifdef HAVE_LINUX_22_JOYSTICK_API
- ioctl(jstick->dev, JSIOCGAXMAP, jstick->axesMap);
+ if (jstick->dev > 0)
+ ioctl(jstick->dev, JSIOCGAXMAP, jstick->axesMap);
#endif
return jstick->dev;
}
More information about the wine-patches
mailing list