dinput: Give correct count of devices still to be enumerated.
Jetro Jormalainen
jje-wine at jv.jetro.fi
Sat Feb 4 07:35:10 CST 2017
EnumDevicesBySemantics should give count of all devices instead of
just keyboard and mouse still to be enumerated when calling callback.
Tested on Arch Linux and Windows 10.
Signed-off-by: Jetro Jormalainen <jje-wine at jv.jetro.fi>
---
dlls/dinput/dinput_main.c | 55 ++++++++++++++++++++++++++++++++++++---------
dlls/dinput8/tests/dinput.c | 11 ++++++++-
2 files changed, 54 insertions(+), 12 deletions(-)
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c
index 06af92f9b2..05651c9ced 100644
--- a/dlls/dinput/dinput_main.c
+++ b/dlls/dinput/dinput_main.c
@@ -930,7 +930,8 @@ static HRESULT WINAPI IDirectInput8AImpl_EnumDevicesBySemantics(
LPDIRECTINPUTDEVICE8A lpdid;
DWORD callbackFlags;
int i, j;
-
+ int c = 0;
+ DIDEVICEINSTANCEA *didevis = 0;
FIXME("(this=%p,%s,%p,%p,%p,%04x): semi-stub\n", This, debugstr_a(ptszUserName), lpdiActionFormat,
lpCallback, pvRef, dwFlags);
@@ -958,19 +959,34 @@ static HRESULT WINAPI IDirectInput8AImpl_EnumDevicesBySemantics(
{
TRACE(" - checking device %u ('%s')\n", i, dinput_devices[i]->name);
- callbackFlags = diactionformat_priorityA(lpdiActionFormat, lpdiActionFormat->dwGenre);
/* Default behavior is to enumerate attached game controllers */
enumSuccess = dinput_devices[i]->enum_deviceA(DI8DEVCLASS_GAMECTRL, DIEDFL_ATTACHEDONLY | dwFlags, &didevi, This->dwVersion, j);
if (enumSuccess == S_OK)
{
- IDirectInput_CreateDevice(iface, &didevi.guidInstance, &lpdid, NULL);
-
- if (lpCallback(&didevi, lpdid, callbackFlags, 0, pvRef) == DIENUM_STOP)
- return DI_OK;
+ if (c++)
+ didevis = HeapReAlloc(GetProcessHeap(), 0, didevis, sizeof(DIDEVICEINSTANCEW)*c);
+ else
+ didevis = HeapAlloc(GetProcessHeap(), 0, sizeof(DIDEVICEINSTANCEW)*c);
+ didevis[c-1] = didevi;
}
}
}
+ for (i=0; i < c; i++)
+ {
+ unsigned remain = c - (i+1) + ((dwFlags & DIEDBSFL_FORCEFEEDBACK) ? 0 : sizeof(guids)/sizeof(guids[0]));
+ callbackFlags = diactionformat_priorityA(lpdiActionFormat, lpdiActionFormat->dwGenre);
+ IDirectInput_CreateDevice(iface, &didevis[i].guidInstance, &lpdid, NULL);
+
+ if (lpCallback(&didevis[i], lpdid, callbackFlags, remain, pvRef) == DIENUM_STOP)
+ {
+ HeapFree(GetProcessHeap(), 0, (void*) didevis);
+ return DI_OK;
+ }
+ }
+
+ HeapFree(GetProcessHeap(), 0, (void*) didevis);
+
if (dwFlags & DIEDBSFL_FORCEFEEDBACK) return DI_OK;
/* Enumerate keyboard and mouse */
@@ -1001,6 +1017,8 @@ static HRESULT WINAPI IDirectInput8WImpl_EnumDevicesBySemantics(
LPDIRECTINPUTDEVICE8W lpdid;
DWORD callbackFlags;
int i, j;
+ int c = 0;
+ DIDEVICEINSTANCEW *didevis = 0;
FIXME("(this=%p,%s,%p,%p,%p,%04x): semi-stub\n", This, debugstr_w(ptszUserName), lpdiActionFormat,
lpCallback, pvRef, dwFlags);
@@ -1018,19 +1036,34 @@ static HRESULT WINAPI IDirectInput8WImpl_EnumDevicesBySemantics(
{
TRACE(" - checking device %u ('%s')\n", i, dinput_devices[i]->name);
- callbackFlags = diactionformat_priorityW(lpdiActionFormat, lpdiActionFormat->dwGenre);
/* Default behavior is to enumerate attached game controllers */
enumSuccess = dinput_devices[i]->enum_deviceW(DI8DEVCLASS_GAMECTRL, DIEDFL_ATTACHEDONLY | dwFlags, &didevi, This->dwVersion, j);
if (enumSuccess == S_OK)
{
- IDirectInput_CreateDevice(iface, &didevi.guidInstance, &lpdid, NULL);
-
- if (lpCallback(&didevi, lpdid, callbackFlags, 0, pvRef) == DIENUM_STOP)
- return DI_OK;
+ if (c++)
+ didevis = HeapReAlloc(GetProcessHeap(), 0, didevis, sizeof(DIDEVICEINSTANCEW)*c);
+ else
+ didevis = HeapAlloc(GetProcessHeap(), 0, sizeof(DIDEVICEINSTANCEW)*c);
+ didevis[c-1] = didevi;
}
}
}
+ for (i=0; i < c; i++)
+ {
+ unsigned remain = c - (i+1) + ((dwFlags & DIEDBSFL_FORCEFEEDBACK) ? 0 : sizeof(guids)/sizeof(guids[0]));
+ callbackFlags = diactionformat_priorityW(lpdiActionFormat, lpdiActionFormat->dwGenre);
+ IDirectInput_CreateDevice(iface, &didevis[i].guidInstance, &lpdid, NULL);
+
+ if (lpCallback(&didevis[i], lpdid, callbackFlags, remain, pvRef) == DIENUM_STOP)
+ {
+ HeapFree(GetProcessHeap(), 0, (void*) didevis);
+ return DI_OK;
+ }
+ }
+
+ HeapFree(GetProcessHeap(), 0, (void*) didevis);
+
if (dwFlags & DIEDBSFL_FORCEFEEDBACK) return DI_OK;
/* Enumerate keyboard and mouse */
diff --git a/dlls/dinput8/tests/dinput.c b/dlls/dinput8/tests/dinput.c
index a6cbd34bb2..faf71dcf30 100644
--- a/dlls/dinput8/tests/dinput.c
+++ b/dlls/dinput8/tests/dinput.c
@@ -445,6 +445,7 @@ static void test_EnumDevices(void)
struct enum_semantics_test
{
unsigned int device_count;
+ DWORD first_remaining;
BOOL mouse;
BOOL keyboard;
DIACTIONFORMATA *lpdiaf;
@@ -476,6 +477,12 @@ static BOOL CALLBACK enum_semantics_callback(const DIDEVICEINSTANCEA *lpddi, IDi
if (context == NULL) return DIENUM_STOP;
+ if (!data->device_count) {
+ data->first_remaining = dwRemaining;
+ }
+ ok (dwRemaining == data->first_remaining - data->device_count,
+ "enum semantics remaining devices is wrong, expected %d, had %d",
+ data->first_remaining - data->device_count, dwRemaining);
data->device_count++;
if (IsEqualGUID(&lpddi->guidInstance, &GUID_SysKeyboard)) data->keyboard = TRUE;
@@ -507,7 +514,7 @@ static void test_EnumDevicesBySemantics(void)
HRESULT hr;
DIACTIONFORMATA diaf;
const GUID ACTION_MAPPING_GUID = { 0x1, 0x2, 0x3, { 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb } };
- struct enum_semantics_test data = { 0, FALSE, FALSE, &diaf, NULL };
+ struct enum_semantics_test data = { 0, 0, FALSE, FALSE, &diaf, NULL };
int device_total = 0;
hr = DirectInput8Create(hInstance, DIRECTINPUT_VERSION, &IID_IDirectInput8A, (void **)&pDI, NULL);
@@ -539,6 +546,7 @@ static void test_EnumDevicesBySemantics(void)
/* Enumerate Force feedback devices. We should get no mouse nor keyboard */
data.keyboard = FALSE;
data.mouse = FALSE;
+ data.device_count = 0;
hr = IDirectInput8_EnumDevicesBySemantics(pDI, NULL, &diaf, enum_semantics_callback, &data, DIEDBSFL_FORCEFEEDBACK);
ok (SUCCEEDED(hr), "EnumDevicesBySemantics failed hr=%08x\n", hr);
ok (!data.keyboard, "Keyboard should not be enumerated when asking for forcefeedback\n");
@@ -595,6 +603,7 @@ static void test_EnumDevicesBySemantics(void)
/* The call fails with a zeroed GUID */
memset(&diaf.guidActionMap, 0, sizeof(GUID));
+ data.device_count = 0;
hr = IDirectInput8_EnumDevicesBySemantics(pDI, NULL, &diaf, enum_semantics_callback, NULL, 0);
todo_wine ok(FAILED(hr), "EnumDevicesBySemantics succeeded with invalid GUID hr=%08x\n", hr);
--
2.11.0
More information about the wine-patches
mailing list