From aa8b27c396f926212689d18da91778f5f8821c6d Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Sat, 9 Mar 2024 10:46:02 +1100 Subject: [PATCH] Updated user32-rawinput-mouse patchset This update supersede user32-rawinput-mouse-experimental, removing. --- ...-MOUSEEVENTF_-ABSOLUTE-VIRTUALDESK-f.patch | 27 -- ...pport-for-absolute-rawinput-messages.patch | 26 -- ...rcing-relative-rawinput-mouse-positi.patch | 30 -- .../definition | 3 - ...rt-for-absolute-rawinput-mouse-messa.patch | 36 +++ ...e-MOUSEEVENTF_MOVE-flag-when-accumul.patch | 55 ++++ ...ort-XInput2-events-for-individual-wi.patch | 255 ----------------- ...rt-for-absolute-position-in-RawMoti.patch} | 52 +++- ...hardware_message-flags-for-rawinput-.patch | 122 ++++++++ ...hardware_message-flags-for-rawinput-.patch | 100 ------- ...k-of-mouse-device-and-pointer-butto.patch} | 121 ++++---- ...HWMSG_RAWINPUT-flags-only-when-RAWIN.patch | 244 ---------------- ...o-Raw-Motion-Button-events-in-the-de.patch | 229 +++++++++++++++ ...ending-RIM_TYPEMOUSE-through-__wine_.patch | 45 --- ...tive-RawMotion-events-position-unpr.patch} | 73 ++--- ...en-to-RawMotion-and-RawButton-events.patch | 264 ------------------ patches/user32-rawinput-mouse/definition | 1 - 17 files changed, 588 insertions(+), 1095 deletions(-) delete mode 100644 patches/user32-rawinput-mouse-experimental/0001-server-Clear-the-MOUSEEVENTF_-ABSOLUTE-VIRTUALDESK-f.patch delete mode 100644 patches/user32-rawinput-mouse-experimental/0002-user32-Add-support-for-absolute-rawinput-messages.patch delete mode 100644 patches/user32-rawinput-mouse-experimental/0003-server-Stop-enforcing-relative-rawinput-mouse-positi.patch delete mode 100644 patches/user32-rawinput-mouse-experimental/definition create mode 100644 patches/user32-rawinput-mouse/0001-server-Add-support-for-absolute-rawinput-mouse-messa.patch create mode 100644 patches/user32-rawinput-mouse/0002-winex11-Clear-the-MOUSEEVENTF_MOVE-flag-when-accumul.patch delete mode 100644 patches/user32-rawinput-mouse/0002-winex11.drv-Support-XInput2-events-for-individual-wi.patch rename patches/{user32-rawinput-mouse-experimental/0005-winex11.drv-Add-support-for-absolute-RawMotion-event.patch => user32-rawinput-mouse/0003-winex11-Add-support-for-absolute-position-in-RawMoti.patch} (55%) create mode 100644 patches/user32-rawinput-mouse/0004-server-Add-send_hardware_message-flags-for-rawinput-.patch delete mode 100644 patches/user32-rawinput-mouse/0005-server-Add-send_hardware_message-flags-for-rawinput-.patch rename patches/user32-rawinput-mouse/{0004-winex11.drv-Keep-track-of-pointer-and-device-button-.patch => 0005-winex11-Keep-track-of-mouse-device-and-pointer-butto.patch} (67%) delete mode 100644 patches/user32-rawinput-mouse/0006-user32-Set-SEND_HWMSG_RAWINPUT-flags-only-when-RAWIN.patch create mode 100644 patches/user32-rawinput-mouse/0006-winex11-Listen-to-Raw-Motion-Button-events-in-the-de.patch delete mode 100644 patches/user32-rawinput-mouse/0007-user32-Support-sending-RIM_TYPEMOUSE-through-__wine_.patch rename patches/{user32-rawinput-mouse-experimental/0006-winex11.drv-Send-relative-RawMotion-events-unprocess.patch => user32-rawinput-mouse/0007-winex11-Send-relative-RawMotion-events-position-unpr.patch} (50%) delete mode 100644 patches/user32-rawinput-mouse/0008-winex11.drv-Listen-to-RawMotion-and-RawButton-events.patch diff --git a/patches/user32-rawinput-mouse-experimental/0001-server-Clear-the-MOUSEEVENTF_-ABSOLUTE-VIRTUALDESK-f.patch b/patches/user32-rawinput-mouse-experimental/0001-server-Clear-the-MOUSEEVENTF_-ABSOLUTE-VIRTUALDESK-f.patch deleted file mode 100644 index 22ca512b..00000000 --- a/patches/user32-rawinput-mouse-experimental/0001-server-Clear-the-MOUSEEVENTF_-ABSOLUTE-VIRTUALDESK-f.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 021af6dcf439d70df46b9fc839c2cc0877b8e43c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Thu, 28 Oct 2021 09:11:02 +0200 -Subject: [PATCH] server: Clear the MOUSEEVENTF_(ABSOLUTE|VIRTUALDESK) flags. - -For rawinput messages, as user32 is currently only expecting relative -motion. ---- - server/queue.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/server/queue.c b/server/queue.c -index 1aedda1ca71..87b25820cfe 100644 ---- a/server/queue.c -+++ b/server/queue.c -@@ -1967,7 +1967,7 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons - raw_msg.message = WM_INPUT; - - raw_msg.info = input->mouse.info; -- raw_msg.flags = flags; -+ raw_msg.flags = flags & ~(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK); - raw_msg.rawinput.type = RIM_TYPEMOUSE; - raw_msg.rawinput.mouse.x = x - desktop->cursor.x; - raw_msg.rawinput.mouse.y = y - desktop->cursor.y; --- -2.43.0 - diff --git a/patches/user32-rawinput-mouse-experimental/0002-user32-Add-support-for-absolute-rawinput-messages.patch b/patches/user32-rawinput-mouse-experimental/0002-user32-Add-support-for-absolute-rawinput-messages.patch deleted file mode 100644 index e6abea3e..00000000 --- a/patches/user32-rawinput-mouse-experimental/0002-user32-Add-support-for-absolute-rawinput-messages.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0a849a6fcdab538be01d2eb3b0bb9c1dd42e9d6a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Mon, 25 Oct 2021 11:26:43 +0200 -Subject: [PATCH] user32: Add support for absolute rawinput messages. - ---- - dlls/win32u/rawinput.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/dlls/win32u/rawinput.c b/dlls/win32u/rawinput.c -index 81403771c4a..186bd1e52b1 100644 ---- a/dlls/win32u/rawinput.c -+++ b/dlls/win32u/rawinput.c -@@ -96,7 +96,8 @@ static bool rawinput_from_hardware_message( RAWINPUT *rawinput, const struct har - rawinput->header.hDevice = WINE_MOUSE_HANDLE; - rawinput->header.wParam = 0; - -- rawinput->data.mouse.usFlags = MOUSE_MOVE_RELATIVE; -+ rawinput->data.mouse.usFlags = msg_data->flags & MOUSEEVENTF_ABSOLUTE ? MOUSE_MOVE_ABSOLUTE : MOUSE_MOVE_RELATIVE; -+ if (msg_data->flags & MOUSEEVENTF_VIRTUALDESK) rawinput->data.mouse.usFlags |= MOUSE_VIRTUAL_DESKTOP; - rawinput->data.mouse.usButtonFlags = 0; - rawinput->data.mouse.usButtonData = 0; - for (i = 1; i < ARRAY_SIZE(button_flags); ++i) --- -2.35.1 - diff --git a/patches/user32-rawinput-mouse-experimental/0003-server-Stop-enforcing-relative-rawinput-mouse-positi.patch b/patches/user32-rawinput-mouse-experimental/0003-server-Stop-enforcing-relative-rawinput-mouse-positi.patch deleted file mode 100644 index 1e69b82a..00000000 --- a/patches/user32-rawinput-mouse-experimental/0003-server-Stop-enforcing-relative-rawinput-mouse-positi.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 7ab586e1da370ab17f5cc64dc97449a436f2fa5e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Mon, 25 Oct 2021 11:22:04 +0200 -Subject: [PATCH] server: Stop enforcing relative rawinput mouse positions. - ---- - server/queue.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/server/queue.c b/server/queue.c -index 87b25820cfe..a94bdf53939 100644 ---- a/server/queue.c -+++ b/server/queue.c -@@ -1967,10 +1967,10 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons - raw_msg.message = WM_INPUT; - - raw_msg.info = input->mouse.info; -- raw_msg.flags = flags & ~(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK); -+ raw_msg.flags = flags; - raw_msg.rawinput.type = RIM_TYPEMOUSE; -- raw_msg.rawinput.mouse.x = x - desktop->cursor.x; -- raw_msg.rawinput.mouse.y = y - desktop->cursor.y; -+ raw_msg.rawinput.mouse.x = (flags & MOUSEEVENTF_MOVE) ? input->mouse.x : 0; -+ raw_msg.rawinput.mouse.y = (flags & MOUSEEVENTF_MOVE) ? input->mouse.y : 0; - raw_msg.rawinput.mouse.data = input->mouse.data; - - enum_processes( queue_rawinput_message, &raw_msg ); --- -2.43.0 - diff --git a/patches/user32-rawinput-mouse-experimental/definition b/patches/user32-rawinput-mouse-experimental/definition deleted file mode 100644 index 279f41d0..00000000 --- a/patches/user32-rawinput-mouse-experimental/definition +++ /dev/null @@ -1,3 +0,0 @@ -Fixes: [45882] - Raw Input should use untransformed mouse values (affects Overwatch, several Source games). -Depends: user32-rawinput-mouse -Disabled: True diff --git a/patches/user32-rawinput-mouse/0001-server-Add-support-for-absolute-rawinput-mouse-messa.patch b/patches/user32-rawinput-mouse/0001-server-Add-support-for-absolute-rawinput-mouse-messa.patch new file mode 100644 index 00000000..d71e72fe --- /dev/null +++ b/patches/user32-rawinput-mouse/0001-server-Add-support-for-absolute-rawinput-mouse-messa.patch @@ -0,0 +1,36 @@ +From 22d786152100f510a69cf9a2153638c47af7f017 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?R=C3=A9mi=20Bernon?= +Date: Fri, 8 Mar 2024 10:48:31 +0100 +Subject: [PATCH 1/7] server: Add support for absolute rawinput mouse messages. + +--- + server/queue.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/server/queue.c b/server/queue.c +index 0e8653bedf0..67c03c10b40 100644 +--- a/server/queue.c ++++ b/server/queue.c +@@ -1811,7 +1811,9 @@ static void rawmouse_init( struct rawinput *header, RAWMOUSE *rawmouse, int x, i + header->wparam = 0; + header->usage = MAKELONG(HID_USAGE_GENERIC_MOUSE, HID_USAGE_PAGE_GENERIC); + +- rawmouse->usFlags = MOUSE_MOVE_RELATIVE; ++ rawmouse->usFlags = 0; ++ if (flags & MOUSEEVENTF_ABSOLUTE) rawmouse->usFlags |= MOUSE_MOVE_ABSOLUTE; ++ if (flags & MOUSEEVENTF_VIRTUALDESK) rawmouse->usFlags |= MOUSE_VIRTUAL_DESKTOP; + rawmouse->usButtonFlags = 0; + rawmouse->usButtonData = 0; + for (i = 1; i < ARRAY_SIZE(button_flags); ++i) +@@ -2044,7 +2046,7 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons + raw_msg.time = time; + raw_msg.message = WM_INPUT; + raw_msg.flags = flags; +- rawmouse_init( &raw_msg.rawinput, &raw_msg.data.mouse, x - desktop->cursor.x, y - desktop->cursor.y, ++ rawmouse_init( &raw_msg.rawinput, &raw_msg.data.mouse, input->mouse.x, input->mouse.y, + raw_msg.flags, input->mouse.data, input->mouse.info ); + + dispatch_rawinput_message( desktop, &raw_msg ); +-- +2.43.0 + diff --git a/patches/user32-rawinput-mouse/0002-winex11-Clear-the-MOUSEEVENTF_MOVE-flag-when-accumul.patch b/patches/user32-rawinput-mouse/0002-winex11-Clear-the-MOUSEEVENTF_MOVE-flag-when-accumul.patch new file mode 100644 index 00000000..d80a8c14 --- /dev/null +++ b/patches/user32-rawinput-mouse/0002-winex11-Clear-the-MOUSEEVENTF_MOVE-flag-when-accumul.patch @@ -0,0 +1,55 @@ +From 7a0030874b52ffdb0324b8f114190e909ee572cd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?R=C3=A9mi=20Bernon?= +Date: Fri, 8 Mar 2024 11:08:53 +0100 +Subject: [PATCH 2/7] winex11: Clear the MOUSEEVENTF_MOVE flag when + accumulating motion. + +--- + dlls/winex11.drv/mouse.c | 23 +++++++++++------------ + 1 file changed, 11 insertions(+), 12 deletions(-) + +diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c +index 7293480b635..45619d4970d 100644 +--- a/dlls/winex11.drv/mouse.c ++++ b/dlls/winex11.drv/mouse.c +@@ -1703,19 +1703,17 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input ) + values++; + } + +- input->mi.dx = round( x->value ); +- input->mi.dy = round( y->value ); +- +- TRACE( "event %f,%f value %f,%f input %d,%d\n", x_value, y_value, x->value, y->value, +- (int)input->mi.dx, (int)input->mi.dy ); +- +- x->value -= input->mi.dx; +- y->value -= input->mi.dy; +- +- if (!input->mi.dx && !input->mi.dy) ++ if (!(input->mi.dx = round( x->value )) && !(input->mi.dy = round( y->value ))) + { +- TRACE( "accumulating motion\n" ); +- return FALSE; ++ TRACE( "event %f,%f value %f,%f, accumulating motion\n", x_value, y_value, x->value, y->value ); ++ input->mi.dwFlags &= ~MOUSEEVENTF_MOVE; ++ } ++ else ++ { ++ TRACE( "event %f,%f value %f,%f, input %d,%d\n", x_value, y_value, x->value, y->value, ++ (int)input->mi.dx, (int)input->mi.dy ); ++ x->value -= input->mi.dx; ++ y->value -= input->mi.dy; + } + + return TRUE; +@@ -1743,6 +1741,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev ) + input.mi.dx = 0; + input.mi.dy = 0; + if (!map_raw_event_coords( event, &input )) return FALSE; ++ if (!(input.mi.dwFlags & MOUSEEVENTF_MOVE)) return FALSE; + + NtUserSendHardwareInput( 0, 0, &input, 0 ); + return TRUE; +-- +2.43.0 + diff --git a/patches/user32-rawinput-mouse/0002-winex11.drv-Support-XInput2-events-for-individual-wi.patch b/patches/user32-rawinput-mouse/0002-winex11.drv-Support-XInput2-events-for-individual-wi.patch deleted file mode 100644 index 725c5ab3..00000000 --- a/patches/user32-rawinput-mouse/0002-winex11.drv-Support-XInput2-events-for-individual-wi.patch +++ /dev/null @@ -1,255 +0,0 @@ -From e37bc9f0f5554b56861fd3971d1611e8f6db9448 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Thu, 23 Jan 2020 11:00:19 +0100 -Subject: [PATCH] winex11.drv: Support XInput2 events for individual windows. - -This will allow us to listen to the XInput version of several events, -which can bring additional information. ---- - dlls/winex11.drv/desktop.c | 2 ++ - dlls/winex11.drv/event.c | 7 +++++ - dlls/winex11.drv/mouse.c | 59 +++++++++++++++++++++++++++----------- - dlls/winex11.drv/window.c | 3 ++ - dlls/winex11.drv/x11drv.h | 12 +++++++- - 5 files changed, 66 insertions(+), 17 deletions(-) - -diff --git a/dlls/winex11.drv/desktop.c b/dlls/winex11.drv/desktop.c -index 687c0cf5a4c..01bd6a1b74a 100644 ---- a/dlls/winex11.drv/desktop.c -+++ b/dlls/winex11.drv/desktop.c -@@ -86,6 +86,8 @@ BOOL X11DRV_CreateDesktop( const WCHAR *name, UINT width, UINT height ) - 0, 0, width, height, 0, default_visual.depth, InputOutput, - default_visual.visual, CWEventMask | CWCursor | CWColormap, &win_attr ); - if (!win) return FALSE; -+ -+ x11drv_xinput_enable( display, win, win_attr.event_mask ); - XFlush( display ); - - X11DRV_init_desktop( win, width, height ); -diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c -index 97bec34b0ea..d2de3c53d79 100644 ---- a/dlls/winex11.drv/event.c -+++ b/dlls/winex11.drv/event.c -@@ -235,6 +235,13 @@ static Bool filter_event( Display *display, XEvent *event, char *arg ) - return (mask & QS_MOUSEBUTTON) != 0; - #ifdef GenericEvent - case GenericEvent: -+#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H -+ if (event->xcookie.extension == xinput2_opcode && -+ (event->xcookie.evtype == XI_RawMotion || -+ event->xcookie.evtype == XI_DeviceChanged)) -+ return (mask & QS_MOUSEMOVE) != 0; -+#endif -+ return (mask & QS_SENDMESSAGE) != 0; - #endif - case MotionNotify: - case EnterNotify: -diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c -index 911e93d8de1..820126a2c48 100644 ---- a/dlls/winex11.drv/mouse.c -+++ b/dlls/winex11.drv/mouse.c -@@ -280,20 +280,32 @@ void x11drv_xinput_init(void) - - - /*********************************************************************** -- * enable_xinput2 -+ * x11drv_xinput_enable - */ --static void enable_xinput2(void) -+void x11drv_xinput_enable( Display *display, Window window, long event_mask ) - { - struct x11drv_thread_data *data = x11drv_thread_data(); - XIEventMask mask; - XIDeviceInfo *pointer_info; - unsigned char mask_bits[XIMaskLen(XI_LASTEVENT)]; -+ enum xi2_state xi2_state = data ? data->xi2_state : xi_unknown; - int count; - -- TRACE( "state:%d\n", data->xi2_state ); -- if (data->xi2_state != xi_disabled) return; -+ TRACE( "state:%d window:%lx event_mask:%lx\n", xi2_state, window, event_mask ); - -- if (!pXIGetClientPointer( data->display, None, &data->xi2_core_pointer )) return; -+ if (xi2_state == xi_unavailable) return; -+ -+ if (window != DefaultRootWindow( display )) -+ { -+ mask.mask = mask_bits; -+ mask.mask_len = sizeof(mask_bits); -+ mask.deviceid = XIAllMasterDevices; -+ memset( mask_bits, 0, sizeof(mask_bits) ); -+ -+ pXISelectEvents( display, window, &mask, 1 ); -+ XSelectInput( display, window, event_mask ); -+ return; -+ } - - mask.mask = mask_bits; - mask.mask_len = sizeof(mask_bits); -@@ -303,8 +315,9 @@ static void enable_xinput2(void) - XISetMask( mask_bits, XI_RawMotion ); - XISetMask( mask_bits, XI_ButtonPress ); - -- pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask, 1 ); -+ pXISelectEvents( display, DefaultRootWindow( display ), &mask, 1 ); - -+ if (!data || !pXIGetClientPointer( data->display, None, &data->xi2_core_pointer )) return; - pointer_info = pXIQueryDevice( data->display, data->xi2_core_pointer, &count ); - update_relative_valuators( pointer_info->classes, pointer_info->num_classes ); - pXIFreeDeviceInfo( pointer_info ); -@@ -313,7 +326,7 @@ static void enable_xinput2(void) - * no XI_DeviceChanged events happened. If any hierarchy change occurred that - * might be relevant here (eg. user switching mice after (un)plugging), a - * XI_DeviceChanged event will point us to the right slave. So this list is -- * safe to be obtained statically at enable_xinput2() time. -+ * safe to be obtained statically at x11drv_xinput_enable() time. - */ - if (data->xi2_devices) pXIFreeDeviceInfo( data->xi2_devices ); - data->xi2_devices = pXIQueryDevice( data->display, XIAllDevices, &data->xi2_device_count ); -@@ -325,24 +338,37 @@ static void enable_xinput2(void) - #endif - - /*********************************************************************** -- * disable_xinput2 -+ * x11drv_xinput_disable - */ --static void disable_xinput2(void) -+void x11drv_xinput_disable( Display *display, Window window, long event_mask ) - { - #ifdef HAVE_X11_EXTENSIONS_XINPUT2_H - struct x11drv_thread_data *data = x11drv_thread_data(); -+ enum xi2_state xi2_state = data ? data->xi2_state : xi_unknown; - XIEventMask mask; - -- TRACE( "state:%d\n", data->xi2_state ); -- if (data->xi2_state != xi_enabled) return; -+ TRACE( "state:%d window:%lx event_mask:%lx\n", xi2_state, window, event_mask ); - -- data->xi2_state = xi_disabled; -+ if (xi2_state == xi_unavailable) return; -+ -+ if (window != DefaultRootWindow( display )) -+ { -+ mask.mask = NULL; -+ mask.mask_len = 0; -+ mask.deviceid = XIAllMasterDevices; -+ -+ pXISelectEvents( display, window, &mask, 1 ); -+ XSelectInput( display, window, event_mask ); -+ return; -+ } - - mask.mask = NULL; - mask.mask_len = 0; - mask.deviceid = XIAllDevices; - -- pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask, 1 ); -+ pXISelectEvents( display, DefaultRootWindow( display ), &mask, 1 ); -+ -+ if (!data) return; - pXIFreeDeviceInfo( data->xi2_devices ); - data->x_valuator.number = -1; - data->y_valuator.number = -1; -@@ -351,6 +377,7 @@ static void disable_xinput2(void) - data->xi2_devices = NULL; - data->xi2_core_pointer = 0; - data->xi2_current_slave = 0; -+ data->xi2_state = xi_disabled; - #endif - } - -@@ -383,7 +410,7 @@ static BOOL grab_clipping_window( const RECT *clip ) - } - - /* enable XInput2 unless we are already clipping */ -- if (!data->clipping_cursor) enable_xinput2(); -+ if (!data->clipping_cursor) x11drv_xinput_enable( data->display, DefaultRootWindow( data->display ), PointerMotionMask ); - - if (data->xi2_state != xi_enabled) - { -@@ -423,7 +450,7 @@ static BOOL grab_clipping_window( const RECT *clip ) - - if (!clipping_cursor) - { -- disable_xinput2(); -+ x11drv_xinput_disable( data->display, DefaultRootWindow( data->display ), PointerMotionMask ); - return FALSE; - } - clip_rect = *clip; -@@ -452,7 +479,7 @@ void ungrab_clipping_window(void) - if (clipping_cursor) XUngrabPointer( data->display, CurrentTime ); - clipping_cursor = FALSE; - data->clipping_cursor = FALSE; -- disable_xinput2(); -+ x11drv_xinput_disable( data->display, DefaultRootWindow( data->display ), PointerMotionMask ); - } - - /*********************************************************************** -diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c -index 53982bb8c3b..c2d7e850656 100644 ---- a/dlls/winex11.drv/window.c -+++ b/dlls/winex11.drv/window.c -@@ -362,6 +362,7 @@ static void sync_window_style( struct x11drv_win_data *data ) - int mask = get_window_attributes( data, &attr ); - - XChangeWindowAttributes( data->display, data->whole_window, mask, &attr ); -+ x11drv_xinput_enable( data->display, data->whole_window, attr.event_mask ); - } - } - -@@ -1680,6 +1681,7 @@ static void create_whole_window( struct x11drv_win_data *data ) - data->vis.visual, mask, &attr ); - if (!data->whole_window) goto done; - -+ x11drv_xinput_enable( data->display, data->whole_window, attr.event_mask ); - set_initial_wm_hints( data->display, data->whole_window ); - set_wm_hints( data ); - -@@ -2018,6 +2020,7 @@ BOOL X11DRV_CreateWindow( HWND hwnd ) - data->clip_window = XCreateWindow( data->display, root_window, 0, 0, 1, 1, 0, 0, - InputOnly, default_visual.visual, - CWOverrideRedirect | CWEventMask, &attr ); -+ x11drv_xinput_enable( data->display, data->clip_window, attr.event_mask ); - XFlush( data->display ); - NtUserSetProp( hwnd, clip_window_prop, (HANDLE)data->clip_window ); - X11DRV_DisplayDevices_RegisterEventHandlers(); -diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h -index fd69e55054c..1f96716b2ad 100644 ---- a/dlls/winex11.drv/x11drv.h -+++ b/dlls/winex11.drv/x11drv.h -@@ -263,6 +263,8 @@ extern void X11DRV_ThreadDetach(void); - extern void X11DRV_Xcursor_Init(void); - extern void x11drv_xinput_load(void); - extern void x11drv_xinput_init(void); -+extern void x11drv_xinput_enable( Display *display, Window window, long event_mask ); -+extern void x11drv_xinput_disable( Display *display, Window window, long event_mask ); - - extern DWORD copy_image_bits( BITMAPINFO *info, BOOL is_r8g8b8, XImage *image, - const struct gdi_image_bits *src_bits, struct gdi_image_bits *dst_bits, -@@ -377,6 +379,14 @@ struct x11drv_escape_flush_gl_drawable - * X11 USER driver - */ - -+enum xi2_state -+{ -+ xi_unavailable = -1, -+ xi_unknown, -+ xi_disabled, -+ xi_enabled -+}; -+ - struct x11drv_thread_data - { - Display *display; -@@ -392,7 +402,7 @@ struct x11drv_thread_data - Window clip_window; /* window used for cursor clipping */ - BOOL clipping_cursor; /* whether thread is currently clipping the cursor */ - #ifdef HAVE_X11_EXTENSIONS_XINPUT2_H -- enum { xi_unavailable = -1, xi_unknown, xi_disabled, xi_enabled } xi2_state; /* XInput2 state */ -+ enum xi2_state xi2_state; /* XInput2 state */ - void *xi2_devices; /* list of XInput2 devices (valid when state is enabled) */ - int xi2_device_count; - XIValuatorClassInfo x_valuator; --- -2.42.0 - diff --git a/patches/user32-rawinput-mouse-experimental/0005-winex11.drv-Add-support-for-absolute-RawMotion-event.patch b/patches/user32-rawinput-mouse/0003-winex11-Add-support-for-absolute-position-in-RawMoti.patch similarity index 55% rename from patches/user32-rawinput-mouse-experimental/0005-winex11.drv-Add-support-for-absolute-RawMotion-event.patch rename to patches/user32-rawinput-mouse/0003-winex11-Add-support-for-absolute-position-in-RawMoti.patch index a320a817..f1ebe919 100644 --- a/patches/user32-rawinput-mouse-experimental/0005-winex11.drv-Add-support-for-absolute-RawMotion-event.patch +++ b/patches/user32-rawinput-mouse/0003-winex11-Add-support-for-absolute-position-in-RawMoti.patch @@ -1,17 +1,18 @@ -From eef4aa97b1271118a95419cbca2870c0bfa6fbcd Mon Sep 17 00:00:00 2001 +From 25e8368ac3671ab0407e66bac00c19106296d474 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Thu, 28 Oct 2021 09:18:37 +0200 -Subject: [PATCH] winex11.drv: Add support for absolute RawMotion events. +Date: Fri, 8 Mar 2024 11:15:57 +0100 +Subject: [PATCH 3/7] winex11: Add support for absolute position in RawMotion + events. --- - dlls/winex11.drv/mouse.c | 26 +++++++++++++++++++++----- - 1 file changed, 21 insertions(+), 5 deletions(-) + dlls/winex11.drv/mouse.c | 36 ++++++++++++++++++++++++++++++------ + 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c -index ec12c8b1917..f10745a1ad0 100644 +index 45619d4970d..87007b837bd 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c -@@ -315,12 +315,18 @@ static void update_relative_valuators( XIAnyClassInfo **classes, int num_classes +@@ -240,12 +240,18 @@ static void update_relative_valuators( XIAnyClassInfo **classes, int num_classes { valuator = (XIValuatorClassInfo *)classes[num_classes]; if (classes[num_classes]->type != XIValuatorClass) continue; @@ -32,24 +33,32 @@ index ec12c8b1917..f10745a1ad0 100644 thread_data->x_valuator.value = 0; thread_data->y_valuator.value = 0; -@@ -1778,7 +1784,15 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input ) - if (thread_data->xi2_state != xi_enabled) return FALSE; - if (event->deviceid != thread_data->xi2_core_pointer) return FALSE; +@@ -1670,6 +1676,7 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input ) + { + struct x11drv_thread_data *thread_data = x11drv_thread_data(); + XIValuatorClassInfo *x = &thread_data->x_valuator, *y = &thread_data->y_valuator; ++ const UINT absolute_flags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK; + double x_value = 0, y_value = 0, x_scale, y_scale; + const double *values = event->valuators.values; + RECT virtual_rect; +@@ -1680,7 +1687,15 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input ) + if (!xinput2_available) return FALSE; + if (event->deviceid != thread_data->xinput2_pointer) return FALSE; - virtual_rect = NtUserGetVirtualScreenRect(); + if (x->mode == XIModeRelative && y->mode == XIModeRelative) -+ input->mi.dwFlags &= ~(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK); ++ input->mi.dwFlags &= ~absolute_flags; + else if (x->mode == XIModeAbsolute && y->mode == XIModeAbsolute) -+ input->mi.dwFlags |= MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK; ++ input->mi.dwFlags |= absolute_flags; + else + FIXME( "Unsupported relative/absolute X/Y axis mismatch\n." ); + -+ if (input->mi.dwFlags & MOUSEEVENTF_VIRTUALDESK) SetRect( &virtual_rect, 0, 0, 65535, 65535 ); ++ if (input->mi.dwFlags & MOUSEEVENTF_VIRTUALDESK) SetRect( &virtual_rect, 0, 0, UINT16_MAX, UINT16_MAX ); + else virtual_rect = NtUserGetVirtualScreenRect(); if (x->max <= x->min) x_scale = 1; else x_scale = (virtual_rect.right - virtual_rect.left) / (x->max - x->min); -@@ -1791,12 +1805,14 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input ) +@@ -1693,17 +1708,26 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input ) if (i == x->number) { x_value = *values; @@ -66,6 +75,19 @@ index ec12c8b1917..f10745a1ad0 100644 } values++; } + +- if (!(input->mi.dx = round( x->value )) && !(input->mi.dy = round( y->value ))) ++ if (input->mi.dwFlags & MOUSEEVENTF_ABSOLUTE) ++ { ++ input->mi.dx = round( x->value ); ++ input->mi.dy = round( y->value ); ++ TRACE( "event %f,%f value %f,%f absolute input %d,%d\n", x_value, y_value, x->value, y->value, ++ (int)input->mi.dx, (int)input->mi.dy ); ++ } ++ else if (!(input->mi.dx = round( x->value )) && !(input->mi.dy = round( y->value ))) + { + TRACE( "event %f,%f value %f,%f, accumulating motion\n", x_value, y_value, x->value, y->value ); + input->mi.dwFlags &= ~MOUSEEVENTF_MOVE; -- -2.40.1 +2.43.0 diff --git a/patches/user32-rawinput-mouse/0004-server-Add-send_hardware_message-flags-for-rawinput-.patch b/patches/user32-rawinput-mouse/0004-server-Add-send_hardware_message-flags-for-rawinput-.patch new file mode 100644 index 00000000..d4753e0f --- /dev/null +++ b/patches/user32-rawinput-mouse/0004-server-Add-send_hardware_message-flags-for-rawinput-.patch @@ -0,0 +1,122 @@ +From 5e9af0573526693cbc98ad8282b5f2023c6b5bf7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?R=C3=A9mi=20Bernon?= +Date: Mon, 26 Aug 2019 14:37:20 +0200 +Subject: [PATCH 4/7] server: Add send_hardware_message flags for rawinput + translation. + +--- + include/ntuser.h | 4 ++++ + server/protocol.def | 3 +-- + server/queue.c | 16 ++++++++++------ + 3 files changed, 15 insertions(+), 8 deletions(-) + +diff --git a/include/ntuser.h b/include/ntuser.h +index f947fec7fea..4ded432bd99 100644 +--- a/include/ntuser.h ++++ b/include/ntuser.h +@@ -1423,6 +1423,10 @@ struct hid_packet + + C_ASSERT(sizeof(struct hid_packet) == offsetof(struct hid_packet, data[0])); + ++#define SEND_HWMSG_INJECTED 1 ++#define SEND_HWMSG_NO_RAW 2 ++#define SEND_HWMSG_NO_MSG 4 ++ + struct send_hardware_input_params + { + UINT flags; +diff --git a/server/protocol.def b/server/protocol.def +index 7b21aa16636..8e483bf3bbf 100644 +--- a/server/protocol.def ++++ b/server/protocol.def +@@ -2126,7 +2126,7 @@ enum message_type + @REQ(send_hardware_message) + user_handle_t win; /* window handle */ + hw_input_t input; /* input data */ +- unsigned int flags; /* flags (see below) */ ++ unsigned int flags; /* flags (see ntuser.h) */ + VARARG(report,bytes); /* HID report data */ + @REPLY + int wait; /* do we need to wait for a reply? */ +@@ -2135,7 +2135,6 @@ enum message_type + int new_x; /* new cursor position */ + int new_y; + @END +-#define SEND_HWMSG_INJECTED 0x01 + + + /* Get a message from the current queue */ +diff --git a/server/queue.c b/server/queue.c +index 67c03c10b40..0687a7feac1 100644 +--- a/server/queue.c ++++ b/server/queue.c +@@ -1983,7 +1983,7 @@ static void dispatch_rawinput_message( struct desktop *desktop, struct rawinput_ + + /* queue a hardware message for a mouse event */ + static int queue_mouse_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input, +- unsigned int origin, struct msg_queue *sender ) ++ unsigned int origin, struct msg_queue *sender, unsigned int send_flags ) + { + const struct rawinput_device *device; + struct hardware_msg_data *msg_data; +@@ -2038,7 +2038,7 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons + y = desktop->cursor.y; + } + +- if ((foreground = get_foreground_thread( desktop, win ))) ++ if (!(send_flags & SEND_HWMSG_NO_RAW) && (foreground = get_foreground_thread( desktop, win ))) + { + memset( &raw_msg, 0, sizeof(raw_msg) ); + raw_msg.foreground = foreground; +@@ -2060,6 +2060,8 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons + return 0; + } + ++ if (send_flags & SEND_HWMSG_NO_MSG) return 0; ++ + for (i = 0; i < ARRAY_SIZE( messages ); i++) + { + if (!messages[i]) continue; +@@ -2091,7 +2093,7 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons + + /* queue a hardware message for a keyboard event */ + static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input, +- unsigned int origin, struct msg_queue *sender ) ++ unsigned int origin, struct msg_queue *sender, unsigned int send_flags ) + { + struct hw_msg_source source = { IMDT_KEYBOARD, origin }; + const struct rawinput_device *device; +@@ -2168,7 +2170,7 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c + break; + } + +- if ((foreground = get_foreground_thread( desktop, win ))) ++ if (!(send_flags & SEND_HWMSG_NO_RAW) && (foreground = get_foreground_thread( desktop, win ))) + { + struct rawinput_message raw_msg = {0}; + raw_msg.foreground = foreground; +@@ -2189,6 +2191,8 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c + return 0; + } + ++ if (send_flags & SEND_HWMSG_NO_MSG) return 0; ++ + if (!(msg = alloc_hardware_message( input->kbd.info, source, time, 0 ))) return 0; + msg_data = msg->data; + +@@ -2936,10 +2940,10 @@ DECL_HANDLER(send_hardware_message) + switch (req->input.type) + { + case INPUT_MOUSE: +- wait = queue_mouse_message( desktop, req->win, &req->input, origin, sender ); ++ wait = queue_mouse_message( desktop, req->win, &req->input, origin, sender, req->flags ); + break; + case INPUT_KEYBOARD: +- wait = queue_keyboard_message( desktop, req->win, &req->input, origin, sender ); ++ wait = queue_keyboard_message( desktop, req->win, &req->input, origin, sender, req->flags ); + break; + case INPUT_HARDWARE: + queue_custom_hardware_message( desktop, req->win, origin, &req->input ); +-- +2.43.0 + diff --git a/patches/user32-rawinput-mouse/0005-server-Add-send_hardware_message-flags-for-rawinput-.patch b/patches/user32-rawinput-mouse/0005-server-Add-send_hardware_message-flags-for-rawinput-.patch deleted file mode 100644 index e8275399..00000000 --- a/patches/user32-rawinput-mouse/0005-server-Add-send_hardware_message-flags-for-rawinput-.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 5afa48387aee90fcc968ae049a1d047271cf4ecc Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Mon, 26 Aug 2019 14:37:20 +0200 -Subject: [PATCH] server: Add send_hardware_message flags for rawinput - translation. - ---- - dlls/win32u/message.c | 2 ++ - server/protocol.def | 1 + - server/queue.c | 12 ++++++------ - 3 files changed, 9 insertions(+), 6 deletions(-) - -diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c -index d15f9af3f9f..5f7ac9189c3 100644 ---- a/dlls/win32u/message.c -+++ b/dlls/win32u/message.c -@@ -3463,6 +3463,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, const RAWINPUT *r - req->input.mouse.flags = input->mi.dwFlags; - req->input.mouse.time = input->mi.time; - req->input.mouse.info = input->mi.dwExtraInfo; -+ req->flags |= SEND_HWMSG_RAWINPUT; - affects_key_state = !!(input->mi.dwFlags & (MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP | - MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP | - MOUSEEVENTF_MIDDLEDOWN | MOUSEEVENTF_MIDDLEUP | -@@ -3474,6 +3475,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, const RAWINPUT *r - req->input.kbd.flags = input->ki.dwFlags; - req->input.kbd.time = input->ki.time; - req->input.kbd.info = input->ki.dwExtraInfo; -+ req->flags |= SEND_HWMSG_RAWINPUT; - affects_key_state = TRUE; - break; - case INPUT_HARDWARE: -diff --git a/server/protocol.def b/server/protocol.def -index 919297c818c..416fdf020fd 100644 ---- a/server/protocol.def -+++ b/server/protocol.def -@@ -2143,6 +2143,7 @@ enum message_type - int new_y; - @END - #define SEND_HWMSG_INJECTED 0x01 -+#define SEND_HWMSG_RAWINPUT 0x02 - - - /* Get a message from the current queue */ -diff --git a/server/queue.c b/server/queue.c -index fcc946ff0cb..f62593b096a 100644 ---- a/server/queue.c -+++ b/server/queue.c -@@ -1845,7 +1845,7 @@ done: - - /* queue a hardware message for a mouse event */ - static int queue_mouse_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input, -- unsigned int origin, struct msg_queue *sender ) -+ unsigned int origin, struct msg_queue *sender, unsigned int req_flags ) - { - const struct rawinput_device *device; - struct hardware_msg_data *msg_data; -@@ -1900,7 +1900,7 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons - y = desktop->cursor.y; - } - -- if ((foreground = get_foreground_thread( desktop, win ))) -+ if ((req_flags & SEND_HWMSG_RAWINPUT) && (foreground = get_foreground_thread( desktop, win ))) - { - memset( &raw_msg, 0, sizeof(raw_msg) ); - raw_msg.foreground = foreground; -@@ -1960,7 +1960,7 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons - - /* queue a hardware message for a keyboard event */ - static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input, -- unsigned int origin, struct msg_queue *sender ) -+ unsigned int origin, struct msg_queue *sender, unsigned int req_flags ) - { - struct hw_msg_source source = { IMDT_KEYBOARD, origin }; - const struct rawinput_device *device; -@@ -2038,7 +2038,7 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c - break; - } - -- if ((foreground = get_foreground_thread( desktop, win ))) -+ if ((req_flags & SEND_HWMSG_RAWINPUT) && (foreground = get_foreground_thread( desktop, win ))) - { - memset( &raw_msg, 0, sizeof(raw_msg) ); - raw_msg.foreground = foreground; -@@ -2664,10 +2664,10 @@ DECL_HANDLER(send_hardware_message) - switch (req->input.type) - { - case INPUT_MOUSE: -- reply->wait = queue_mouse_message( desktop, req->win, &req->input, origin, sender ); -+ reply->wait = queue_mouse_message( desktop, req->win, &req->input, origin, sender, req->flags ); - break; - case INPUT_KEYBOARD: -- reply->wait = queue_keyboard_message( desktop, req->win, &req->input, origin, sender ); -+ reply->wait = queue_keyboard_message( desktop, req->win, &req->input, origin, sender, req->flags ); - break; - case INPUT_HARDWARE: - queue_custom_hardware_message( desktop, req->win, origin, &req->input ); --- -2.40.1 - diff --git a/patches/user32-rawinput-mouse/0004-winex11.drv-Keep-track-of-pointer-and-device-button-.patch b/patches/user32-rawinput-mouse/0005-winex11-Keep-track-of-mouse-device-and-pointer-butto.patch similarity index 67% rename from patches/user32-rawinput-mouse/0004-winex11.drv-Keep-track-of-pointer-and-device-button-.patch rename to patches/user32-rawinput-mouse/0005-winex11-Keep-track-of-mouse-device-and-pointer-butto.patch index 637ede4e..a2805a3a 100644 --- a/patches/user32-rawinput-mouse/0004-winex11.drv-Keep-track-of-pointer-and-device-button-.patch +++ b/patches/user32-rawinput-mouse/0005-winex11-Keep-track-of-mouse-device-and-pointer-butto.patch @@ -1,7 +1,7 @@ -From 7fcbbbd139dc8504ca084e468afc436cfaee6ef1 Mon Sep 17 00:00:00 2001 +From f1a3f71d4de4721ec1760236215a213088961594 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Bernon?= Date: Thu, 19 Dec 2019 22:34:44 +0100 -Subject: [PATCH] winex11.drv: Keep track of pointer and device button +Subject: [PATCH 5/7] winex11: Keep track of mouse device and pointer button mappings. We are going to receive raw button events and we will need to apply the @@ -9,49 +9,69 @@ correct button mappings ourselves. Original patch by Andrew Eikum . --- - dlls/winex11.drv/keyboard.c | 23 ++++++--- - dlls/winex11.drv/mouse.c | 89 +++++++++++++++++++++++++++++++++- + configure.ac | 1 + + dlls/winex11.drv/keyboard.c | 24 +++++++-- + dlls/winex11.drv/mouse.c | 93 +++++++++++++++++++++++++++++++++- dlls/winex11.drv/x11drv.h | 1 + dlls/winex11.drv/x11drv_main.c | 1 + - 4 files changed, 106 insertions(+), 8 deletions(-) + 5 files changed, 114 insertions(+), 6 deletions(-) +diff --git a/configure.ac b/configure.ac +index 2b16df17bb8..93f6d57e686 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1201,6 +1201,7 @@ then + + dnl *** All of the following tests require X11/Xlib.h + AC_CHECK_HEADERS([X11/extensions/shape.h \ ++ X11/extensions/XInput.h \ + X11/extensions/XInput2.h \ + X11/extensions/XShm.h \ + X11/extensions/Xfixes.h \ diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c -index 5c7f6c37276..674d8d6db58 100644 +index 23f07b851a7..130b7e516a2 100644 --- a/dlls/winex11.drv/keyboard.c +++ b/dlls/winex11.drv/keyboard.c -@@ -1848,13 +1848,24 @@ BOOL X11DRV_MappingNotify( HWND dummy, XEvent *event ) +@@ -1838,11 +1838,7 @@ BOOL X11DRV_ActivateKeyboardLayout(HKL hkl, UINT flags) + return TRUE; + } + +- +-/*********************************************************************** +- * X11DRV_MappingNotify +- */ +-BOOL X11DRV_MappingNotify( HWND dummy, XEvent *event ) ++static BOOL X11DRV_KeyboardMappingNotify( HWND dummy, XEvent *event ) { HWND hwnd; -- XRefreshKeyboardMapping(&event->xmapping); -- X11DRV_InitKeyboard( event->xmapping.display ); +@@ -1856,6 +1852,24 @@ BOOL X11DRV_MappingNotify( HWND dummy, XEvent *event ) + return TRUE; + } + ++/*********************************************************************** ++ * X11DRV_MappingNotify ++ */ ++BOOL X11DRV_MappingNotify( HWND dummy, XEvent *event ) ++{ + switch (event->xmapping.request) + { + case MappingModifier: + case MappingKeyboard: -+ XRefreshKeyboardMapping( &event->xmapping ); -+ X11DRV_InitKeyboard( event->xmapping.display ); -+ -+ hwnd = get_focus(); -+ if (!hwnd) hwnd = get_active_window(); -+ NtUserPostMessage( hwnd, WM_INPUTLANGCHANGEREQUEST, -+ 0 /*FIXME*/, (LPARAM)NtUserGetKeyboardLayout(0) ); -+ break; -+ ++ return X11DRV_KeyboardMappingNotify( dummy, event ); + case MappingPointer: + X11DRV_InitMouse( event->xmapping.display ); + break; + } ++ ++ return TRUE; ++} ++ -- hwnd = get_focus(); -- if (!hwnd) hwnd = get_active_window(); -- NtUserPostMessage( hwnd, WM_INPUTLANGCHANGEREQUEST, -- 0 /*FIXME*/, (LPARAM)NtUserGetKeyboardLayout(0) ); - return TRUE; - } - + /*********************************************************************** + * VkKeyScanEx (X11DRV.@) diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c -index ab89f32a8a2..75d961423ba 100644 +index 87007b837bd..f10d3cfb2d6 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -30,6 +30,9 @@ @@ -79,7 +99,7 @@ index ab89f32a8a2..75d961423ba 100644 /*********************************************************************** * X11DRV_Xcursor_Init * -@@ -224,6 +235,70 @@ void set_window_cursor( Window window, HCURSOR handle ) +@@ -224,6 +235,75 @@ void set_window_cursor( Window window, HCURSOR handle ) XFlush( gdi_display ); } @@ -93,6 +113,8 @@ index ab89f32a8a2..75d961423ba 100644 +static struct mouse_button_mapping *pointer_mapping; +static struct mouse_button_mapping *device_mapping; + ++#ifdef HAVE_X11_EXTENSIONS_XINPUT_H ++ +static void update_pointer_mapping( Display *display ) +{ + struct mouse_button_mapping *tmp; @@ -106,14 +128,11 @@ index ab89f32a8a2..75d961423ba 100644 + tmp->button_count = ARRAY_SIZE( tmp->buttons ); + tmp->button_count = XGetPointerMapping( display, tmp->buttons, tmp->button_count ); + -+ tmp = InterlockedExchangePointer( (void**)&pointer_mapping, tmp ); -+ -+ free( tmp ); ++ free( InterlockedExchangePointer( (void**)&pointer_mapping, tmp ) ); +} + +static void update_device_mapping( Display *display, int deviceid ) +{ -+#ifdef HAVE_X11_EXTENSIONS_XINPUT_H + struct mouse_button_mapping *tmp; + XDevice *device; + @@ -134,47 +153,47 @@ index ab89f32a8a2..75d961423ba 100644 + tmp->button_count = ARRAY_SIZE( tmp->buttons ); + tmp->button_count = pXGetDeviceButtonMapping( display, device, tmp->buttons, tmp->button_count ); + -+ tmp = InterlockedExchangePointer( (void**)&device_mapping, tmp ); -+ -+ free( tmp ); ++ free( InterlockedExchangePointer( (void**)&device_mapping, tmp ) ); + + pXCloseDevice( display, device ); -+#endif +} + +void X11DRV_InitMouse( Display *display ) +{ + update_pointer_mapping( display ); +} ++ ++#else /* HAVE_X11_EXTENSIONS_XINPUT_H */ ++ ++void X11DRV_InitMouse( Display *display ) ++{ ++} ++ ++#endif /* HAVE_X11_EXTENSIONS_XINPUT_H */ ++ + #ifdef HAVE_X11_EXTENSIONS_XINPUT2_H /*********************************************************************** * update_relative_valuators -@@ -1677,6 +1752,8 @@ static BOOL X11DRV_DeviceChanged( XGenericEventCookie *xev ) - if (event->reason != XISlaveSwitch) return FALSE; +@@ -1669,6 +1749,8 @@ static BOOL X11DRV_DeviceChanged( XGenericEventCookie *xev ) + if (event->deviceid != data->xinput2_pointer) return FALSE; update_relative_valuators( event->classes, event->num_classes ); + update_device_mapping( event->display, event->sourceid ); + return TRUE; } -@@ -1764,13 +1841,12 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev ) - - #endif /* HAVE_X11_EXTENSIONS_XINPUT2_H */ - -- - /*********************************************************************** - * x11drv_xinput_load +@@ -1817,7 +1899,7 @@ static BOOL X11DRV_TouchEvent( HWND hwnd, XGenericEventCookie *xev ) */ - void x11drv_xinput_load(void) + void x11drv_xinput2_load(void) { -#if defined(SONAME_LIBXI) && defined(HAVE_X11_EXTENSIONS_XINPUT2_H) +#if defined(SONAME_LIBXI) int event, error; void *libxi_handle = dlopen( SONAME_LIBXI, RTLD_NOW ); -@@ -1786,11 +1862,20 @@ void x11drv_xinput_load(void) +@@ -1833,11 +1915,20 @@ void x11drv_xinput2_load(void) return; \ } @@ -196,10 +215,10 @@ index ab89f32a8a2..75d961423ba 100644 xinput2_available = XQueryExtension( gdi_display, "XInputExtension", &xinput2_opcode, &event, &error ); diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h -index 4d94f042ee1..7ad685dfafb 100644 +index 2f46522f59f..655c6847b92 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h -@@ -692,6 +692,7 @@ extern void retry_grab_clipping_window(void); +@@ -684,6 +684,7 @@ extern void retry_grab_clipping_window(void); extern void ungrab_clipping_window(void); extern void move_resize_window( HWND hwnd, int dir ); extern void X11DRV_InitKeyboard( Display *display ); @@ -208,10 +227,10 @@ index 4d94f042ee1..7ad685dfafb 100644 extern HWND *build_hwnd_list(void); diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c -index 573a41bbe96..0eb5a2e8d45 100644 +index 0925fe54b9c..4b4d5563b60 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c -@@ -704,6 +704,7 @@ static NTSTATUS x11drv_init( void *arg ) +@@ -699,6 +699,7 @@ static NTSTATUS x11drv_init( void *arg ) XkbUseExtension( gdi_display, NULL, NULL ); X11DRV_InitKeyboard( gdi_display ); @@ -220,5 +239,5 @@ index 573a41bbe96..0eb5a2e8d45 100644 init_user_driver(); -- -2.42.0 +2.43.0 diff --git a/patches/user32-rawinput-mouse/0006-user32-Set-SEND_HWMSG_RAWINPUT-flags-only-when-RAWIN.patch b/patches/user32-rawinput-mouse/0006-user32-Set-SEND_HWMSG_RAWINPUT-flags-only-when-RAWIN.patch deleted file mode 100644 index 9c87b541..00000000 --- a/patches/user32-rawinput-mouse/0006-user32-Set-SEND_HWMSG_RAWINPUT-flags-only-when-RAWIN.patch +++ /dev/null @@ -1,244 +0,0 @@ -From 1c5763ee8859e76c72b2247a846bdf9addf9b138 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Wed, 24 Mar 2021 23:29:28 +0100 -Subject: [PATCH] user32: Set SEND_HWMSG_RAWINPUT flags only when RAWINPUT is - set. - -So we can generate legacy messages only by calling __wine_send_input -with NULL rawinput, and generate WM_INPUT messages only by calling -__wine_send_input with INPUT_HARDWARE input type and a rawinput. ---- - dlls/win32u/input.c | 3 ++- - dlls/win32u/message.c | 4 ++-- - dlls/wineandroid.drv/keyboard.c | 3 ++- - dlls/wineandroid.drv/window.c | 5 +++-- - dlls/winemac.drv/keyboard.c | 3 ++- - dlls/winemac.drv/mouse.c | 3 ++- - dlls/winex11.drv/keyboard.c | 3 ++- - dlls/winex11.drv/mouse.c | 11 +++++++---- - 8 files changed, 22 insertions(+), 13 deletions(-) - -diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c -index 1f9e48423fc..dc8f44ee910 100644 ---- a/dlls/win32u/input.c -+++ b/dlls/win32u/input.c -@@ -655,6 +655,7 @@ UINT WINAPI NtUserSendInput( UINT count, INPUT *inputs, int size ) - { - UINT i; - NTSTATUS status = STATUS_SUCCESS; -+ RAWINPUT rawinput; - - if (size != sizeof(INPUT)) - { -@@ -684,7 +685,7 @@ UINT WINAPI NtUserSendInput( UINT count, INPUT *inputs, int size ) - update_mouse_coords( &input ); - /* fallthrough */ - case INPUT_KEYBOARD: -- status = send_hardware_message( 0, &input, NULL, SEND_HWMSG_INJECTED ); -+ status = send_hardware_message( 0, &input, &rawinput, SEND_HWMSG_INJECTED ); - break; - case INPUT_HARDWARE: - RtlSetLastWin32Error( ERROR_CALL_NOT_IMPLEMENTED ); -diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c -index 5f7ac9189c3..b60afaad475 100644 ---- a/dlls/win32u/message.c -+++ b/dlls/win32u/message.c -@@ -3463,7 +3463,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, const RAWINPUT *r - req->input.mouse.flags = input->mi.dwFlags; - req->input.mouse.time = input->mi.time; - req->input.mouse.info = input->mi.dwExtraInfo; -- req->flags |= SEND_HWMSG_RAWINPUT; -+ if (rawinput) req->flags |= SEND_HWMSG_RAWINPUT; - affects_key_state = !!(input->mi.dwFlags & (MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP | - MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP | - MOUSEEVENTF_MIDDLEDOWN | MOUSEEVENTF_MIDDLEUP | -@@ -3475,7 +3475,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, const RAWINPUT *r - req->input.kbd.flags = input->ki.dwFlags; - req->input.kbd.time = input->ki.time; - req->input.kbd.info = input->ki.dwExtraInfo; -- req->flags |= SEND_HWMSG_RAWINPUT; -+ if (rawinput) req->flags |= SEND_HWMSG_RAWINPUT; - affects_key_state = TRUE; - break; - case INPUT_HARDWARE: -diff --git a/dlls/wineandroid.drv/keyboard.c b/dlls/wineandroid.drv/keyboard.c -index 9f369094949..1606afb3f86 100644 ---- a/dlls/wineandroid.drv/keyboard.c -+++ b/dlls/wineandroid.drv/keyboard.c -@@ -671,6 +671,7 @@ static BOOL get_async_key_state( BYTE state[256] ) - - static void send_keyboard_input( HWND hwnd, WORD vkey, WORD scan, DWORD flags ) - { -+ RAWINPUT rawinput; - INPUT input; - - input.type = INPUT_KEYBOARD; -@@ -680,7 +681,7 @@ static void send_keyboard_input( HWND hwnd, WORD vkey, WORD scan, DWORD flags ) - input.ki.time = 0; - input.ki.dwExtraInfo = 0; - -- __wine_send_input( hwnd, &input, NULL ); -+ __wine_send_input( hwnd, &input, &rawinput ); - } - - /*********************************************************************** -diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c -index d62a2c53909..47a424b40b8 100644 ---- a/dlls/wineandroid.drv/window.c -+++ b/dlls/wineandroid.drv/window.c -@@ -421,6 +421,7 @@ static int process_events( DWORD mask ) - DPI_AWARENESS_CONTEXT context; - struct java_event *event, *next, *previous; - unsigned int count = 0; -+ RAWINPUT rawinput; - - assert( GetCurrentThreadId() == desktop_tid ); - -@@ -514,7 +515,7 @@ static int process_events( DWORD mask ) - } - SERVER_END_REQ; - } -- __wine_send_input( capture ? capture : event->data.motion.hwnd, &event->data.motion.input, NULL ); -+ __wine_send_input( capture ? capture : event->data.motion.hwnd, &event->data.motion.input, &rawinput ); - } - break; - -@@ -528,7 +529,7 @@ static int process_events( DWORD mask ) - event->data.kbd.input.ki.wVk, event->data.kbd.input.ki.wVk, - event->data.kbd.input.ki.wScan ); - update_keyboard_lock_state( event->data.kbd.input.ki.wVk, event->data.kbd.lock_state ); -- __wine_send_input( 0, &event->data.kbd.input, NULL ); -+ __wine_send_input( 0, &event->data.kbd.input, &rawinput ); - break; - - default: -diff --git a/dlls/winemac.drv/keyboard.c b/dlls/winemac.drv/keyboard.c -index c1963daa56e..14f0010e37e 100644 ---- a/dlls/winemac.drv/keyboard.c -+++ b/dlls/winemac.drv/keyboard.c -@@ -990,6 +990,7 @@ void macdrv_compute_keyboard_layout(struct macdrv_thread_data *thread_data) - */ - static void macdrv_send_keyboard_input(HWND hwnd, WORD vkey, WORD scan, unsigned int flags, unsigned int time) - { -+ RAWINPUT rawinput; - INPUT input; - - TRACE_(key)("hwnd %p vkey=%04x scan=%04x flags=%04x\n", hwnd, vkey, scan, flags); -@@ -1001,7 +1002,7 @@ static void macdrv_send_keyboard_input(HWND hwnd, WORD vkey, WORD scan, unsigned - input.ki.time = time; - input.ki.dwExtraInfo = 0; - -- __wine_send_input(hwnd, &input, NULL); -+ __wine_send_input(hwnd, &input, &rawinput); - } - - -diff --git a/dlls/winemac.drv/mouse.c b/dlls/winemac.drv/mouse.c -index 5c04c71e1dc..260831c44dc 100644 ---- a/dlls/winemac.drv/mouse.c -+++ b/dlls/winemac.drv/mouse.c -@@ -129,6 +129,7 @@ static const CFStringRef cocoa_cursor_names[] = - static void send_mouse_input(HWND hwnd, macdrv_window cocoa_window, UINT flags, int x, int y, - DWORD mouse_data, BOOL drag, unsigned long time) - { -+ RAWINPUT rawinput; - INPUT input; - HWND top_level_hwnd; - -@@ -158,7 +159,7 @@ static void send_mouse_input(HWND hwnd, macdrv_window cocoa_window, UINT flags, - input.mi.time = time; - input.mi.dwExtraInfo = 0; - -- __wine_send_input(top_level_hwnd, &input, NULL); -+ __wine_send_input(top_level_hwnd, &input, &rawinput); - } - - -diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c -index b54ca795954..231af33fd48 100644 ---- a/dlls/winex11.drv/keyboard.c -+++ b/dlls/winex11.drv/keyboard.c -@@ -1121,6 +1121,7 @@ static WORD EVENT_event_to_vkey( XIC xic, XKeyEvent *e) - */ - static void X11DRV_send_keyboard_input( HWND hwnd, WORD vkey, WORD scan, UINT flags, UINT time ) - { -+ RAWINPUT rawinput; - INPUT input; - - TRACE_(key)( "hwnd %p vkey=%04x scan=%04x flags=%04x\n", hwnd, vkey, scan, flags ); -@@ -1132,7 +1133,7 @@ static void X11DRV_send_keyboard_input( HWND hwnd, WORD vkey, WORD scan, UINT fl - input.ki.time = time; - input.ki.dwExtraInfo = 0; - -- __wine_send_input( hwnd, &input, NULL ); -+ __wine_send_input( hwnd, &input, &rawinput ); - } - - -diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c -index 33f6ac24af8..ca0092f21c1 100644 ---- a/dlls/winex11.drv/mouse.c -+++ b/dlls/winex11.drv/mouse.c -@@ -626,6 +626,7 @@ static void map_event_coords( HWND hwnd, Window window, Window event_root, int x - static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPUT *input ) - { - struct x11drv_win_data *data; -+ RAWINPUT rawinput; - - input->type = INPUT_MOUSE; - -@@ -633,7 +634,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU - { - struct x11drv_thread_data *thread_data = x11drv_thread_data(); - if (!thread_data->clipping_cursor || thread_data->clip_window != window) return; -- __wine_send_input( hwnd, input, NULL ); -+ __wine_send_input( hwnd, input, &rawinput ); - return; - } - -@@ -660,7 +661,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU - SERVER_END_REQ; - } - -- __wine_send_input( hwnd, input, NULL ); -+ __wine_send_input( hwnd, input, &rawinput ); - } - - #ifdef SONAME_LIBXCURSOR -@@ -1588,6 +1589,7 @@ void move_resize_window( HWND hwnd, int dir ) - { - MSG msg; - INPUT input; -+ RAWINPUT rawinput; - int x, y, rootX, rootY; - - if (!XQueryPointer( display, root_window, &root, &child, &rootX, &rootY, &x, &y, &xstate )) break; -@@ -1603,7 +1605,7 @@ void move_resize_window( HWND hwnd, int dir ) - input.mi.dwFlags = button_up_flags[button - 1] | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE; - input.mi.time = NtGetTickCount(); - input.mi.dwExtraInfo = 0; -- __wine_send_input( hwnd, &input, NULL ); -+ __wine_send_input( hwnd, &input, &rawinput ); - } - - while (NtUserPeekMessage( &msg, 0, 0, 0, PM_REMOVE )) -@@ -1816,6 +1818,7 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input ) - static BOOL X11DRV_RawMotion( XGenericEventCookie *xev ) - { - XIRawEvent *event = xev->data; -+ RAWINPUT rawinput; - INPUT input; - - if (broken_rawevents && is_old_motion_event( xev->serial )) -@@ -1833,7 +1836,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev ) - input.mi.dy = 0; - if (!map_raw_event_coords( event, &input )) return FALSE; - -- __wine_send_input( 0, &input, NULL ); -+ __wine_send_input( 0, &input, &rawinput ); - return TRUE; - } - --- -2.40.1 - diff --git a/patches/user32-rawinput-mouse/0006-winex11-Listen-to-Raw-Motion-Button-events-in-the-de.patch b/patches/user32-rawinput-mouse/0006-winex11-Listen-to-Raw-Motion-Button-events-in-the-de.patch new file mode 100644 index 00000000..08796093 --- /dev/null +++ b/patches/user32-rawinput-mouse/0006-winex11-Listen-to-Raw-Motion-Button-events-in-the-de.patch @@ -0,0 +1,229 @@ +From 1c3132e5307aead682883f5f7613d5811d38b53a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?R=C3=A9mi=20Bernon?= +Date: Mon, 25 Oct 2021 11:45:47 +0200 +Subject: [PATCH 6/7] winex11: Listen to Raw(Motion|Button) events in the + desktop thread. + +We still need to send "normal" input from the clipping window thread +to trigger low-level hooks callbacks when clipping cursor. This is for +instance used in our dinput implementation. +--- + dlls/winex11.drv/event.c | 10 ++++-- + dlls/winex11.drv/mouse.c | 73 ++++++++++++++++++++++++++++++++++++--- + dlls/winex11.drv/window.c | 4 +++ + dlls/winex11.drv/x11drv.h | 1 + + 4 files changed, 81 insertions(+), 7 deletions(-) + +diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c +index 8b02361aaff..f4e290f8b8f 100644 +--- a/dlls/winex11.drv/event.c ++++ b/dlls/winex11.drv/event.c +@@ -315,6 +315,10 @@ static enum event_merge_action merge_raw_motion_events( XIRawEvent *prev, XIRawE + */ + static enum event_merge_action merge_events( XEvent *prev, XEvent *next ) + { ++#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H ++ struct x11drv_thread_data *thread_data = x11drv_thread_data(); ++#endif ++ + switch (prev->type) + { + case ConfigureNotify: +@@ -346,19 +350,21 @@ static enum event_merge_action merge_events( XEvent *prev, XEvent *next ) + case GenericEvent: + if (next->xcookie.extension != xinput2_opcode) break; + if (next->xcookie.evtype != XI_RawMotion) break; +- if (x11drv_thread_data()->warp_serial) break; ++ if (thread_data->xinput2_rawinput) break; ++ if (thread_data->warp_serial) break; + return MERGE_KEEP; + } + break; + case GenericEvent: + if (prev->xcookie.extension != xinput2_opcode) break; + if (prev->xcookie.evtype != XI_RawMotion) break; ++ if (thread_data->xinput2_rawinput) break; + switch (next->type) + { + case GenericEvent: + if (next->xcookie.extension != xinput2_opcode) break; + if (next->xcookie.evtype != XI_RawMotion) break; +- if (x11drv_thread_data()->warp_serial) break; ++ if (thread_data->warp_serial) break; + return merge_raw_motion_events( prev->xcookie.data, next->xcookie.data ); + #endif + } +diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c +index f10d3cfb2d6..6557331df22 100644 +--- a/dlls/winex11.drv/mouse.c ++++ b/dlls/winex11.drv/mouse.c +@@ -343,6 +343,7 @@ static void update_relative_valuators( XIAnyClassInfo **classes, int num_classes + */ + void x11drv_xinput2_enable( Display *display, Window window ) + { ++ struct x11drv_thread_data *thread_data = x11drv_thread_data(); + XIEventMask mask; + unsigned char mask_bits[XIMaskLen(XI_LASTEVENT)]; + +@@ -357,7 +358,13 @@ void x11drv_xinput2_enable( Display *display, Window window ) + { + XISetMask( mask_bits, XI_DeviceChanged ); + XISetMask( mask_bits, XI_RawMotion ); +- XISetMask( mask_bits, XI_ButtonPress ); ++ if (!thread_data->xinput2_rawinput) ++ XISetMask( mask_bits, XI_ButtonPress ); ++ else ++ { ++ XISetMask( mask_bits, XI_RawButtonPress ); ++ XISetMask( mask_bits, XI_RawButtonRelease ); ++ } + } + else + { +@@ -375,10 +382,12 @@ void x11drv_xinput2_enable( Display *display, Window window ) + */ + void x11drv_xinput2_disable( Display *display, Window window ) + { ++ struct x11drv_thread_data *thread_data = x11drv_thread_data(); + unsigned char mask_bits[XIMaskLen(XI_LASTEVENT)]; + XIEventMask mask; + + if (!xinput2_available) return; ++ if (thread_data->xinput2_rawinput) return; + + mask.mask = mask_bits; + mask.mask_len = sizeof(mask_bits); +@@ -632,7 +641,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU + { + struct x11drv_thread_data *thread_data = x11drv_thread_data(); + if (!thread_data->clipping_cursor || thread_data->clip_window != window) return; +- NtUserSendHardwareInput( hwnd, 0, input, 0 ); ++ NtUserSendHardwareInput( hwnd, SEND_HWMSG_NO_RAW, input, 0 ); + return; + } + +@@ -659,7 +668,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU + SERVER_END_REQ; + } + +- NtUserSendHardwareInput( hwnd, 0, input, 0 ); ++ NtUserSendHardwareInput( hwnd, SEND_HWMSG_NO_RAW, input, 0 ); + } + + #ifdef SONAME_LIBXCURSOR +@@ -1602,7 +1611,7 @@ void move_resize_window( HWND hwnd, int dir ) + input.mi.dwFlags = button_up_flags[button - 1] | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE; + input.mi.time = NtGetTickCount(); + input.mi.dwExtraInfo = 0; +- NtUserSendHardwareInput( hwnd, 0, &input, 0 ); ++ NtUserSendHardwareInput( hwnd, SEND_HWMSG_NO_RAW, &input, 0 ); + } + + while (NtUserPeekMessage( &msg, 0, 0, 0, PM_REMOVE )) +@@ -1830,6 +1839,8 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input ) + */ + static BOOL X11DRV_RawMotion( XGenericEventCookie *xev ) + { ++ struct x11drv_thread_data *thread_data = x11drv_thread_data(); ++ UINT flags = thread_data->xinput2_rawinput ? SEND_HWMSG_NO_MSG : SEND_HWMSG_NO_RAW; + XIRawEvent *event = xev->data; + INPUT input; + +@@ -1849,7 +1860,55 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev ) + if (!map_raw_event_coords( event, &input )) return FALSE; + if (!(input.mi.dwFlags & MOUSEEVENTF_MOVE)) return FALSE; + +- NtUserSendHardwareInput( 0, 0, &input, 0 ); ++ NtUserSendHardwareInput( 0, flags, &input, 0 ); ++ return TRUE; ++} ++ ++/*********************************************************************** ++ * X11DRV_RawButtonEvent ++ */ ++static BOOL X11DRV_RawButtonEvent( XGenericEventCookie *cookie ) ++{ ++ struct x11drv_thread_data *thread_data = x11drv_thread_data(); ++ const UINT *button_data, *button_flags; ++ XIRawEvent *event = cookie->data; ++ int button = event->detail - 1; ++ INPUT input; ++ ++ if (!thread_data->xinput2_rawinput) return FALSE; ++ ++ if (!device_mapping || device_mapping->deviceid != event->sourceid) ++ update_device_mapping( event->display, event->sourceid ); ++ ++ if (button >= 0 && device_mapping) button = device_mapping->buttons[button] - 1; ++ if (button >= 0 && pointer_mapping) button = pointer_mapping->buttons[button] - 1; ++ ++ if (button < 0 || button >= NB_BUTTONS) return FALSE; ++ if (event->deviceid != thread_data->xinput2_pointer) return FALSE; ++ ++ TRACE( "raw button %u (raw: %u) %s\n", button, event->detail, event->evtype == XI_RawButtonRelease ? "up" : "down" ); ++ ++ if (event->evtype == XI_RawButtonRelease) ++ { ++ button_data = button_up_data; ++ button_flags = button_up_flags; ++ } ++ else ++ { ++ button_data = button_down_data; ++ button_flags = button_down_flags; ++ } ++ ++ input.type = INPUT_MOUSE; ++ input.mi.mouseData = button_data[button]; ++ input.mi.dwFlags = button_flags[button] | MOUSEEVENTF_MOVE; ++ input.mi.time = EVENT_x11_time_to_win32_time( event->time ); ++ input.mi.dwExtraInfo = 0; ++ input.mi.dx = 0; ++ input.mi.dy = 0; ++ map_raw_event_coords( event, &input ); ++ ++ NtUserSendHardwareInput( 0, SEND_HWMSG_NO_MSG, &input, 0 ); + return TRUE; + } + +@@ -1964,6 +2023,10 @@ BOOL X11DRV_GenericEvent( HWND hwnd, XEvent *xev ) + case XI_RawMotion: + ret = X11DRV_RawMotion( event ); + break; ++ case XI_RawButtonPress: ++ case XI_RawButtonRelease: ++ ret = X11DRV_RawButtonEvent( event ); ++ break; + + case XI_TouchBegin: + case XI_TouchUpdate: +diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c +index cbe4fc197d1..03ad33060ae 100644 +--- a/dlls/winex11.drv/window.c ++++ b/dlls/winex11.drv/window.c +@@ -2040,6 +2040,10 @@ BOOL X11DRV_CreateWindow( HWND hwnd ) + struct x11drv_thread_data *data = x11drv_init_thread_data(); + XSetWindowAttributes attr; + ++ /* listen to raw xinput event in the desktop window thread */ ++ data->xinput2_rawinput = TRUE; ++ x11drv_xinput2_enable( data->display, DefaultRootWindow( data->display ) ); ++ + /* create the cursor clipping window */ + attr.override_redirect = TRUE; + attr.event_mask = StructureNotifyMask | FocusChangeMask; +diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h +index 655c6847b92..37bd1d9d91c 100644 +--- a/dlls/winex11.drv/x11drv.h ++++ b/dlls/winex11.drv/x11drv.h +@@ -395,6 +395,7 @@ struct x11drv_thread_data + XIValuatorClassInfo x_valuator; + XIValuatorClassInfo y_valuator; + int xinput2_pointer; /* XInput2 master pointer device id */ ++ int xinput2_rawinput; /* XInput2 rawinput-only thread */ + #endif /* HAVE_X11_EXTENSIONS_XINPUT2_H */ + }; + +-- +2.43.0 + diff --git a/patches/user32-rawinput-mouse/0007-user32-Support-sending-RIM_TYPEMOUSE-through-__wine_.patch b/patches/user32-rawinput-mouse/0007-user32-Support-sending-RIM_TYPEMOUSE-through-__wine_.patch deleted file mode 100644 index ddacbc43..00000000 --- a/patches/user32-rawinput-mouse/0007-user32-Support-sending-RIM_TYPEMOUSE-through-__wine_.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 84e2d01ee1a616724d5a61ca95db13b309b752f5 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Thu, 25 Mar 2021 14:26:35 +0100 -Subject: [PATCH] user32: Support sending RIM_TYPEMOUSE through - __wine_send_input. - ---- - dlls/win32u/message.c | 6 ++++++ - server/queue.c | 3 +++ - 2 files changed, 9 insertions(+) - -diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c -index 99bae5280f6..ff8f5bd6d87 100644 ---- a/dlls/win32u/message.c -+++ b/dlls/win32u/message.c -@@ -3553,6 +3553,12 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, const RAWINPUT *r - case WM_INPUT_DEVICE_CHANGE: - switch (rawinput->header.dwType) - { -+ case RIM_TYPEMOUSE: -+ req->input.hw.mouse.x = rawinput->data.mouse.lLastX; -+ req->input.hw.mouse.y = rawinput->data.mouse.lLastY; -+ req->input.hw.mouse.data = rawinput->data.mouse.ulRawButtons; -+ req->input.hw.lparam = rawinput->data.mouse.usFlags; -+ break; - case RIM_TYPEHID: - req->input.hw.wparam = rawinput->header.wParam; - req->input.hw.hid.device = HandleToUlong( rawinput->header.hDevice ); -diff --git a/server/queue.c b/server/queue.c -index e234b5e8af9..1aedda1ca71 100644 ---- a/server/queue.c -+++ b/server/queue.c -@@ -2109,6 +2109,9 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c - raw_msg.rawinput.kbd.vkey = vkey; - raw_msg.rawinput.kbd.scan = input->kbd.scan; - -+ if (input->hw.msg == WM_INPUT && input->hw.rawinput.type == RIM_TYPEMOUSE) -+ msg_data->flags = input->hw.lparam; -+ - enum_processes( queue_rawinput_message, &raw_msg ); - release_object( foreground ); - } --- -2.43.0 - diff --git a/patches/user32-rawinput-mouse-experimental/0006-winex11.drv-Send-relative-RawMotion-events-unprocess.patch b/patches/user32-rawinput-mouse/0007-winex11-Send-relative-RawMotion-events-position-unpr.patch similarity index 50% rename from patches/user32-rawinput-mouse-experimental/0006-winex11.drv-Send-relative-RawMotion-events-unprocess.patch rename to patches/user32-rawinput-mouse/0007-winex11-Send-relative-RawMotion-events-position-unpr.patch index a3176bc7..bc0e0e2f 100644 --- a/patches/user32-rawinput-mouse-experimental/0006-winex11.drv-Send-relative-RawMotion-events-unprocess.patch +++ b/patches/user32-rawinput-mouse/0007-winex11-Send-relative-RawMotion-events-position-unpr.patch @@ -1,7 +1,8 @@ -From d45e910803dd78f892ddece1743849943d7c67f3 Mon Sep 17 00:00:00 2001 +From 63298efb1ad8f04f38f7e1bc518bec7786192d26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Mon, 25 Oct 2021 11:48:00 +0200 -Subject: [PATCH] winex11.drv: Send relative RawMotion events unprocessed. +Date: Fri, 8 Mar 2024 11:11:27 +0100 +Subject: [PATCH 7/7] winex11: Send relative RawMotion events position + unprocessed. This makes relative raw input independent from cursor speed, as it is the case on Windows. Absolute raw input is already translated to @@ -9,30 +10,31 @@ virtual desktop space, and cursor speed is meaningless in this case. This does not support mixed relative/absolute X/Y axis. --- - dlls/winex11.drv/mouse.c | 18 ++++++++++++------ - 1 file changed, 12 insertions(+), 6 deletions(-) + dlls/winex11.drv/mouse.c | 20 +++++++++++++++----- + 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c -index 4a42b3c85b6..e58ee125c95 100644 +index 6557331df22..d26ed5d794b 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c -@@ -1770,12 +1770,12 @@ static BOOL X11DRV_DeviceChanged( XGenericEventCookie *xev ) +@@ -1763,13 +1763,13 @@ static BOOL X11DRV_DeviceChanged( XGenericEventCookie *xev ) return TRUE; } -static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input ) -+static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input, RAWINPUT *rawinput ) ++static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input, BOOL send_raw ) { struct x11drv_thread_data *thread_data = x11drv_thread_data(); XIValuatorClassInfo *x = &thread_data->x_valuator, *y = &thread_data->y_valuator; ++ const double *values = event->valuators.values, *raw_values = event->raw_values; + const UINT absolute_flags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK; - double x_value = 0, y_value = 0, x_scale, y_scale; - const double *values = event->valuators.values; -+ const double *values = event->valuators.values, *raw_values = event->raw_values; + double x_raw = 0, y_raw = 0, x_value = 0, y_value = 0, x_scale, y_scale; RECT virtual_rect; int i; -@@ -1804,22 +1804,30 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input ) +@@ -1798,16 +1798,19 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input ) if (!XIMaskIsSet( event->valuators.mask, i )) continue; if (i == x->number) { @@ -52,35 +54,38 @@ index 4a42b3c85b6..e58ee125c95 100644 values++; } - input->mi.dx = round( x->value ); - input->mi.dy = round( y->value ); - -+ if (x->mode != XIModeAbsolute) rawinput->data.mouse.lLastX = x_raw; -+ else rawinput->data.mouse.lLastX = input->mi.dx; -+ if (y->mode != XIModeAbsolute) rawinput->data.mouse.lLastY = y_raw; -+ else rawinput->data.mouse.lLastY = input->mi.dy; -+ - TRACE( "event %f,%f value %f,%f input %d,%d\n", x_value, y_value, x->value, y->value, - (int)input->mi.dx, (int)input->mi.dy ); - -@@ -1858,7 +1866,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev ) +@@ -1818,6 +1821,13 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input ) + TRACE( "event %f,%f value %f,%f absolute input %d,%d\n", x_value, y_value, x->value, y->value, + (int)input->mi.dx, (int)input->mi.dy ); + } ++ else if (send_raw) ++ { ++ input->mi.dx = round( x_raw ); ++ input->mi.dy = round( y_raw ); ++ TRACE( "event %f,%f raw value %f,%f, raw input %d,%d\n", x_value, y_value, x_raw, y_raw, ++ (int)input->mi.dx, (int)input->mi.dy ); ++ } + else if (!(input->mi.dx = round( x->value )) && !(input->mi.dy = round( y->value ))) + { + TRACE( "event %f,%f value %f,%f, accumulating motion\n", x_value, y_value, x->value, y->value ); +@@ -1857,7 +1867,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev ) input.mi.dwExtraInfo = 0; input.mi.dx = 0; input.mi.dy = 0; - if (!map_raw_event_coords( event, &input )) return FALSE; -+ if (!map_raw_event_coords( event, &input, &rawinput )) return FALSE; ++ if (!map_raw_event_coords( event, &input, flags & SEND_HWMSG_NO_MSG )) return FALSE; + if (!(input.mi.dwFlags & MOUSEEVENTF_MOVE)) return FALSE; - if (!thread_data->xi2_rawinput_only) - __wine_send_input( 0, &input, NULL ); -@@ -1872,8 +1880,6 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev ) - rawinput.data.mouse.ulRawButtons = 0; - rawinput.data.mouse.usButtonData = 0; - rawinput.data.mouse.usButtonFlags = 0; -- rawinput.data.mouse.lLastX = input.mi.dx; -- rawinput.data.mouse.lLastY = input.mi.dy; - rawinput.data.mouse.ulExtraInformation = 0; + NtUserSendHardwareInput( 0, flags, &input, 0 ); +@@ -1906,7 +1916,7 @@ static BOOL X11DRV_RawButtonEvent( XGenericEventCookie *cookie ) + input.mi.dwExtraInfo = 0; + input.mi.dx = 0; + input.mi.dy = 0; +- map_raw_event_coords( event, &input ); ++ map_raw_event_coords( event, &input, TRUE ); - input.type = INPUT_HARDWARE; + NtUserSendHardwareInput( 0, SEND_HWMSG_NO_MSG, &input, 0 ); + return TRUE; -- -2.40.1 +2.43.0 diff --git a/patches/user32-rawinput-mouse/0008-winex11.drv-Listen-to-RawMotion-and-RawButton-events.patch b/patches/user32-rawinput-mouse/0008-winex11.drv-Listen-to-RawMotion-and-RawButton-events.patch deleted file mode 100644 index bd9ac41e..00000000 --- a/patches/user32-rawinput-mouse/0008-winex11.drv-Listen-to-RawMotion-and-RawButton-events.patch +++ /dev/null @@ -1,264 +0,0 @@ -From 1bf08ef753b4f7fc43e72aa71c20c1b952b83bb3 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Mon, 25 Oct 2021 11:45:47 +0200 -Subject: [PATCH] winex11.drv: Listen to RawMotion and RawButton* events in the - desktop thread. - -We still need to send "normal" input from the clipping window thread -to trigger low-level hooks callbacks when clipping cursor. This is for -instance used in our dinput implementation. ---- - dlls/winex11.drv/event.c | 10 +++- - dlls/winex11.drv/mouse.c | 105 +++++++++++++++++++++++++++++++++++--- - dlls/winex11.drv/window.c | 4 ++ - dlls/winex11.drv/x11drv.h | 1 + - 4 files changed, 111 insertions(+), 9 deletions(-) - -diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c -index f6d9041ca65..d11f75cf1a6 100644 ---- a/dlls/winex11.drv/event.c -+++ b/dlls/winex11.drv/event.c -@@ -318,6 +318,10 @@ static enum event_merge_action merge_raw_motion_events( XIRawEvent *prev, XIRawE - */ - static enum event_merge_action merge_events( XEvent *prev, XEvent *next ) - { -+#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H -+ struct x11drv_thread_data *thread_data = x11drv_thread_data(); -+#endif -+ - switch (prev->type) - { - case ConfigureNotify: -@@ -349,19 +353,21 @@ static enum event_merge_action merge_events( XEvent *prev, XEvent *next ) - case GenericEvent: - if (next->xcookie.extension != xinput2_opcode) break; - if (next->xcookie.evtype != XI_RawMotion) break; -- if (x11drv_thread_data()->warp_serial) break; -+ if (thread_data->xi2_rawinput_only) break; -+ if (thread_data->warp_serial) break; - return MERGE_KEEP; - } - break; - case GenericEvent: - if (prev->xcookie.extension != xinput2_opcode) break; - if (prev->xcookie.evtype != XI_RawMotion) break; -+ if (thread_data->xi2_rawinput_only) break; - switch (next->type) - { - case GenericEvent: - if (next->xcookie.extension != xinput2_opcode) break; - if (next->xcookie.evtype != XI_RawMotion) break; -- if (x11drv_thread_data()->warp_serial) break; -+ if (thread_data->warp_serial) break; - return merge_raw_motion_events( prev->xcookie.data, next->xcookie.data ); - #endif - } -diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c -index ca0092f21c1..0a1ce16381c 100644 ---- a/dlls/winex11.drv/mouse.c -+++ b/dlls/winex11.drv/mouse.c -@@ -388,7 +388,16 @@ void x11drv_xinput_enable( Display *display, Window window, long event_mask ) - memset( mask_bits, 0, sizeof(mask_bits) ); - XISetMask( mask_bits, XI_DeviceChanged ); - XISetMask( mask_bits, XI_RawMotion ); -- XISetMask( mask_bits, XI_ButtonPress ); -+ -+ if (data->xi2_rawinput_only) -+ { -+ XISetMask( mask_bits, XI_RawButtonPress ); -+ XISetMask( mask_bits, XI_RawButtonRelease ); -+ } -+ else -+ { -+ XISetMask( mask_bits, XI_ButtonPress ); -+ } - - pXISelectEvents( display, DefaultRootWindow( display ), &mask, 1 ); - -@@ -415,6 +424,7 @@ void x11drv_xinput_disable( Display *display, Window window, long event_mask ) - TRACE( "state:%d window:%lx event_mask:%lx\n", xi2_state, window, event_mask ); - - if (xi2_state == xi_unavailable) return; -+ if (data->xi2_rawinput_only) return; - - if (window != DefaultRootWindow( display )) - { -@@ -626,7 +636,6 @@ static void map_event_coords( HWND hwnd, Window window, Window event_root, int x - static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPUT *input ) - { - struct x11drv_win_data *data; -- RAWINPUT rawinput; - - input->type = INPUT_MOUSE; - -@@ -634,7 +643,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU - { - struct x11drv_thread_data *thread_data = x11drv_thread_data(); - if (!thread_data->clipping_cursor || thread_data->clip_window != window) return; -- __wine_send_input( hwnd, input, &rawinput ); -+ __wine_send_input( hwnd, input, NULL ); - return; - } - -@@ -661,7 +670,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU - SERVER_END_REQ; - } - -- __wine_send_input( hwnd, input, &rawinput ); -+ __wine_send_input( hwnd, input, NULL ); - } - - #ifdef SONAME_LIBXCURSOR -@@ -1589,7 +1598,6 @@ void move_resize_window( HWND hwnd, int dir ) - { - MSG msg; - INPUT input; -- RAWINPUT rawinput; - int x, y, rootX, rootY; - - if (!XQueryPointer( display, root_window, &root, &child, &rootX, &rootY, &x, &y, &xstate )) break; -@@ -1605,7 +1613,7 @@ void move_resize_window( HWND hwnd, int dir ) - input.mi.dwFlags = button_up_flags[button - 1] | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE; - input.mi.time = NtGetTickCount(); - input.mi.dwExtraInfo = 0; -- __wine_send_input( hwnd, &input, &rawinput ); -+ __wine_send_input( hwnd, &input, NULL ); - } - - while (NtUserPeekMessage( &msg, 0, 0, 0, PM_REMOVE )) -@@ -1817,6 +1825,7 @@ static BOOL map_raw_event_coords( XIRawEvent *event, INPUT *input ) - */ - static BOOL X11DRV_RawMotion( XGenericEventCookie *xev ) - { -+ struct x11drv_thread_data *thread_data = x11drv_thread_data(); - XIRawEvent *event = xev->data; - RAWINPUT rawinput; - INPUT input; -@@ -1836,7 +1845,85 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev ) - input.mi.dy = 0; - if (!map_raw_event_coords( event, &input )) return FALSE; - -- __wine_send_input( 0, &input, &rawinput ); -+ if (!thread_data->xi2_rawinput_only) -+ __wine_send_input( 0, &input, NULL ); -+ else -+ { -+ rawinput.header.dwType = RIM_TYPEMOUSE; -+ rawinput.header.dwSize = offsetof(RAWINPUT, data) + sizeof(RAWMOUSE); -+ rawinput.header.hDevice = ULongToHandle(1); /* WINE_MOUSE_HANDLE */ -+ rawinput.header.wParam = RIM_INPUT; -+ rawinput.data.mouse.usFlags = input.mi.dwFlags; -+ rawinput.data.mouse.ulRawButtons = 0; -+ rawinput.data.mouse.usButtonData = 0; -+ rawinput.data.mouse.usButtonFlags = 0; -+ rawinput.data.mouse.lLastX = input.mi.dx; -+ rawinput.data.mouse.lLastY = input.mi.dy; -+ rawinput.data.mouse.ulExtraInformation = 0; -+ -+ input.type = INPUT_HARDWARE; -+ input.hi.uMsg = WM_INPUT; -+ input.hi.wParamH = 0; -+ input.hi.wParamL = 0; -+ if (rawinput.data.mouse.lLastX || rawinput.data.mouse.lLastY) -+ __wine_send_input( 0, &input, &rawinput ); -+ } -+ -+ return TRUE; -+} -+ -+/*********************************************************************** -+ * X11DRV_RawButtonEvent -+ */ -+static BOOL X11DRV_RawButtonEvent( XGenericEventCookie *cookie ) -+{ -+ struct x11drv_thread_data *thread_data = x11drv_thread_data(); -+ XIRawEvent *event = cookie->data; -+ int button = event->detail - 1; -+ RAWINPUT rawinput; -+ INPUT input; -+ -+ if (!device_mapping || device_mapping->deviceid != event->sourceid) -+ update_device_mapping( event->display, event->sourceid ); -+ -+ if (button >= 0 && device_mapping) -+ button = device_mapping->buttons[button] - 1; -+ -+ if (button >= 0 && pointer_mapping) -+ button = pointer_mapping->buttons[button] - 1; -+ -+ if (button < 0 || button >= NB_BUTTONS) return FALSE; -+ if (thread_data->xi2_state != xi_enabled) return FALSE; -+ if (event->deviceid != thread_data->xi2_core_pointer) return FALSE; -+ -+ TRACE( "raw button %u (raw: %u) %s\n", button, event->detail, event->evtype == XI_RawButtonRelease ? "up" : "down" ); -+ -+ rawinput.header.dwType = RIM_TYPEMOUSE; -+ rawinput.header.dwSize = offsetof(RAWINPUT, data) + sizeof(RAWMOUSE); -+ rawinput.header.hDevice = ULongToHandle(1); /* WINE_MOUSE_HANDLE */ -+ rawinput.header.wParam = RIM_INPUT; -+ if (event->evtype == XI_RawButtonRelease) -+ { -+ rawinput.data.mouse.usFlags = button_up_flags[button]; -+ rawinput.data.mouse.ulRawButtons = button_up_data[button]; -+ } -+ else -+ { -+ rawinput.data.mouse.usFlags = button_down_flags[button]; -+ rawinput.data.mouse.ulRawButtons = button_down_data[button]; -+ } -+ rawinput.data.mouse.usButtonData = 0; -+ rawinput.data.mouse.usButtonFlags = 0; -+ rawinput.data.mouse.lLastX = 0; -+ rawinput.data.mouse.lLastY = 0; -+ rawinput.data.mouse.ulExtraInformation = 0; -+ -+ input.type = INPUT_HARDWARE; -+ input.hi.uMsg = WM_INPUT; -+ input.hi.wParamH = 0; -+ input.hi.wParamL = 0; -+ if (rawinput.data.mouse.usFlags || rawinput.data.mouse.ulRawButtons) -+ __wine_send_input( 0, &input, &rawinput ); - return TRUE; - } - -@@ -1912,6 +1999,10 @@ BOOL X11DRV_GenericEvent( HWND hwnd, XEvent *xev ) - case XI_RawMotion: - ret = X11DRV_RawMotion( event ); - break; -+ case XI_RawButtonPress: -+ case XI_RawButtonRelease: -+ ret = X11DRV_RawButtonEvent( event ); -+ break; - - default: - TRACE( "Unhandled event %#x\n", event->evtype ); -diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c -index f043e64047e..bf7afe0e8bf 100644 ---- a/dlls/winex11.drv/window.c -+++ b/dlls/winex11.drv/window.c -@@ -1999,6 +1999,10 @@ BOOL X11DRV_CreateWindow( HWND hwnd ) - struct x11drv_thread_data *data = x11drv_init_thread_data(); - XSetWindowAttributes attr; - -+ /* listen to raw xinput event in the desktop window thread */ -+ data->xi2_rawinput_only = TRUE; -+ x11drv_xinput_enable( data->display, DefaultRootWindow( data->display ), PointerMotionMask ); -+ - /* create the cursor clipping window */ - attr.override_redirect = TRUE; - attr.event_mask = StructureNotifyMask | FocusChangeMask; -diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h -index 8bbac23f88e..55b3049a7cc 100644 ---- a/dlls/winex11.drv/x11drv.h -+++ b/dlls/winex11.drv/x11drv.h -@@ -405,6 +405,7 @@ struct x11drv_thread_data - XIValuatorClassInfo x_valuator; - XIValuatorClassInfo y_valuator; - int xi2_core_pointer; /* XInput2 core pointer id */ -+ int xi2_rawinput_only; - #endif /* HAVE_X11_EXTENSIONS_XINPUT2_H */ - }; - --- -2.40.1 - diff --git a/patches/user32-rawinput-mouse/definition b/patches/user32-rawinput-mouse/definition index baadf8ee..dc3fe9f3 100644 --- a/patches/user32-rawinput-mouse/definition +++ b/patches/user32-rawinput-mouse/definition @@ -1,3 +1,2 @@ Fixes: [42631] Mouse drift, jump or don't react to small slow movements in Unity-engine games and Fallout 4 (partly fixed in Unity games, have walkaround in Fallout4 ) Fixes: [42675] Overwatch: Phantom mouse input / view pulled up to ceiling -Disabled: True