From: "Rémi Bernon" Subject: [PATCH 7/9] dinput8: Use raw input interface for dinput8 mouse device. Message-Id: <20190925093545.2612-8-rbernon@codeweavers.com> Date: Wed, 25 Sep 2019 11:35:43 +0200 In-Reply-To: <20190925093545.2612-1-rbernon@codeweavers.com> References: <20190925093545.2612-1-rbernon@codeweavers.com> Signed-off-by: Rémi Bernon --- dlls/dinput/mouse.c | 117 +++++++++++++++++++++++++++++++++++- dlls/dinput8/tests/device.c | 10 +-- 2 files changed, 119 insertions(+), 8 deletions(-) diff --git a/dlls/dinput/mouse.c b/dlls/dinput/mouse.c index 52a766b2a1a..a94fff0670b 100644 --- a/dlls/dinput/mouse.c +++ b/dlls/dinput/mouse.c @@ -246,6 +246,13 @@ static SysMouseImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput) list_add_tail(&dinput->devices_list, &newDevice->base.entry); LeaveCriticalSection(&dinput->crit); + if (dinput->dwVersion >= 0x0800) + { + newDevice->base.use_raw_input = TRUE; + newDevice->base.raw_device.usUsagePage = 1; /* HID generic device page */ + newDevice->base.raw_device.usUsage = 2; /* HID generic mouse */ + } + return newDevice; failed: @@ -318,7 +325,115 @@ static int dinput_mouse_hook( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM { MSLLHOOKSTRUCT *hook = (MSLLHOOKSTRUCT *)lparam; SysMouseImpl* This = impl_from_IDirectInputDevice8A(iface); - int wdata = 0, inst_id = -1, ret = 0; + int wdata = 0, inst_id = -1, ret = 0, i; + + if (wparam == RIM_INPUT || wparam == RIM_INPUTSINK) + { + RAWINPUTHEADER raw_header; + RAWINPUT raw_input; + UINT size; + POINT rel, pt; + + static const USHORT mouse_button_flags[] = + { + RI_MOUSE_BUTTON_1_DOWN, RI_MOUSE_BUTTON_1_UP, + RI_MOUSE_BUTTON_2_DOWN, RI_MOUSE_BUTTON_2_UP, + RI_MOUSE_BUTTON_3_DOWN, RI_MOUSE_BUTTON_3_UP, + RI_MOUSE_BUTTON_4_DOWN, RI_MOUSE_BUTTON_4_UP, + RI_MOUSE_BUTTON_5_DOWN, RI_MOUSE_BUTTON_5_UP + }; + + 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_TYPEMOUSE) + return 0; + + if (raw_header.dwSize > sizeof(raw_input)) + { + WARN( "Unexpected size for mouse 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; + } + + if (raw_input.data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP) + FIXME( "Unimplemented MOUSE_VIRTUAL_DESKTOP flag\n" ); + if (raw_input.data.mouse.usFlags & MOUSE_ATTRIBUTES_CHANGED) + FIXME( "Unimplemented MOUSE_ATTRIBUTES_CHANGED flag\n" ); + + EnterCriticalSection(&This->base.crit); + + rel.x = raw_input.data.mouse.lLastX; + rel.y = raw_input.data.mouse.lLastY; + if (raw_input.data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE) + { + GetCursorPos(&pt); + rel.x -= pt.x; + rel.y -= pt.y; + } + + This->m_state.lX += rel.x; + This->m_state.lY += rel.y; + + if (This->base.data_format.user_df->dwFlags & DIDF_ABSAXIS) + { + pt.x = This->m_state.lX; + pt.y = This->m_state.lY; + } + else + { + pt = rel; + } + + if (rel.x) + queue_event(iface, DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE) | DIDFT_RELAXIS, + pt.x, GetCurrentTime(), This->base.dinput->evsequence); + + if (rel.y) + queue_event(iface, DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE) | DIDFT_RELAXIS, + pt.y, GetCurrentTime(), This->base.dinput->evsequence); + + if (rel.x || rel.y) + { + if ((This->warp_override == WARP_FORCE_ON) || + (This->warp_override != WARP_DISABLE && (This->base.dwCoopLevel & DISCL_EXCLUSIVE))) + This->need_warp = TRUE; + } + + if (raw_input.data.mouse.usButtonFlags & RI_MOUSE_WHEEL) + { + This->m_state.lZ += (wdata = (SHORT)raw_input.data.mouse.usButtonData); + queue_event(iface, DIDFT_MAKEINSTANCE(WINE_MOUSE_Z_AXIS_INSTANCE) | DIDFT_RELAXIS, + wdata, GetCurrentTime(), This->base.dinput->evsequence); + ret = This->clipped; + } + + for (i = 0; i < ARRAY_SIZE(mouse_button_flags); ++i) + { + if (raw_input.data.mouse.usButtonFlags & mouse_button_flags[i]) + { + This->m_state.rgbButtons[i / 2] = 0x80 - (i % 2) * 0x80; + queue_event(iface, DIDFT_MAKEINSTANCE(WINE_MOUSE_BUTTONS_INSTANCE + (i / 2)) | DIDFT_PSHBUTTON, + This->m_state.rgbButtons[i / 2], GetCurrentTime(), This->base.dinput->evsequence); + } + } + + LeaveCriticalSection(&This->base.crit); + + return ret; + } TRACE("msg %lx @ (%d %d)\n", wparam, hook->pt.x, hook->pt.y); diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c index 72a59878d8a..2aadf5ddf9b 100644 --- a/dlls/dinput8/tests/device.c +++ b/dlls/dinput8/tests/device.c @@ -646,13 +646,9 @@ 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 == 2, "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 == di_hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget); @@ -662,6 +658,9 @@ static void test_mouse_keyboard(void) GetRegisteredRawInputDevices(NULL, &raw_devices_count, sizeof(RAWINPUTDEVICE)); ok(raw_devices_count == 0, "Unexpected raw devices registered: %d\n", raw_devices_count); + if (raw_devices[0].hwndTarget != NULL) + di_hwnd = raw_devices[0].hwndTarget; + /* expect dinput8 to take over any activated raw input devices */ raw_devices[0].usUsagePage = 0x01; raw_devices[0].usUsage = 0x05; @@ -689,9 +688,7 @@ static void test_mouse_keyboard(void) ok(hr == 3, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count); ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage); ok(raw_devices[0].usUsage == 2, "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 == di_hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget); ok(raw_devices[1].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[1].usUsagePage); ok(raw_devices[1].usUsage == 5, "Unexpected raw device usage: %x\n", raw_devices[1].usUsage); @@ -717,7 +714,6 @@ static void test_mouse_keyboard(void) todo_wine ok(hr == 1, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count); ok(raw_devices[0].usUsagePage == 1, "Unexpected raw device usage page: %x\n", raw_devices[0].usUsagePage); - todo_wine ok(raw_devices[0].usUsage == 5, "Unexpected raw device usage: %x\n", raw_devices[0].usUsage); ok(raw_devices[0].dwFlags == 0, "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags); ok(raw_devices[0].hwndTarget == hwnd, "Unexpected raw device target: %p\n", raw_devices[0].hwndTarget); -- 2.23.0