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

Andrew Eikum aeikum at codeweavers.com
Thu Feb 9 08:26:36 CST 2017


Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>

On Wed, Feb 08, 2017 at 10:07:53PM +0200, Jetro Jormalainen wrote:
> 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   | 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 06af92f9b2..65ce52c5c9 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 a6cbd34bb2..18f3001596 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);
>  
> -- 
> 2.11.0
> 
> 
> 



More information about the wine-patches mailing list