dinput multiple joystick patch

Robert Reif reif at earthlink.net
Sat Sep 11 14:50:17 CDT 2004


Adds support for multiple devices.
-------------- next part --------------
Index: dlls/dinput/dinput_main.c
===================================================================
RCS file: /home/wine/wine/dlls/dinput/dinput_main.c,v
retrieving revision 1.45
diff -u -r1.45 dinput_main.c
--- dlls/dinput/dinput_main.c	9 Sep 2004 20:17:08 -0000	1.45
+++ dlls/dinput/dinput_main.c	11 Sep 2004 19:16:49 -0000
@@ -238,7 +238,7 @@
 {
     IDirectInputImpl *This = (IDirectInputImpl *)iface;
     DIDEVICEINSTANCEA devInstance;
-    int i;
+    int i, j, r;
     
     TRACE("(this=%p,0x%04lx '%s',%p,%p,%04lx)\n",
 	  This, dwDevType, _dump_DIDEVTYPE_value(dwDevType),
@@ -246,11 +246,13 @@
     TRACE(" flags: "); _dump_EnumDevices_dwFlags(dwFlags); TRACE("\n");
     
     for (i = 0; i < nrof_dinput_devices; i++) {
-	devInstance.dwSize = sizeof(devInstance);
-	TRACE("  - checking device %d ('%s')\n", i, dinput_devices[i]->name);
-	if (dinput_devices[i]->enum_deviceA(dwDevType, dwFlags, &devInstance, This->version)) {
-	    if (lpCallback(&devInstance,pvRef) == DIENUM_STOP)
-		return 0;
+        for (j = 0, r = -1; r != 0; j++) {
+	    devInstance.dwSize = sizeof(devInstance);
+	    TRACE("  - checking device %d ('%s')\n", i, dinput_devices[i]->name);
+	    if ((r = dinput_devices[i]->enum_deviceA(dwDevType, dwFlags, &devInstance, This->version, j))) {
+	        if (lpCallback(&devInstance,pvRef) == DIENUM_STOP)
+		    return 0;
+	    }
 	}
     }
     
@@ -265,7 +267,7 @@
 {
     IDirectInputImpl *This = (IDirectInputImpl *)iface;
     DIDEVICEINSTANCEW devInstance;
-    int i;
+    int i, j, r;
     
     TRACE("(this=%p,0x%04lx '%s',%p,%p,%04lx)\n",
 	  This, dwDevType, _dump_DIDEVTYPE_value(dwDevType),
@@ -273,11 +275,13 @@
     TRACE(" flags: "); _dump_EnumDevices_dwFlags(dwFlags); TRACE("\n");
     
     for (i = 0; i < nrof_dinput_devices; i++) {
-	devInstance.dwSize = sizeof(devInstance);
-	TRACE("  - checking device %d ('%s')\n", i, dinput_devices[i]->name);
-	if (dinput_devices[i]->enum_deviceW(dwDevType, dwFlags, &devInstance, This->version)) {
-	    if (lpCallback(&devInstance,pvRef) == DIENUM_STOP)
-		return 0;
+        for (j = 0, r = -1; r != 0; j++) {
+	    devInstance.dwSize = sizeof(devInstance);
+	    TRACE("  - checking device %d ('%s')\n", i, dinput_devices[i]->name);
+	    if ((r = dinput_devices[i]->enum_deviceW(dwDevType, dwFlags, &devInstance, This->version, j))) {
+	        if (lpCallback(&devInstance,pvRef) == DIENUM_STOP)
+		    return 0;
+	    }
 	}
     }
     
Index: dlls/dinput/dinput_private.h
===================================================================
RCS file: /home/wine/wine/dlls/dinput/dinput_private.h,v
retrieving revision 1.12
diff -u -r1.12 dinput_private.h
--- dlls/dinput/dinput_private.h	4 Jun 2004 18:06:37 -0000	1.12
+++ dlls/dinput/dinput_private.h	11 Sep 2004 19:16:49 -0000
@@ -42,8 +42,8 @@
 typedef struct dinput_device {
     INT pref;
     const char *name;
-    BOOL (*enum_deviceA)(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version);
-    BOOL (*enum_deviceW)(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, int version);
+    BOOL (*enum_deviceA)(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version, int id);
+    BOOL (*enum_deviceW)(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, int version, int id);
     HRESULT (*create_deviceA)(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEA* pdev);
     HRESULT (*create_deviceW)(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEW* pdev);
 } dinput_device;
Index: dlls/dinput/joystick_linux.c
===================================================================
RCS file: /home/wine/wine/dlls/dinput/joystick_linux.c,v
retrieving revision 1.14
diff -u -r1.14 joystick_linux.c
--- dlls/dinput/joystick_linux.c	9 Sep 2004 20:17:08 -0000	1.14
+++ dlls/dinput/joystick_linux.c	11 Sep 2004 19:16:51 -0000
@@ -21,7 +21,6 @@
 
 /*
  * To Do:
- *	support more than one device
  *	dead zone
  *	buffered mode
  *	force feadback
@@ -57,7 +56,7 @@
 #ifdef HAVE_LINUX_JOYSTICK_H
 # include <linux/joystick.h>
 #endif
-#define JOYDEV	"/dev/js0"
+#define JOYDEV	"/dev/js"
 
 #include "wine/debug.h"
 #include "wine/unicode.h"
@@ -92,6 +91,7 @@
         LPVOID                          lpVtbl;
         DWORD                           ref;
         GUID                            guid;
+	char				dev[32];
 
 	/* The 'parent' DInput */
 	IDirectInputImpl               *dinput;
@@ -146,9 +146,10 @@
     }
 }
 
-static BOOL joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version)
+static BOOL joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version, int id)
 {
     int fd = -1;
+    char dev[32];
 
     if (dwFlags & DIEDFL_FORCEFEEDBACK) {
         WARN("force feedback not supported\n");
@@ -157,23 +158,25 @@
 
     if ((dwDevType==0) || (GET_DIDEVICE_TYPE(dwDevType)==DIDEVTYPE_JOYSTICK)) {
         /* check whether we have a joystick */
-        if ((fd = open(JOYDEV,O_RDONLY)) < 0) {
-            WARN("open(%s,O_RDONLY) failed: %s\n", JOYDEV, strerror(errno));
+        sprintf(dev, "%s%d", JOYDEV, id);
+        if ((fd = open(dev,O_RDONLY)) < 0) {
+            WARN("open(%s,O_RDONLY) failed: %s\n", dev, strerror(errno));
             return FALSE;
         }
 
         /* Return joystick */
-        lpddi->guidInstance = GUID_Joystick;
+        lpddi->guidInstance = DInput_Wine_Joystick_GUID;
+        lpddi->guidInstance.Data3 = id;
         lpddi->guidProduct = DInput_Wine_Joystick_GUID;
         /* we only support traditional joysticks for now */
         if (version >= 8)
             lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
         else
             lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8);
-        strcpy(lpddi->tszInstanceName, "Joystick");
+        sprintf(lpddi->tszInstanceName, "Joystick %d", id);
 #if defined(JSIOCGNAME)
         if (ioctl(fd,JSIOCGNAME(sizeof(lpddi->tszProductName)),lpddi->tszProductName) < 0) {
-            WARN("ioctl(%s,JSIOCGNAME) failed: %s\n", JOYDEV, strerror(errno));
+            WARN("ioctl(%s,JSIOCGNAME) failed: %s\n", dev, strerror(errno));
             strcpy(lpddi->tszProductName, "Wine Joystick");
         }
 #else
@@ -182,17 +185,19 @@
 
         lpddi->guidFFDriver = GUID_NULL;
         close(fd);
-        TRACE("Enumerating the linux Joystick device: %s (%s)\n", JOYDEV, lpddi->tszProductName);
+        TRACE("Enumerating the linux Joystick device: %s (%s)\n", dev, lpddi->tszProductName);
         return TRUE;
     }
 
     return FALSE;
 }
 
-static BOOL joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, int version)
+static BOOL joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, int version, int id)
 {
     int fd = -1;
     char name[MAX_PATH];
+    char dev[32];
+    char friendly[32];
 
     if (dwFlags & DIEDFL_FORCEFEEDBACK) {
         WARN("force feedback not supported\n");
@@ -201,22 +206,26 @@
 
     if ((dwDevType==0) || (GET_DIDEVICE_TYPE(dwDevType)==DIDEVTYPE_JOYSTICK)) {
         /* check whether we have a joystick */
-        if ((fd = open(JOYDEV,O_RDONLY)) < 0) {
-            WARN("open(%s,O_RDONLY) failed: %s\n", JOYDEV, strerror(errno));
+        sprintf(dev, "%s%d", JOYDEV, id);
+        if ((fd = open(dev,O_RDONLY)) < 0) {
+            WARN("open(%s,O_RDONLY) failed: %s\n", dev, strerror(errno));
             return FALSE;
         }
 
         /* Return joystick */
-        lpddi->guidInstance = GUID_Joystick;
+        lpddi->guidInstance = DInput_Wine_Joystick_GUID;
+        lpddi->guidInstance.Data3 = id;
         lpddi->guidProduct = DInput_Wine_Joystick_GUID;
         /* we only support traditional joysticks for now */
-        lpddi->dwDevType = DIDEVTYPE_JOYSTICK |
-                           (DIDEVTYPEJOYSTICK_TRADITIONAL<<8);
-
-        MultiByteToWideChar(CP_ACP, 0, "Joystick", -1, lpddi->tszInstanceName, MAX_PATH);
+        if (version >= 8)
+            lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
+        else
+            lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8);
+        sprintf(friendly, "Joystick %d", id);
+        MultiByteToWideChar(CP_ACP, 0, friendly, -1, lpddi->tszInstanceName, MAX_PATH);
 #if defined(JSIOCGNAME)
         if (ioctl(fd,JSIOCGNAME(sizeof(name)),name) < 0) {
-            WARN("ioctl(%s,JSIOCGNAME) failed: %s\n", JOYDEV, strerror(errno));
+            WARN("ioctl(%s,JSIOCGNAME) failed: %s\n", dev, strerror(errno));
             strcpy(name, "Wine Joystick");
         }
 #else
@@ -225,7 +234,7 @@
         MultiByteToWideChar(CP_ACP, 0, name, -1, lpddi->tszProductName, MAX_PATH);
         lpddi->guidFFDriver = GUID_NULL;
         close(fd);
-        TRACE("Enumerating the linux Joystick device: %s (%s)\n",JOYDEV,name);
+        TRACE("Enumerating the linux Joystick device: %s (%s)\n",dev,name);
         return TRUE;
     }
 
@@ -436,8 +445,10 @@
         return DIERR_OUTOFMEMORY;
     }
 
-    if ((newDevice->joyfd = open(JOYDEV,O_RDONLY)) < 0) {
-        WARN("open(%s,O_RDONLY) failed: %s\n", JOYDEV, strerror(errno));
+    sprintf(newDevice->dev, "%s%d", JOYDEV, rguid->Data3);
+
+    if ((newDevice->joyfd = open(newDevice->dev,O_RDONLY)) < 0) {
+        WARN("open(%s,O_RDONLY) failed: %s\n", newDevice->dev, strerror(errno));
         HeapFree(GetProcessHeap(), 0, newDevice);
         return DIERR_DEVICENOTREG;
     }
@@ -445,7 +456,7 @@
     /* get the device name */
 #if defined(JSIOCGNAME)
     if (ioctl(newDevice->joyfd,JSIOCGNAME(MAX_PATH),name) < 0) {
-        WARN("ioctl(%s,JSIOCGNAME) failed: %s\n", JOYDEV, strerror(errno));
+        WARN("ioctl(%s,JSIOCGNAME) failed: %s\n", newDevice->dev, strerror(errno));
         strcpy(name, "Wine Joystick");
     }
 #else
@@ -458,13 +469,13 @@
 
 #ifdef JSIOCGAXES
     if (ioctl(newDevice->joyfd,JSIOCGAXES,&newDevice->axes) < 0) {
-        WARN("ioctl(%s,JSIOCGAXES) failed: %s, defauting to 2\n", JOYDEV, strerror(errno));
+        WARN("ioctl(%s,JSIOCGAXES) failed: %s, defauting to 2\n", newDevice->dev, strerror(errno));
         newDevice->axes = 2;
     }
 #endif
 #ifdef JSIOCGBUTTONS
     if (ioctl(newDevice->joyfd,JSIOCGBUTTONS,&newDevice->buttons) < 0) {
-        WARN("ioctl(%s,JSIOCGBUTTONS) failed: %s, defauting to 2\n", JOYDEV, strerror(errno));
+        WARN("ioctl(%s,JSIOCGBUTTONS) failed: %s, defauting to 2\n", newDevice->dev, strerror(errno));
         newDevice->buttons = 2;
     }
 #endif
@@ -575,10 +586,21 @@
     return hr;
 }
 
+static BOOL IsJoystickGUID(REFGUID guid)
+{
+    GUID wine_joystick = DInput_Wine_Joystick_GUID;
+    GUID dev_guid = *guid;
+
+    wine_joystick.Data3 = 0;
+    dev_guid.Data3 = 0;
+
+    return IsEqualGUID(&wine_joystick, &dev_guid);
+}
+
 static HRESULT joydev_create_deviceA(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEA* pdev)
 {
   if ((IsEqualGUID(&GUID_Joystick,rguid)) ||
-      (IsEqualGUID(&DInput_Wine_Joystick_GUID,rguid))) {
+      (IsJoystickGUID(rguid))) {
     if ((riid == NULL) ||
 	IsEqualGUID(&IID_IDirectInputDeviceA,riid) ||
 	IsEqualGUID(&IID_IDirectInputDevice2A,riid) ||
@@ -600,7 +622,7 @@
 static HRESULT joydev_create_deviceW(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEW* pdev)
 {
   if ((IsEqualGUID(&GUID_Joystick,rguid)) ||
-      (IsEqualGUID(&DInput_Wine_Joystick_GUID,rguid))) {
+      (IsJoystickGUID(rguid))) {
     if ((riid == NULL) ||
 	IsEqualGUID(&IID_IDirectInputDeviceW,riid) ||
 	IsEqualGUID(&IID_IDirectInputDevice2W,riid) ||
@@ -758,11 +780,11 @@
 
     /* open the joystick device */
     if (This->joyfd==-1) {
-        TRACE("opening joystick device %s\n", JOYDEV);
+        TRACE("opening joystick device %s\n", This->dev);
 
-        This->joyfd=open(JOYDEV,O_RDONLY);
+        This->joyfd=open(This->dev,O_RDONLY);
         if (This->joyfd==-1) {
-            ERR("open(%s) failed: %s\n", JOYDEV, strerror(errno));
+            ERR("open(%s) failed: %s\n", This->dev, strerror(errno));
             return DIERR_NOTFOUND;
         }
     }
Index: dlls/dinput/joystick_linuxinput.c
===================================================================
RCS file: /home/wine/wine/dlls/dinput/joystick_linuxinput.c,v
retrieving revision 1.9
diff -u -r1.9 joystick_linuxinput.c
--- dlls/dinput/joystick_linuxinput.c	9 Sep 2004 20:17:08 -0000	1.9
+++ dlls/dinput/joystick_linuxinput.c	11 Sep 2004 19:16:51 -0000
@@ -167,10 +167,13 @@
   return havejoy;
 }
 
-static BOOL joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version)
+static BOOL joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version, int id)
 {
   int havejoy = 0;
 
+  if (id != 0)
+      return FALSE;
+
   if ((dwDevType != 0) && (GET_DIDEVICE_TYPE(dwDevType) != DIDEVTYPE_JOYSTICK))
       return FALSE;
 
@@ -200,9 +203,12 @@
   return TRUE;
 }
 
-static BOOL joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, int version)
+static BOOL joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, int version, int id)
 {
   int havejoy = 0;
+
+  if (id != 0)
+      return FALSE;
 
   if ((dwDevType != 0) && (GET_DIDEVICE_TYPE(dwDevType) != DIDEVTYPE_JOYSTICK))
       return FALSE;
Index: dlls/dinput/keyboard.c
===================================================================
RCS file: /home/wine/wine/dlls/dinput/keyboard.c,v
retrieving revision 1.6
diff -u -r1.6 keyboard.c
--- dlls/dinput/keyboard.c	9 Sep 2004 20:17:08 -0000	1.6
+++ dlls/dinput/keyboard.c	11 Sep 2004 19:16:51 -0000
@@ -199,8 +199,11 @@
     memcpy(lpddi, &ddi, (dwSize < sizeof(ddi) ? dwSize : sizeof(ddi)));
 }
  
-static BOOL keyboarddev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version)
+static BOOL keyboarddev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version, int id)
 {
+  if (id != 0)
+    return FALSE;
+
   if ((dwDevType == 0) ||
       ((dwDevType == DIDEVTYPE_KEYBOARD) && (version < 8)) ||
       ((dwDevType == DI8DEVTYPE_KEYBOARD) && (version >= 8))) {
@@ -214,8 +217,11 @@
   return FALSE;
 }
 
-static BOOL keyboarddev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, int version)
+static BOOL keyboarddev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, int version, int id)
 {
+  if (id != 0)
+    return FALSE;
+
   if ((dwDevType == 0) ||
       ((dwDevType == DIDEVTYPE_KEYBOARD) && (version < 8)) ||
       ((dwDevType == DI8DEVTYPE_KEYBOARD) && (version >= 8))) {
Index: dlls/dinput/mouse.c
===================================================================
RCS file: /home/wine/wine/dlls/dinput/mouse.c,v
retrieving revision 1.8
diff -u -r1.8 mouse.c
--- dlls/dinput/mouse.c	9 Sep 2004 20:17:08 -0000	1.8
+++ dlls/dinput/mouse.c	11 Sep 2004 19:16:52 -0000
@@ -202,8 +202,11 @@
     memcpy(lpddi, &ddi, (dwSize < sizeof(ddi) ? dwSize : sizeof(ddi)));
 }
 
-static BOOL mousedev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version)
+static BOOL mousedev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version, int id)
 {
+    if (id != 0)
+        return FALSE;
+
     if ((dwDevType == 0) ||
 	((dwDevType == DIDEVTYPE_MOUSE) && (version < 8)) ||
 	((dwDevType == DI8DEVTYPE_MOUSE) && (version >= 8))) {
@@ -217,8 +220,11 @@
     return FALSE;
 }
 
-static BOOL mousedev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, int version)
+static BOOL mousedev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, int version, int id)
 {
+    if (id != 0)
+        return FALSE;
+
     if ((dwDevType == 0) ||
 	((dwDevType == DIDEVTYPE_MOUSE) && (version < 8)) ||
 	((dwDevType == DI8DEVTYPE_MOUSE) && (version >= 8))) {


More information about the wine-patches mailing list