[PATCH 6/7] dinput8: Use raw input interface for dinput8 keyboard device

Rémi Bernon rbernon at codeweavers.com
Mon Aug 26 09:07:00 CDT 2019


Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/dinput/keyboard.c      | 88 ++++++++++++++++++++++++++++++-------
 dlls/dinput8/tests/device.c |  7 ---
 2 files changed, 72 insertions(+), 23 deletions(-)

diff --git a/dlls/dinput/keyboard.c b/dlls/dinput/keyboard.c
index b5e665933ec..0f3d85a0ecc 100644
--- a/dlls/dinput/keyboard.c
+++ b/dlls/dinput/keyboard.c
@@ -107,28 +107,77 @@ static int KeyboardCallback( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM
 {
     SysKeyboardImpl *This = impl_from_IDirectInputDevice8A(iface);
     int dik_code, ret = This->base.dwCoopLevel & DISCL_EXCLUSIVE;
-    KBDLLHOOKSTRUCT *hook = (KBDLLHOOKSTRUCT *)lparam;
+    KBDLLHOOKSTRUCT *hook;
     BYTE new_diks;
 
-    if (wparam != WM_KEYDOWN && wparam != WM_KEYUP &&
-        wparam != WM_SYSKEYDOWN && wparam != WM_SYSKEYUP)
-        return 0;
+    if (wparam == RIM_INPUT || wparam == RIM_INPUTSINK)
+    {
+        RAWINPUTHEADER raw_header;
+        RAWINPUT raw_input;
+        UINT size;
+
+        TRACE("(%p) wp %08lx, lp %08lx\n", iface, wparam, lparam);
+
+        size = sizeof(raw_header);
+        if (GetRawInputData( (HRAWINPUT)lparam, RID_HEADER, &raw_header, &size, sizeof(RAWINPUTHEADER) ) != sizeof(raw_header))
+        {
+            WARN( "Unable to read raw input data header\n" );
+            return 0;
+        }
+
+        if (raw_header.dwType != RIM_TYPEKEYBOARD)
+            return 0;
 
-    TRACE("(%p) wp %08lx, lp %08lx, vk %02x, scan %02x\n",
-          iface, wparam, lparam, hook->vkCode, hook->scanCode);
+        if (raw_header.dwSize > sizeof(raw_input))
+        {
+            WARN( "Unexpected size for keyboard raw input data\n" );
+            return 0;
+        }
+
+        size = raw_header.dwSize;
+        if (GetRawInputData( (HRAWINPUT)lparam, RID_INPUT, &raw_input, &size, sizeof(RAWINPUTHEADER) ) != raw_header.dwSize )
+        {
+            WARN( "Unable to read raw input data\n" );
+            return 0;
+        }
 
-    switch (hook->vkCode)
+        switch (raw_input.data.keyboard.VKey)
+        {
+            /* R-Shift is special - it is an extended key with separate scan code */
+            case VK_RSHIFT: dik_code = DIK_RSHIFT; break;
+            case VK_PAUSE: dik_code = DIK_PAUSE; break;
+            case VK_NUMLOCK: dik_code = DIK_NUMLOCK; break;
+            case VK_SUBTRACT: dik_code = DIK_SUBTRACT; break;
+            default:
+                dik_code = map_dik_code(0, raw_input.data.keyboard.VKey, This->subtype);
+                if (raw_input.data.keyboard.Flags & RI_KEY_E0) dik_code |= 0x80;
+        }
+        new_diks = (raw_input.data.keyboard.Flags & RI_KEY_BREAK) ? 0 : 0x80;
+    }
+    else
     {
-        /* R-Shift is special - it is an extended key with separate scan code */
-        case VK_RSHIFT  : dik_code = DIK_RSHIFT; break;
-        case VK_PAUSE   : dik_code = DIK_PAUSE; break;
-        case VK_NUMLOCK : dik_code = DIK_NUMLOCK; break;
-        case VK_SUBTRACT: dik_code = DIK_SUBTRACT; break;
-        default:
-            dik_code = map_dik_code(hook->scanCode & 0xff, hook->vkCode, This->subtype);
-            if (hook->flags & LLKHF_EXTENDED) dik_code |= 0x80;
+        if (wparam != WM_KEYDOWN && wparam != WM_KEYUP &&
+            wparam != WM_SYSKEYDOWN && wparam != WM_SYSKEYUP)
+            return 0;
+
+        hook = (KBDLLHOOKSTRUCT *)lparam;
+
+        TRACE("(%p) wp %08lx, lp %08lx, vk %02x, scan %02x\n",
+              iface, wparam, lparam, hook->vkCode, hook->scanCode);
+
+        switch (hook->vkCode)
+        {
+            /* R-Shift is special - it is an extended key with separate scan code */
+            case VK_RSHIFT  : dik_code = DIK_RSHIFT; break;
+            case VK_PAUSE   : dik_code = DIK_PAUSE; break;
+            case VK_NUMLOCK : dik_code = DIK_NUMLOCK; break;
+            case VK_SUBTRACT: dik_code = DIK_SUBTRACT; break;
+            default:
+                dik_code = map_dik_code(hook->scanCode & 0xff, hook->vkCode, This->subtype);
+                if (hook->flags & LLKHF_EXTENDED) dik_code |= 0x80;
+        }
+        new_diks = hook->flags & LLKHF_UP ? 0 : 0x80;
     }
-    new_diks = hook->flags & LLKHF_UP ? 0 : 0x80;
 
     /* returns now if key event already known */
     if (new_diks == This->DInputKeyState[dik_code])
@@ -295,6 +344,13 @@ static SysKeyboardImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput)
     list_add_tail(&dinput->devices_list, &newDevice->base.entry);
     LeaveCriticalSection(&dinput->crit);
 
+    if (dinput->dwVersion >= DIRECTINPUT_VERSION)
+    {
+        newDevice->base.use_raw_input = TRUE;
+        newDevice->base.raw_device.usUsagePage = 1; /* HID generic device page */
+        newDevice->base.raw_device.usUsage = 6; /* HID generic keyboard */
+    }
+
     return newDevice;
 
 failed:
diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c
index 2b7814e3bbc..9f2d0dbd29a 100644
--- a/dlls/dinput8/tests/device.c
+++ b/dlls/dinput8/tests/device.c
@@ -609,15 +609,10 @@ static void test_mouse_keyboard(void)
     raw_devices_count = ARRAY_SIZE(raw_devices);
     memset(raw_devices, 0, sizeof(raw_devices));
     hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE));
-    todo_wine
     ok(hr == 1, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count);
-    todo_wine
     ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage);
-    todo_wine
     ok(raw_devices[0].usUsage == 6, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage);
-    todo_wine
     ok(raw_devices[0].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags);
-    todo_wine
     ok(raw_devices[0].hwndTarget != NULL, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget);
     hr = IDirectInputDevice8_Unacquire(di_keyboard);
     ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr);
@@ -699,9 +694,7 @@ static void test_mouse_keyboard(void)
     ok(raw_devices[1].hwndTarget == hwnd, "Unexpected raw device target: %p\n", raw_devices[1].hwndTarget);
     ok(raw_devices[2].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[1].usUsagePage);
     ok(raw_devices[2].usUsage == 6, "Unexpected raw device usage: %x\n", raw_devices[1].usUsage);
-    todo_wine
     ok(raw_devices[2].dwFlags == RIDEV_INPUTSINK, "Unexpected raw device flags: %x\n", raw_devices[1].dwFlags);
-    todo_wine
     ok(raw_devices[2].hwndTarget == di_hwnd, "Unexpected raw device target: %p\n", raw_devices[1].hwndTarget);
     hr = IDirectInputDevice8_Unacquire(di_keyboard);
     ok(SUCCEEDED(hr), "IDirectInputDevice8_Acquire failed: %08x\n", hr);
-- 
2.23.0.rc1




More information about the wine-devel mailing list