Module: wine Branch: master Commit: 0a82d891fc0b5b7f8b176e5e52d8858bab8d28bb URL: https://source.winehq.org/git/wine.git/?a=commit;h=0a82d891fc0b5b7f8b176e5e5...
Author: Arkadiusz Hiler ahiler@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@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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);