Jetro Jormalainen : dinput: Give correct count of devices still to be enumerated.

Alexandre Julliard julliard at winehq.org
Thu Feb 9 15:54:27 CST 2017


Module: wine
Branch: master
Commit: 04bddb6c93dc3554fceff9612c56b62a43443b48
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=04bddb6c93dc3554fceff9612c56b62a43443b48

Author: Jetro Jormalainen <jje-wine at jv.jetro.fi>
Date:   Wed Feb  8 22:07:53 2017 +0200

dinput: Give correct count of devices still to be enumerated.

EnumDevicesBySemantics should give count of all devices instead of
just keyboard and mouse still to be enumerated when calling callback.

Signed-off-by: Jetro Jormalainen <jje-wine at jv.jetro.fi>
Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
Signed-off-by: Bruno Jesus <00cpxxx at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/dinput/dinput_main.c   | 63 +++++++++++++++++++++++++++++++++++++--------
 dlls/dinput8/tests/dinput.c | 11 +++++++-
 2 files changed, 62 insertions(+), 12 deletions(-)

diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c
index 06af92f..65ce52c 100644
--- a/dlls/dinput/dinput_main.c
+++ b/dlls/dinput/dinput_main.c
@@ -930,7 +930,9 @@ static HRESULT WINAPI IDirectInput8AImpl_EnumDevicesBySemantics(
     LPDIRECTINPUTDEVICE8A lpdid;
     DWORD callbackFlags;
     int i, j;
-
+    int device_count = 0;
+    int remain;
+    DIDEVICEINSTANCEA *didevis = 0;
 
     FIXME("(this=%p,%s,%p,%p,%p,%04x): semi-stub\n", This, debugstr_a(ptszUserName), lpdiActionFormat,
           lpCallback, pvRef, dwFlags);
@@ -958,19 +960,37 @@ 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 (device_count++)
+                    didevis = HeapReAlloc(GetProcessHeap(), 0, didevis, sizeof(DIDEVICEINSTANCEW)*device_count);
+                else
+                    didevis = HeapAlloc(GetProcessHeap(), 0, sizeof(DIDEVICEINSTANCEW)*device_count);
+                didevis[device_count-1] = didevi;
             }
         }
     }
 
+    remain = device_count;
+    if (!(dwFlags & DIEDBSFL_FORCEFEEDBACK))
+        remain += sizeof(guids)/sizeof(guids[0]);
+
+    for (i = 0; i < device_count; i++)
+    {
+        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, didevis);
+            return DI_OK;
+        }
+    }
+
+    HeapFree(GetProcessHeap(), 0, didevis);
+
     if (dwFlags & DIEDBSFL_FORCEFEEDBACK) return DI_OK;
 
     /* Enumerate keyboard and mouse */
@@ -1001,6 +1021,9 @@ static HRESULT WINAPI IDirectInput8WImpl_EnumDevicesBySemantics(
     LPDIRECTINPUTDEVICE8W lpdid;
     DWORD callbackFlags;
     int i, j;
+    int device_count = 0;
+    int remain;
+    DIDEVICEINSTANCEW *didevis = 0;
 
     FIXME("(this=%p,%s,%p,%p,%p,%04x): semi-stub\n", This, debugstr_w(ptszUserName), lpdiActionFormat,
           lpCallback, pvRef, dwFlags);
@@ -1018,19 +1041,37 @@ 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 (device_count++)
+                    didevis = HeapReAlloc(GetProcessHeap(), 0, didevis, sizeof(DIDEVICEINSTANCEW)*device_count);
+                else
+                    didevis = HeapAlloc(GetProcessHeap(), 0, sizeof(DIDEVICEINSTANCEW)*device_count);
+                didevis[device_count-1] = didevi;
             }
         }
     }
 
+    remain = device_count;
+    if (!(dwFlags & DIEDBSFL_FORCEFEEDBACK))
+        remain += sizeof(guids)/sizeof(guids[0]);
+
+    for (i = 0; i < device_count; i++)
+    {
+        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, didevis);
+            return DI_OK;
+        }
+    }
+
+    HeapFree(GetProcessHeap(), 0, 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 a6cbd34..18f3001 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\n",
+        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);
 




More information about the wine-cvs mailing list