[PATCH 2/2] dinput: Fix product GUID generation in Linux joystick and event API (try 2)

Corentin Rossignon corossig at gmail.com
Sun Jul 24 10:46:42 CDT 2016


Signed-off-by: Corentin Rossignon <corossig at gmail.com>
---
 dlls/dinput/joystick_linux.c      | 34 +++++++++++++++++++++++++++++++---
 dlls/dinput/joystick_linuxinput.c | 27 +++++++++++++++++++++++++--
 2 files changed, 56 insertions(+), 5 deletions(-)

diff --git a/dlls/dinput/joystick_linux.c b/dlls/dinput/joystick_linux.c
index 90b7280..f8499ca 100644
--- a/dlls/dinput/joystick_linux.c
+++ b/dlls/dinput/joystick_linux.c
@@ -77,6 +77,7 @@ struct JoyDev
 {
     char device[MAX_PATH];
     char name[MAX_PATH];
+    GUID guid_product;

     BYTE axis_count;
     BYTE button_count;
@@ -122,6 +123,19 @@ static const GUID DInput_Wine_Joystick_GUID = { /* 9e573ed9-7734-11d2-8d4a-23903
   {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
 };
 
+/*
+ * Construct the GUID in the same way of Windows doing this.
+ * Data1 is concatenation of productid and vendorid.
+ * Data2 and Data3 are NULL.
+ * Data4 seems to be a constant.
+ */
+static const GUID DInput_Wine_Joystick_Constant_Part_GUID = {
+  0x000000000,
+  0x0000,
+  0x0000,
+  {0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44}
+};
+
 #define MAX_JOYSTICKS 64
 static INT joystick_devices_count = -1;
 static struct JoyDev *joystick_devices;
@@ -235,7 +249,18 @@ static INT find_joystick_devices(void)
             }
 
             close(sys_fd);
         }
+
+        if (joydev.vendor_id == 0 || joydev.product_id == 0)
+        {
+            joydev.guid_product = DInput_Wine_Joystick_GUID;
+        }
+        else
+        {
+            /* Concatenate product_id with vendor_id to mimic Windows behaviour */
+            joydev.guid_product       = DInput_Wine_Joystick_Constant_Part_GUID;
+            joydev.guid_product.Data1 = MAKELONG(joydev.vendor_id, joydev.product_id);
+        }
 
         close(fd);
 
@@ -267,7 +292,7 @@ static void fill_joystick_dideviceinstanceA(LPDIDEVICEINSTANCEA lpddi, DWORD ver
     lpddi->dwSize = dwSize;
     lpddi->guidInstance = DInput_Wine_Joystick_GUID;
     lpddi->guidInstance.Data3 = id;
-    lpddi->guidProduct = DInput_Wine_Joystick_GUID;
+    lpddi->guidProduct = joystick_devices[id].guid_product;
     /* we only support traditional joysticks for now */
     if (version >= 0x0800)
         lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
@@ -290,7 +315,7 @@ static void fill_joystick_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD ver
     lpddi->dwSize = dwSize;
     lpddi->guidInstance = DInput_Wine_Joystick_GUID;
     lpddi->guidInstance.Data3 = id;
-    lpddi->guidProduct = DInput_Wine_Joystick_GUID;
+    lpddi->guidProduct = joystick_devices[id].guid_product;
     /* we only support traditional joysticks for now */
     if (version >= 0x0800)
         lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
diff --git a/dlls/dinput/joystick_linuxinput.c b/dlls/dinput/joystick_linuxinput.c
index 86f12d0..0c5cc66 100644
--- a/dlls/dinput/joystick_linuxinput.c
+++ b/dlls/dinput/joystick_linuxinput.c
@@ -96,6 +96,7 @@ struct JoyDev {
 	char *device;
 	char *name;
 	GUID guid;
+	GUID guid_product;
 
         BOOL has_ff;
         int num_effects;
@@ -161,6 +162,19 @@ static const GUID DInput_Wine_Joystick_Base_GUID = { /* 9e573eda-7734-11d2-8d4a-
   {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
 };
 
+/*
+ * Construct the GUID in the same way of Windows doing this.
+ * Data1 is concatenation of productid and vendorid.
+ * Data2 and Data3 are NULL.
+ * Data4 seems to be a constant.
+ */
+static const GUID DInput_Wine_Joystick_Constant_Part_GUID = {
+  0x000000000,
+  0x0000,
+  0x0000,
+  {0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44}
+};
+
 #define test_bit(arr,bit) (((BYTE*)(arr))[(bit)>>3]&(1<<((bit)&7)))
 
 #define MAX_JOYDEV 64
@@ -293,11 +307,18 @@ static void find_joydevs(void)
 	}
 
         if (ioctl(fd, EVIOCGID, &device_id) == -1)
+        {
             WARN("ioctl(EVIOCGID) failed: %d %s\n", errno, strerror(errno));
+            joydev.guid_product = DInput_Wine_Joystick_Base_GUID;
+        }
         else
         {
             joydev.vendor_id = device_id.vendor;
             joydev.product_id = device_id.product;
+
+            /* Concatenate product_id with vendor_id to mimic Windows behaviour */
+            joydev.guid_product       = DInput_Wine_Joystick_Constant_Part_GUID;
+            joydev.guid_product.Data1 = MAKELONG(joydev.vendor_id, joydev.product_id);
         }
 
         if (!have_joydevs)
@@ -327,7 +348,7 @@ static void fill_joystick_dideviceinstanceA(LPDIDEVICEINSTANCEA lpddi, DWORD ver
 
     lpddi->dwSize       = dwSize;
     lpddi->guidInstance = joydevs[id].guid;
-    lpddi->guidProduct  = DInput_Wine_Joystick_Base_GUID;
+    lpddi->guidProduct  = joydevs[id].guid_product;
     lpddi->guidFFDriver = GUID_NULL;
 
     if (version >= 0x0800)
@@ -348,7 +369,7 @@ static void fill_joystick_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD ver
 
     lpddi->dwSize       = dwSize;
     lpddi->guidInstance = joydevs[id].guid;
-    lpddi->guidProduct  = DInput_Wine_Joystick_Base_GUID;
+    lpddi->guidProduct  = joydevs[id].guid_product;
     lpddi->guidFFDriver = GUID_NULL;
 
     if (version >= 0x0800)
-- 
2.9.0




More information about the wine-patches mailing list