Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/dinput/dinput_main.c | 10 ++++ dlls/dinput/dinput_private.h | 1 + dlls/dinput/mouse.c | 90 ++++++++++++++++++++++++++++++++++++ dlls/dinput8/tests/device.c | 11 ++--- 4 files changed, 104 insertions(+), 8 deletions(-)
diff --git a/dlls/dinput/dinput_main.c b/dlls/dinput/dinput_main.c index cd1a11b02fb..1c4a26987f9 100644 --- a/dlls/dinput/dinput_main.c +++ b/dlls/dinput/dinput_main.c @@ -654,6 +654,16 @@ static LRESULT WINAPI di_em_win_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPAR size = GetRawInputData( (HRAWINPUT)lparam, RID_INPUT, &ri, &size, sizeof(RAWINPUTHEADER) ); if (size == (UINT)-1 || size < sizeof(RAWINPUTHEADER)) WARN( "Unable to read raw input data\n" ); + else if (ri.header.dwType == RIM_TYPEMOUSE) + { + EnterCriticalSection( &dinput_hook_crit ); + LIST_FOR_EACH_ENTRY( dev, &acquired_mouse_list, IDirectInputDeviceImpl, entry ) + { + if (!dev->use_raw_input) continue; + dinput_mouse_rawinput_hook( &dev->IDirectInputDevice8A_iface, wparam, lparam, &ri ); + } + LeaveCriticalSection( &dinput_hook_crit ); + } }
return DefWindowProcW( hwnd, msg, wparam, lparam ); diff --git a/dlls/dinput/dinput_private.h b/dlls/dinput/dinput_private.h index 06a439d6a41..c0c88da9674 100644 --- a/dlls/dinput/dinput_private.h +++ b/dlls/dinput/dinput_private.h @@ -73,6 +73,7 @@ extern void dinput_hooks_acquire_device(LPDIRECTINPUTDEVICE8W iface); extern void dinput_hooks_unacquire_device(LPDIRECTINPUTDEVICE8W iface); extern int dinput_mouse_hook(LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam); extern int dinput_keyboard_hook(LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam); +extern void dinput_mouse_rawinput_hook( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam, RAWINPUT *raw );
extern void check_dinput_hooks(LPDIRECTINPUTDEVICE8W, BOOL) DECLSPEC_HIDDEN; extern void check_dinput_events(void) DECLSPEC_HIDDEN; diff --git a/dlls/dinput/mouse.c b/dlls/dinput/mouse.c index 5e6f34f0eca..e50731fda41 100644 --- a/dlls/dinput/mouse.c +++ b/dlls/dinput/mouse.c @@ -239,6 +239,13 @@ static SysMouseImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput) newDevice->base.data_format.wine_df = df; IDirectInput_AddRef(&newDevice->base.dinput->IDirectInput7A_iface);
+ 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: @@ -306,6 +313,89 @@ const struct dinput_device mouse_device = { * SysMouseA (DInput Mouse support) */
+void dinput_mouse_rawinput_hook( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam, RAWINPUT *ri ) +{ + SysMouseImpl* This = impl_from_IDirectInputDevice8A( iface ); + POINT rel, pt; + DWORD seq; + int i, wdata = 0; + + 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 ); + + if (ri->data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP) + FIXME( "Unimplemented MOUSE_VIRTUAL_DESKTOP flag\n" ); + if (ri->data.mouse.usFlags & MOUSE_ATTRIBUTES_CHANGED) + FIXME( "Unimplemented MOUSE_ATTRIBUTES_CHANGED flag\n" ); + + EnterCriticalSection( &This->base.crit ); + seq = This->base.dinput->evsequence++; + + rel.x = ri->data.mouse.lLastX; + rel.y = ri->data.mouse.lLastY; + if (ri->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(), seq ); + + if (rel.y) + queue_event( iface, DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE) | DIDFT_RELAXIS, + pt.y, GetCurrentTime(), seq ); + + 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 (ri->data.mouse.usButtonFlags & RI_MOUSE_WHEEL) + { + This->m_state.lZ += (wdata = (SHORT)ri->data.mouse.usButtonData); + queue_event( iface, DIDFT_MAKEINSTANCE(WINE_MOUSE_Z_AXIS_INSTANCE) | DIDFT_RELAXIS, + wdata, GetCurrentTime(), seq ); + } + + for (i = 0; i < ARRAY_SIZE(mouse_button_flags); ++i) + { + if (ri->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(), seq ); + } + } + + LeaveCriticalSection( &This->base.crit ); +} + /* low-level mouse hook */ int dinput_mouse_hook( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam ) { diff --git a/dlls/dinput8/tests/device.c b/dlls/dinput8/tests/device.c index 6fe9a635510..80a7fe26c3b 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); @@ -723,7 +720,6 @@ static void test_mouse_keyboard(void) memset(raw_devices, 0, sizeof(raw_devices)); hr = GetRegisteredRawInputDevices(raw_devices, &raw_devices_count, sizeof(RAWINPUTDEVICE)); ok(hr == 3, "GetRegisteredRawInputDevices returned %d, raw_devices_count: %d\n", hr, raw_devices_count); - todo_wine ok(raw_devices[0].dwFlags == (RIDEV_CAPTUREMOUSE|RIDEV_NOLEGACY), "Unexpected raw device flags: %x\n", raw_devices[0].dwFlags); todo_wine ok(raw_devices[2].dwFlags == (RIDEV_NOHOTKEYS|RIDEV_NOLEGACY), "Unexpected raw device flags: %x\n", raw_devices[1].dwFlags); @@ -737,7 +733,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);