Arkadiusz Hiler : dinput: Implement device creation using product GUID.

Alexandre Julliard julliard at winehq.org
Tue Mar 23 16:54:32 CDT 2021


Module: wine
Branch: master
Commit: 0a82d891fc0b5b7f8b176e5e52d8858bab8d28bb
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=0a82d891fc0b5b7f8b176e5e52d8858bab8d28bb

Author: Arkadiusz Hiler <ahiler at codeweavers.com>
Date:   Tue Mar 23 20:00:36 2021 +0200

dinput: Implement device creation using product GUID.

This fixes Far Cry Primal controller discovery.

Signed-off-by: Arkadiusz Hiler <ahiler at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/dinput/joystick.c            |  4 ++--
 dlls/dinput/joystick_linux.c      | 10 ++++++++++
 dlls/dinput/joystick_linuxinput.c | 10 ++++++++++
 dlls/dinput/joystick_osx.c        | 16 ++++++++++++++++
 dlls/dinput/tests/device.c        | 22 ++++++++++++++++++++++
 5 files changed, 60 insertions(+), 2 deletions(-)

diff --git a/dlls/dinput/joystick.c b/dlls/dinput/joystick.c
index 2eab4d3a33d..f9b89d2d70c 100644
--- a/dlls/dinput/joystick.c
+++ b/dlls/dinput/joystick.c
@@ -717,7 +717,7 @@ HRESULT WINAPI JoystickAGenericImpl_GetDeviceInfo(
         index = pd.dwData;
 
     /* Return joystick */
-    pdidi->guidInstance = This->guidInstance;
+    pdidi->guidInstance = This->base.guid;
     pdidi->guidProduct = This->guidProduct;
     /* we only support traditional joysticks for now */
     pdidi->dwDevType = This->devcaps.dwDevType;
@@ -761,7 +761,7 @@ HRESULT WINAPI JoystickWGenericImpl_GetDeviceInfo(
         index = pd.dwData;
 
     /* Return joystick */
-    pdidi->guidInstance = This->guidInstance;
+    pdidi->guidInstance = This->base.guid;
     pdidi->guidProduct = This->guidProduct;
     /* we only support traditional joysticks for now */
     pdidi->dwDevType = This->devcaps.dwDevType;
diff --git a/dlls/dinput/joystick_linux.c b/dlls/dinput/joystick_linux.c
index 2b26eb806d3..79a077a027c 100644
--- a/dlls/dinput/joystick_linux.c
+++ b/dlls/dinput/joystick_linux.c
@@ -598,6 +598,7 @@ static unsigned short get_joystick_index(REFGUID guid)
 {
     GUID wine_joystick = DInput_Wine_Joystick_GUID;
     GUID dev_guid = *guid;
+    INT i;
 
     wine_joystick.Data3 = 0;
     dev_guid.Data3 = 0;
@@ -608,6 +609,9 @@ static unsigned short get_joystick_index(REFGUID guid)
     /* for the wine joystick GUIDs use the index stored in Data3 */
     if(IsEqualGUID(&wine_joystick, &dev_guid)) return guid->Data3;
 
+    for(i = 0; i < joystick_devices_count; i++)
+        if(IsEqualGUID(&joystick_devices[i].guid_product, guid)) return i;
+
     return MAX_JOYSTICKS;
 }
 
@@ -790,6 +794,9 @@ static HRESULT WINAPI JoystickLinuxAImpl_GetDeviceInfo(LPDIRECTINPUTDEVICE8A ifa
 
     fill_joystick_dideviceinstanceA( ddi, This->generic.base.dinput->dwVersion,
                                      get_joystick_index(&This->generic.base.guid) );
+
+    ddi->guidInstance = This->generic.base.guid;
+
     return DI_OK;
 }
 
@@ -806,6 +813,9 @@ static HRESULT WINAPI JoystickLinuxWImpl_GetDeviceInfo(LPDIRECTINPUTDEVICE8W ifa
 
     fill_joystick_dideviceinstanceW( ddi, This->generic.base.dinput->dwVersion,
                                      get_joystick_index(&This->generic.base.guid) );
+
+    ddi->guidInstance = This->generic.base.guid;
+
     return DI_OK;
 }
 
diff --git a/dlls/dinput/joystick_linuxinput.c b/dlls/dinput/joystick_linuxinput.c
index 102de8269b9..f0d2e0dc32b 100644
--- a/dlls/dinput/joystick_linuxinput.c
+++ b/dlls/dinput/joystick_linuxinput.c
@@ -612,6 +612,7 @@ static unsigned short get_joystick_index(REFGUID guid)
 {
     GUID wine_joystick = DInput_Wine_Joystick_Base_GUID;
     GUID dev_guid = *guid;
+    INT i;
 
     wine_joystick.Data3 = 0;
     dev_guid.Data3 = 0;
@@ -622,6 +623,9 @@ static unsigned short get_joystick_index(REFGUID guid)
     /* for the wine joystick GUIDs use the index stored in Data3 */
     if(IsEqualGUID(&wine_joystick, &dev_guid)) return guid->Data3 - DInput_Wine_Joystick_Base_GUID.Data3;
 
+    for(i = 0; i < have_joydevs; i++)
+        if(IsEqualGUID(&joydevs[i].guid_product, guid)) return i;
+
     return MAX_JOYDEV;
 }
 
@@ -1450,6 +1454,9 @@ static HRESULT WINAPI JoystickAImpl_GetDeviceInfo(LPDIRECTINPUTDEVICE8A iface,
 
     fill_joystick_dideviceinstanceA(pdidi, This->generic.base.dinput->dwVersion,
                                     get_joystick_index(&This->generic.base.guid));
+
+    pdidi->guidInstance = This->generic.base.guid;
+
     return DI_OK;
 }
 
@@ -1467,6 +1474,9 @@ static HRESULT WINAPI JoystickWImpl_GetDeviceInfo(LPDIRECTINPUTDEVICE8W iface,
 
     fill_joystick_dideviceinstanceW(pdidi, This->generic.base.dinput->dwVersion,
                                     get_joystick_index(&This->generic.base.guid));
+
+    pdidi->guidInstance = This->generic.base.guid;
+
     return DI_OK;
 }
 
diff --git a/dlls/dinput/joystick_osx.c b/dlls/dinput/joystick_osx.c
index 805b75639fe..e27357efb32 100644
--- a/dlls/dinput/joystick_osx.c
+++ b/dlls/dinput/joystick_osx.c
@@ -1322,6 +1322,10 @@ static unsigned short get_joystick_index(REFGUID guid)
 {
     GUID wine_joystick = DInput_Wine_OsX_Joystick_GUID;
     GUID dev_guid = *guid;
+    GUID prod_guid = *guid;
+    IOHIDDeviceRef device;
+    int joystick_devices_count;
+    INT i;
 
     wine_joystick.Data3 = 0;
     dev_guid.Data3 = 0;
@@ -1332,6 +1336,18 @@ static unsigned short get_joystick_index(REFGUID guid)
     /* for the wine joystick GUIDs use the index stored in Data3 */
     if(IsEqualGUID(&wine_joystick, &dev_guid)) return guid->Data3;
 
+    prod_guid.Data1 = 0;
+    if(IsEqualGUID(&DInput_PIDVID_Product_GUID, &prod_guid))
+    {
+        joystick_devices_count = find_joystick_devices();
+        for(i = 0; i < joystick_devices_count; i++)
+        {
+            device = get_device_ref(i);
+            if(guid->Data1 == make_vid_pid(device))
+                return i;
+        }
+    }
+
     return 0xffff;
 }
 
diff --git a/dlls/dinput/tests/device.c b/dlls/dinput/tests/device.c
index dcf8a373348..fd212bf2514 100644
--- a/dlls/dinput/tests/device.c
+++ b/dlls/dinput/tests/device.c
@@ -197,12 +197,14 @@ struct enum_data
 {
     IDirectInputA *pDI;
     HWND hwnd;
+    BOOL tested_product_creation;
 };
 
 static BOOL CALLBACK enum_devices(const DIDEVICEINSTANCEA *lpddi, void *pvRef)
 {
     struct enum_data *data = pvRef;
     IDirectInputDeviceA *device, *obj = NULL;
+    DIDEVICEINSTANCEA ddi2;
     HRESULT hr;
 
     hr = IDirectInput_GetDeviceStatus(data->pDI, &lpddi->guidInstance);
@@ -226,6 +228,24 @@ static BOOL CALLBACK enum_devices(const DIDEVICEINSTANCEA *lpddi, void *pvRef)
         IUnknown_Release(obj);
 
         IUnknown_Release(device);
+
+        if (!IsEqualGUID(&lpddi->guidInstance, &lpddi->guidProduct))
+        {
+            data->tested_product_creation = TRUE;
+            hr = IDirectInput_CreateDevice(data->pDI, &lpddi->guidProduct, &device, NULL);
+            ok(SUCCEEDED(hr), "IDirectInput_CreateDevice() failed: %08x\n", hr);
+
+            ddi2.dwSize = sizeof(ddi2);
+            hr = IDirectInputDevice_GetDeviceInfo(device, &ddi2);
+            ok(SUCCEEDED(hr), "IDirectInput_GetDeviceInfo failed: %08x\n", hr);
+
+            ok(IsEqualGUID(&lpddi->guidProduct, &ddi2.guidProduct), "Product GUIDs do not match. Expected %s, got %s\n", debugstr_guid(&lpddi->guidProduct), debugstr_guid(&ddi2.guidProduct));
+            ok(IsEqualGUID(&ddi2.guidProduct, &ddi2.guidInstance), "Instance GUID should equal product GUID. Expected %s, got %s\n", debugstr_guid(&ddi2.guidProduct), debugstr_guid(&ddi2.guidInstance));
+            /* we cannot compare guidInstances as we may get a different device */
+
+            IUnknown_Release(device);
+        }
+
     }
     return DIENUM_CONTINUE;
 }
@@ -263,9 +283,11 @@ static void device_tests(void)
 
         data.pDI = pDI;
         data.hwnd = hwnd;
+        data.tested_product_creation = FALSE;
         hr = IDirectInput_EnumDevices(pDI, 0, enum_devices, &data, DIEDFL_ALLDEVICES);
         ok(SUCCEEDED(hr), "IDirectInput_EnumDevices() failed: %08x\n", hr);
 
+        if (!data.tested_product_creation) winetest_skip("Device creation using product GUID not tested\n");
 
         /* If GetDeviceStatus returns DI_OK the device must exist */
         hr = IDirectInput_GetDeviceStatus(pDI, &GUID_Joystick);




More information about the wine-cvs mailing list