[DINPUT] Sync with Wine Staging 2.2. CORE-12823
[reactos.git] / reactos / dll / directx / wine / dinput / dinput_main.c
index c63ab38..5127371 100644 (file)
@@ -162,15 +162,26 @@ HRESULT WINAPI DECLSPEC_HOTPATCH DirectInputCreateW(HINSTANCE hinst, DWORD dwVer
     return DirectInputCreateEx(hinst, dwVersion, &IID_IDirectInput7W, (LPVOID *)ppDI, punkOuter);
 }
 
-static const char *_dump_DIDEVTYPE_value(DWORD dwDevType)
-{
-    switch (dwDevType) {
-        case 0: return "All devices";
-       case DIDEVTYPE_MOUSE: return "DIDEVTYPE_MOUSE";
-       case DIDEVTYPE_KEYBOARD: return "DIDEVTYPE_KEYBOARD";
-       case DIDEVTYPE_JOYSTICK: return "DIDEVTYPE_JOYSTICK";
-       case DIDEVTYPE_DEVICE: return "DIDEVTYPE_DEVICE";
-       default: return "Unknown";
+static const char *_dump_DIDEVTYPE_value(DWORD dwDevType, DWORD dwVersion)
+{
+    if (dwVersion < 0x0800) {
+        switch (dwDevType) {
+            case 0: return "All devices";
+            case DIDEVTYPE_MOUSE: return "DIDEVTYPE_MOUSE";
+            case DIDEVTYPE_KEYBOARD: return "DIDEVTYPE_KEYBOARD";
+            case DIDEVTYPE_JOYSTICK: return "DIDEVTYPE_JOYSTICK";
+            case DIDEVTYPE_DEVICE: return "DIDEVTYPE_DEVICE";
+            default: return "Unknown";
+        }
+    } else {
+        switch (dwDevType) {
+            case DI8DEVCLASS_ALL: return "All devices";
+            case DI8DEVCLASS_POINTER: return "DI8DEVCLASS_POINTER";
+            case DI8DEVCLASS_KEYBOARD: return "DI8DEVCLASS_KEYBOARD";
+            case DI8DEVCLASS_DEVICE: return "DI8DEVCLASS_DEVICE";
+            case DI8DEVCLASS_GAMECTRL: return "DI8DEVCLASS_GAMECTRL";
+            default: return "Unknown";
+        }
     }
 }
 
@@ -363,10 +374,11 @@ static HRESULT WINAPI IDirectInputAImpl_EnumDevices(
     IDirectInputImpl *This = impl_from_IDirectInput7A(iface);
     DIDEVICEINSTANCEA devInstance;
     unsigned int i;
-    int j, r;
+    int j;
+    HRESULT r;
 
-    TRACE("(this=%p,0x%04x '%s',%p,%p,%04x)\n",
-         This, dwDevType, _dump_DIDEVTYPE_value(dwDevType),
+    TRACE("(this=%p,0x%04x '%s',%p,%p,0x%04x)\n",
+         This, dwDevType, _dump_DIDEVTYPE_value(dwDevType, This->dwVersion),
          lpCallback, pvRef, dwFlags);
     _dump_EnumDevices_dwFlags(dwFlags);
 
@@ -405,8 +417,8 @@ static HRESULT WINAPI IDirectInputWImpl_EnumDevices(
     int j;
     HRESULT r;
 
-    TRACE("(this=%p,0x%04x '%s',%p,%p,%04x)\n",
-         This, dwDevType, _dump_DIDEVTYPE_value(dwDevType),
+    TRACE("(this=%p,0x%04x '%s',%p,%p,0x%04x)\n",
+         This, dwDevType, _dump_DIDEVTYPE_value(dwDevType, This->dwVersion),
          lpCallback, pvRef, dwFlags);
     _dump_EnumDevices_dwFlags(dwFlags);
 
@@ -899,7 +911,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);
@@ -927,19 +941,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(DIDEVICEINSTANCEA)*device_count);
+                else
+                    didevis = HeapAlloc(GetProcessHeap(), 0, sizeof(DIDEVICEINSTANCEA)*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 */
@@ -970,6 +1002,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);
@@ -987,19 +1022,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 */