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