From: Corentin Rossignon Subject: [PATCH 2/2] dinput: Fix product GUID generation in Linux joystick and event API (try 2) Message-Id: <20160724154642.22166-2-corossig@gmail.com> Date: Sun, 24 Jul 2016 16:46:42 +0100 In-Reply-To: <20160724154642.22166-1-corossig@gmail.com> References: <20160724154642.22166-1-corossig@gmail.com> Signed-off-by: Corentin Rossignon --- 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