Adds the registry key `HKEY_CURRENT_USER\Software\Wine\Wayland Driver\unaccelerated_pointer` witch allows raw input. This makes it easier to calculate the same sensitivity in different games, use sensitivity calculators, and easily change values when changing DPI and do not depend on the compositor or OS.
For example, you want to set the sensitivity to half as much, and sensitivity curves in libinput are more difficult to calculate than in the games themselves.
Based on Proton and Wine-Staging patches by @rbernon.
-- v9: winewayland.drv: Add unaccelerated pointer support server: Add send_hardware_message flags for rawinput translation.
From: Grigory Vasilyev h0tc0d3@gmail.com
--- 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/winewayland.drv/wayland_keyboard.c | 9 ++++++--- dlls/winewayland.drv/wayland_pointer.c | 12 ++++++++---- dlls/winex11.drv/keyboard.c | 3 ++- dlls/winex11.drv/mouse.c | 11 +++++++---- include/wine/server_protocol.h | 4 ++-- server/protocol.def | 2 +- server/queue.c | 25 ++++++++++++------------- 13 files changed, 52 insertions(+), 35 deletions(-)
diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index 5b25086cb6f..7d2466fbefe 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; + struct hid_packet hid = {0};
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, SEND_HWMSG_INJECTED, &input, 0 ); + status = send_hardware_message( 0, SEND_HWMSG_INJECTED, &input, (LPARAM)&hid ); break; case INPUT_HARDWARE: RtlSetLastWin32Error( ERROR_CALL_NOT_IMPLEMENTED ); diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index d1f49ca3ed9..bc1fc48052c 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -3470,6 +3470,7 @@ NTSTATUS send_hardware_message( HWND hwnd, UINT flags, const INPUT *input, LPARA int prev_x, prev_y, new_x, new_y; NTSTATUS ret; BOOL wait, affects_key_state = FALSE; + struct hid_packet *hid = (struct hid_packet *)lparam;
info.type = MSG_HARDWARE; info.dest_tid = 0; @@ -3495,6 +3496,7 @@ NTSTATUS send_hardware_message( HWND hwnd, UINT flags, const INPUT *input, LPARA req->input.mouse.flags = input->mi.dwFlags; req->input.mouse.time = input->mi.time; req->input.mouse.info = input->mi.dwExtraInfo; + if (hid) req->flags |= SEND_HWMSG_RAWINPUT; affects_key_state = !!(input->mi.dwFlags & (MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP | MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP | MOUSEEVENTF_MIDDLEDOWN | MOUSEEVENTF_MIDDLEUP | @@ -3523,6 +3525,7 @@ NTSTATUS send_hardware_message( HWND hwnd, UINT flags, const INPUT *input, LPARA req->input.kbd.flags = input->ki.dwFlags & ~KEYEVENTF_SCANCODE; req->input.kbd.time = input->ki.time; req->input.kbd.info = input->ki.dwExtraInfo; + if (hid) req->flags |= SEND_HWMSG_RAWINPUT; affects_key_state = TRUE; break; case INPUT_HARDWARE: @@ -3533,7 +3536,6 @@ NTSTATUS send_hardware_message( HWND hwnd, UINT flags, const INPUT *input, LPARA case WM_INPUT: case WM_INPUT_DEVICE_CHANGE: { - struct hid_packet *hid = (struct hid_packet *)lparam; req->input.hw.hid = hid->head; wine_server_add_data( req, hid->data, hid->head.count * hid->head.length ); break; diff --git a/dlls/wineandroid.drv/keyboard.c b/dlls/wineandroid.drv/keyboard.c index b0380d147da..22725d5f884 100644 --- a/dlls/wineandroid.drv/keyboard.c +++ b/dlls/wineandroid.drv/keyboard.c @@ -672,6 +672,7 @@ static BOOL get_async_key_state( BYTE state[256] ) static void send_keyboard_input( HWND hwnd, WORD vkey, WORD scan, DWORD flags ) { INPUT input; + struct hid_packet hid = {0};
input.type = INPUT_KEYBOARD; input.ki.wVk = vkey; @@ -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;
- NtUserSendHardwareInput( hwnd, 0, &input, 0 ); + NtUserSendHardwareInput( hwnd, 0, &input, (LPARAM)&hid ); }
/*********************************************************************** diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index 764b202d6e5..45a273e54b1 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -418,6 +418,7 @@ static int process_events( DWORD mask ) { struct java_event *event, *next, *previous; unsigned int count = 0; + struct hid_packet hid = {0};
assert( GetCurrentThreadId() == desktop_tid );
@@ -504,7 +505,7 @@ static int process_events( DWORD mask ) } SERVER_END_REQ; } - NtUserSendHardwareInput( capture ? capture : event->data.motion.hwnd, 0, &event->data.motion.input, 0 ); + NtUserSendHardwareInput( capture ? capture : event->data.motion.hwnd, 0, &event->data.motion.input, (LPARAM)&hid ); } break;
@@ -518,7 +519,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 ); - NtUserSendHardwareInput( 0, 0, &event->data.kbd.input, 0 ); + NtUserSendHardwareInput( 0, 0, &event->data.kbd.input, (LPARAM)&hid ); break;
default: diff --git a/dlls/winemac.drv/keyboard.c b/dlls/winemac.drv/keyboard.c index 474ca499961..55a8db12f4f 100644 --- a/dlls/winemac.drv/keyboard.c +++ b/dlls/winemac.drv/keyboard.c @@ -991,6 +991,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) { INPUT input; + struct hid_packet hid = {0};
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;
- NtUserSendHardwareInput(hwnd, 0, &input, 0); + NtUserSendHardwareInput(hwnd, 0, &input, (LPARAM)&hid); }
diff --git a/dlls/winemac.drv/mouse.c b/dlls/winemac.drv/mouse.c index a87654e9885..3df08cce142 100644 --- a/dlls/winemac.drv/mouse.c +++ b/dlls/winemac.drv/mouse.c @@ -131,6 +131,7 @@ static void send_mouse_input(HWND hwnd, macdrv_window cocoa_window, UINT flags, { INPUT input; HWND top_level_hwnd; + struct hid_packet hid = {0};
top_level_hwnd = NtUserGetAncestor(hwnd, GA_ROOT);
@@ -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;
- NtUserSendHardwareInput(top_level_hwnd, 0, &input, 0); + NtUserSendHardwareInput(top_level_hwnd, 0, &input, (LPARAM)&hid); }
diff --git a/dlls/winewayland.drv/wayland_keyboard.c b/dlls/winewayland.drv/wayland_keyboard.c index bdef56e8f0c..957b1bda537 100644 --- a/dlls/winewayland.drv/wayland_keyboard.c +++ b/dlls/winewayland.drv/wayland_keyboard.c @@ -638,6 +638,7 @@ static void release_all_keys(HWND hwnd) BYTE state[256]; int vkey; INPUT input = {.type = INPUT_KEYBOARD}; + struct hid_packet hid = {0};
get_async_key_state(state);
@@ -656,7 +657,7 @@ static void release_all_keys(HWND hwnd) input.ki.wScan = scan & 0xff; input.ki.dwFlags = KEYEVENTF_KEYUP; if (scan & ~0xff) input.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY; - NtUserSendHardwareInput(hwnd, 0, &input, 0); + NtUserSendHardwareInput(hwnd, 0, &input, (LPARAM)&hid); } } } @@ -814,11 +815,12 @@ static void keyboard_handle_leave(void *data, struct wl_keyboard *wl_keyboard, static void send_right_control(HWND hwnd, uint32_t state) { INPUT input = {0}; + struct hid_packet hid = {0}; input.type = INPUT_KEYBOARD; input.ki.wScan = 0xe000 | (key2scan(KEY_RIGHTCTRL) & 0xff); input.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_EXTENDEDKEY; if (state == WL_KEYBOARD_KEY_STATE_RELEASED) input.ki.dwFlags |= KEYEVENTF_KEYUP; - NtUserSendHardwareInput(hwnd, 0, &input, 0); + NtUserSendHardwareInput(hwnd, 0, &input, (LPARAM)&hid); }
static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard, @@ -828,6 +830,7 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard, UINT scan = key2scan(key); INPUT input = {0}; HWND hwnd; + struct hid_packet hid = {0};
if (!(hwnd = wayland_keyboard_get_focused_hwnd())) return;
@@ -842,7 +845,7 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard, if (scan & ~0xff) input.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY;
if (state == WL_KEYBOARD_KEY_STATE_RELEASED) input.ki.dwFlags |= KEYEVENTF_KEYUP; - NtUserSendHardwareInput(hwnd, 0, &input, 0); + NtUserSendHardwareInput(hwnd, 0, &input, (LPARAM)&hid); }
static void keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboard, diff --git a/dlls/winewayland.drv/wayland_pointer.c b/dlls/winewayland.drv/wayland_pointer.c index 1d8acaeabd2..67f9e80f148 100644 --- a/dlls/winewayland.drv/wayland_pointer.c +++ b/dlls/winewayland.drv/wayland_pointer.c @@ -53,6 +53,7 @@ static void pointer_handle_motion_internal(wl_fixed_t sx, wl_fixed_t sy) HWND hwnd; POINT screen; struct wayland_surface *surface; + struct hid_packet hid = {0};
if (!(hwnd = wayland_pointer_get_focused_hwnd())) return; if (!(surface = wayland_surface_lock_hwnd(hwnd))) return; @@ -86,7 +87,7 @@ static void pointer_handle_motion_internal(wl_fixed_t sx, wl_fixed_t sy) hwnd, wl_fixed_to_double(sx), wl_fixed_to_double(sy), (int)screen.x, (int)screen.y);
- NtUserSendHardwareInput(hwnd, 0, &input, 0); + NtUserSendHardwareInput(hwnd, 0, &input, (LPARAM)&hid); }
static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer, @@ -153,6 +154,7 @@ static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer, struct wayland_pointer *pointer = &process_wayland.pointer; INPUT input = {0}; HWND hwnd; + struct hid_packet hid = {0};
if (!(hwnd = wayland_pointer_get_focused_hwnd())) return;
@@ -185,7 +187,7 @@ static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer,
TRACE("hwnd=%p button=%#x state=%u\n", hwnd, button, state);
- NtUserSendHardwareInput(hwnd, 0, &input, 0); + NtUserSendHardwareInput(hwnd, 0, &input, (LPARAM)&hid); }
static void pointer_handle_axis(void *data, struct wl_pointer *wl_pointer, @@ -212,6 +214,7 @@ static void pointer_handle_axis_discrete(void *data, struct wl_pointer *wl_point { INPUT input = {0}; HWND hwnd; + struct hid_packet hid = {0};
if (!(hwnd = wayland_pointer_get_focused_hwnd())) return;
@@ -232,7 +235,7 @@ static void pointer_handle_axis_discrete(void *data, struct wl_pointer *wl_point
TRACE("hwnd=%p axis=%u discrete=%d\n", hwnd, axis, discrete);
- NtUserSendHardwareInput(hwnd, 0, &input, 0); + NtUserSendHardwareInput(hwnd, 0, &input, (LPARAM)&hid); }
static const struct wl_pointer_listener pointer_listener = @@ -258,6 +261,7 @@ static void relative_pointer_v1_relative_motion(void *data, HWND hwnd; POINT screen, origin; struct wayland_surface *surface; + struct hid_packet hid = {0}; RECT window_rect;
if (!(hwnd = wayland_pointer_get_focused_hwnd())) return; @@ -317,7 +321,7 @@ static void relative_pointer_v1_relative_motion(void *data, hwnd, wl_fixed_to_double(dx), wl_fixed_to_double(dy), (int)screen.x, (int)screen.y);
- NtUserSendHardwareInput(hwnd, 0, &input, 0); + NtUserSendHardwareInput(hwnd, 0, &input, (LPARAM)&hid); }
static const struct zwp_relative_pointer_v1_listener relative_pointer_v1_listener = diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c index 23f07b851a7..5394c045fca 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 ) { INPUT input; + struct hid_packet hid = {0};
TRACE_(key)( "hwnd %p vkey=%04x scan=%04x flags=%04x\n", hwnd, vkey, scan, flags );
@@ -1131,7 +1132,7 @@ static void X11DRV_send_keyboard_input( HWND hwnd, WORD vkey, WORD scan, UINT fl input.ki.time = time; input.ki.dwExtraInfo = 0;
- NtUserSendHardwareInput( hwnd, 0, &input, 0 ); + NtUserSendHardwareInput( hwnd, 0, &input, (LPARAM)&hid ); }
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index 30444de0cdf..fd642398fc7 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -538,6 +538,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; + struct hid_packet hid = {0};
input->type = INPUT_MOUSE;
@@ -545,7 +546,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, 0, input, (LPARAM)&hid ); return; }
@@ -569,7 +570,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU SERVER_END_REQ; }
- NtUserSendHardwareInput( hwnd, 0, input, 0 ); + NtUserSendHardwareInput( hwnd, 0, input, (LPARAM)&hid ); }
#ifdef SONAME_LIBXCURSOR @@ -1457,6 +1458,7 @@ void move_resize_window( HWND hwnd, int dir ) XEvent xev; Window win, root, child; unsigned int xstate; + struct hid_packet hid = {0};
if (!(win = X11DRV_get_whole_window( hwnd ))) return;
@@ -1512,7 +1514,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, 0, &input, (LPARAM)&hid ); }
while (NtUserPeekMessage( &msg, 0, 0, 0, PM_REMOVE )) @@ -1724,6 +1726,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev ) { XIRawEvent *event = xev->data; INPUT input; + struct hid_packet hid = {0};
if (broken_rawevents && is_old_motion_event( xev->serial )) { @@ -1740,7 +1743,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev ) input.mi.dy = 0; if (!map_raw_event_coords( event, &input )) return FALSE;
- NtUserSendHardwareInput( 0, 0, &input, 0 ); + NtUserSendHardwareInput( 0, 0, &input, (LPARAM)&hid ); return TRUE; }
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 8a5ae71b856..e1c2d8907a5 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -2885,7 +2885,7 @@ struct send_hardware_message_reply char __pad_28[4]; }; #define SEND_HWMSG_INJECTED 0x01 - +#define SEND_HWMSG_RAWINPUT 0x02
struct get_message_request @@ -6534,7 +6534,7 @@ union generic_reply
/* ### protocol_version begin ### */
-#define SERVER_PROTOCOL_VERSION 806 +#define SERVER_PROTOCOL_VERSION 807
/* ### protocol_version end ### */
diff --git a/server/protocol.def b/server/protocol.def index 25184641082..721caa60d5f 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2161,7 +2161,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 */ @REQ(get_message) diff --git a/server/queue.c b/server/queue.c index 5a6f954bc4d..41629a7e0cf 100644 --- a/server/queue.c +++ b/server/queue.c @@ -1810,7 +1810,7 @@ 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; rawmouse->usButtonFlags = 0; rawmouse->usButtonData = 0; for (i = 1; i < ARRAY_SIZE(button_flags); ++i) @@ -1839,8 +1839,8 @@ static void rawmouse_init( struct rawinput *header, RAWMOUSE *rawmouse, int x, i }
rawmouse->ulRawButtons = 0; - rawmouse->lLastX = x; - rawmouse->lLastY = y; + rawmouse->lLastX = (flags & MOUSEEVENTF_MOVE) ? x : 0; + rawmouse->lLastY = (flags & MOUSEEVENTF_MOVE) ? y : 0; rawmouse->ulExtraInformation = info; }
@@ -1980,7 +1980,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 req_flags ) { struct hardware_msg_data *msg_data; struct rawinput_message raw_msg; @@ -2035,7 +2035,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; @@ -2043,7 +2043,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 ); @@ -2080,14 +2080,14 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons }
static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, const hw_input_t *input, - unsigned int origin, struct msg_queue *sender, int repeat ); + unsigned int origin, struct msg_queue *sender, int repeat, unsigned int req_flags );
static void key_repeat_timeout( void *private ) { struct desktop *desktop = private;
desktop->key_repeat.timeout = NULL; - queue_keyboard_message( desktop, desktop->key_repeat.win, &desktop->key_repeat.input, IMO_HARDWARE, NULL, 1 ); + queue_keyboard_message( desktop, desktop->key_repeat.win, &desktop->key_repeat.input, IMO_HARDWARE, NULL, 1, 0 ); }
static void stop_key_repeat( struct desktop *desktop ) @@ -2100,7 +2100,7 @@ static void stop_key_repeat( struct desktop *desktop )
/* 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, int repeat ) + unsigned int origin, struct msg_queue *sender, int repeat, unsigned int req_flags ) { struct hw_msg_source source = { IMDT_KEYBOARD, origin }; struct hardware_msg_data *msg_data; @@ -2222,8 +2222,7 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c desktop->key_repeat.timeout = add_timeout_user( timeout, key_repeat_timeout, desktop ); } } - - if (!unicode && (foreground = get_foreground_thread( desktop, win ))) + if ((req_flags & SEND_HWMSG_RAWINPUT) && !unicode && (foreground = get_foreground_thread( desktop, win ))) { struct rawinput_message raw_msg = {0}; raw_msg.foreground = foreground; @@ -2981,10 +2980,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, 0 ); + wait = queue_keyboard_message( desktop, req->win, &req->input, origin, sender, 0, req->flags ); break; case INPUT_HARDWARE: queue_custom_hardware_message( desktop, req->win, origin, &req->input );
From: Grigory Vasilyev h0tc0d3@gmail.com
Adds the registry key HKEY_CURRENT_USER\Software\Wine\Wayland Driver\unaccelerated_pointer witch allows raw input. This makes it easier to calculate the same sensitivity in different games, use sensitivity calculators, and easily change values when changing DPI and do not depend on the compositor or OS.
For example, you want to set the sensitivity to half as much, and sensitivity curves in libinput are more difficult to calculate than in the games themselves. --- dlls/winewayland.drv/Makefile.in | 1 + dlls/winewayland.drv/dllmain.c | 44 ++++++++++++++++++++++++++ dlls/winewayland.drv/unixlib.h | 1 + dlls/winewayland.drv/wayland_pointer.c | 29 ++++++++++++++--- dlls/winewayland.drv/waylanddrv_main.c | 10 ++++++ 5 files changed, 80 insertions(+), 5 deletions(-)
diff --git a/dlls/winewayland.drv/Makefile.in b/dlls/winewayland.drv/Makefile.in index 9ad1ad6889d..bee478257ae 100644 --- a/dlls/winewayland.drv/Makefile.in +++ b/dlls/winewayland.drv/Makefile.in @@ -2,6 +2,7 @@ MODULE = winewayland.drv UNIXLIB = winewayland.so UNIX_CFLAGS = $(EGL_CFLAGS) $(WAYLAND_CLIENT_CFLAGS) $(WAYLAND_EGL_CFLAGS) $(XKBCOMMON_CFLAGS) $(XKBREGISTRY_CFLAGS) UNIX_LIBS = -lwin32u $(WAYLAND_CLIENT_LIBS) $(WAYLAND_EGL_LIBS) $(XKBCOMMON_LIBS) $(XKBREGISTRY_LIBS) $(PTHREAD_LIBS) -lm +IMPORTS = advapi32
SOURCES = \ display.c \ diff --git a/dlls/winewayland.drv/dllmain.c b/dlls/winewayland.drv/dllmain.c index d040620957b..4fe2ba2561c 100644 --- a/dlls/winewayland.drv/dllmain.c +++ b/dlls/winewayland.drv/dllmain.c @@ -20,6 +20,7 @@
#include "waylanddrv_dll.h"
+#include "winreg.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(waylanddrv); @@ -38,12 +39,55 @@ static DWORD WINAPI wayland_read_events_thread(void *arg) BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved) { DWORD tid; + DWORD regRes; + DWORD regValueSize; + LPWSTR regValue = NULL; + HKEY hSubKey = NULL; + BOOL unaccelerated_pointer = FALSE;
if (reason != DLL_PROCESS_ATTACH) return TRUE;
DisableThreadLibraryCalls(instance); if (__wine_init_unix_call()) return FALSE;
+ regRes = RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\Wine\Wayland Driver", 0, KEY_READ, &hSubKey); + if (regRes != ERROR_SUCCESS) + { + WINE_TRACE("Registry key HKCU\Software\Wine\Wayland Driver not exist.\n"); + goto close_registry; + } + + regRes = RegQueryValueExW(hSubKey, L"unaccelerated_pointer", NULL, NULL, NULL, ®ValueSize); + if (regRes != ERROR_SUCCESS) + { + WINE_ERR("Can't get value size for HKCU\Software\Wine\Wayland Driver\unaccelerated_pointer. Error: %ld\n", regRes); + goto close_registry; + } + + regValue = calloc(regValueSize + 1, sizeof(*regValue)); + + regRes = RegQueryValueExW(hSubKey, L"unaccelerated_pointer", NULL, NULL, (LPBYTE)regValue, ®ValueSize); + if (regRes != ERROR_SUCCESS) + { + WINE_ERR("Can't get value for HKCU\Software\Wine\Wayland Driver\unaccelerated_pointer. Error: %ld\n", regRes); + free(regValue); + goto close_registry; + } + + WINE_TRACE("Registry HKCU\Software\Wine\Wayland Driver\unaccelerated_pointer value=%hs.\n", regValue); + if(*regValue) + unaccelerated_pointer = TRUE; + + free(regValue); + +close_registry: + RegCloseKey(hSubKey); + + if(unaccelerated_pointer) + WAYLANDDRV_UNIX_CALL(set_unaccelerated_pointer, &unaccelerated_pointer); + else + WAYLANDDRV_UNIX_CALL(set_unaccelerated_pointer, NULL); + if (WAYLANDDRV_UNIX_CALL(init, NULL)) return FALSE;
diff --git a/dlls/winewayland.drv/unixlib.h b/dlls/winewayland.drv/unixlib.h index dc3bfdf8893..53b8afada1d 100644 --- a/dlls/winewayland.drv/unixlib.h +++ b/dlls/winewayland.drv/unixlib.h @@ -27,6 +27,7 @@ enum waylanddrv_unix_func { waylanddrv_unix_func_init, waylanddrv_unix_func_read_events, + waylanddrv_unix_func_set_unaccelerated_pointer, waylanddrv_unix_func_count, };
diff --git a/dlls/winewayland.drv/wayland_pointer.c b/dlls/winewayland.drv/wayland_pointer.c index 67f9e80f148..c575ca4256d 100644 --- a/dlls/winewayland.drv/wayland_pointer.c +++ b/dlls/winewayland.drv/wayland_pointer.c @@ -30,10 +30,13 @@ #include <stdlib.h>
#include "waylanddrv.h" +#include "wine/server_protocol.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(waylanddrv);
+extern BOOL waylanddrv_unaccelerated_pointer; + static HWND wayland_pointer_get_focused_hwnd(void) { struct wayland_pointer *pointer = &process_wayland.pointer; @@ -263,15 +266,28 @@ static void relative_pointer_v1_relative_motion(void *data, struct wayland_surface *surface; struct hid_packet hid = {0}; RECT window_rect; + double delta_x; + double delta_y;
if (!(hwnd = wayland_pointer_get_focused_hwnd())) return; if (!(surface = wayland_surface_lock_hwnd(hwnd))) return;
window_rect = surface->window.rect;
+ if(waylanddrv_unaccelerated_pointer) + { + delta_x = wl_fixed_to_double(dx_unaccel); + delta_y = wl_fixed_to_double(dy_unaccel); + } + else + { + delta_x = wl_fixed_to_double(dx); + delta_y = wl_fixed_to_double(dy); + } + wayland_surface_coords_to_window(surface, - wl_fixed_to_double(dx), - wl_fixed_to_double(dy), + delta_x, + delta_y, (int *)&screen.x, (int *)&screen.y);
pthread_mutex_unlock(&surface->mutex); @@ -317,11 +333,14 @@ static void relative_pointer_v1_relative_motion(void *data, input.mi.dy = screen.y; input.mi.dwFlags = MOUSEEVENTF_MOVE;
- TRACE("hwnd=%p wayland_dxdy=%.2f,%.2f screen_dxdy=%d,%d\n", - hwnd, wl_fixed_to_double(dx), wl_fixed_to_double(dy), + TRACE("hwnd=%p unaccelerated_pointer=%d wayland_dxdy=%.2f,%.2f screen_dxdy=%d,%d\n", + hwnd, waylanddrv_unaccelerated_pointer, delta_x, delta_y, (int)screen.x, (int)screen.y);
- NtUserSendHardwareInput(hwnd, 0, &input, (LPARAM)&hid); + if(waylanddrv_unaccelerated_pointer) + NtUserSendHardwareInput(hwnd, SEND_HWMSG_RAWINPUT, &input, (LPARAM)&hid); + else + NtUserSendHardwareInput(hwnd, 0, &input, (LPARAM)&hid); }
static const struct zwp_relative_pointer_v1_listener relative_pointer_v1_listener = diff --git a/dlls/winewayland.drv/waylanddrv_main.c b/dlls/winewayland.drv/waylanddrv_main.c index 47c1299dd01..9064408f16e 100644 --- a/dlls/winewayland.drv/waylanddrv_main.c +++ b/dlls/winewayland.drv/waylanddrv_main.c @@ -80,6 +80,14 @@ static void wayland_init_process_name(void) } }
+BOOL waylanddrv_unaccelerated_pointer; + +static NTSTATUS waylanddrv_unix_set_unaccelerated_pointer(void *arg) +{ + waylanddrv_unaccelerated_pointer = arg ? *((BOOL *)arg) : FALSE; + return 0; +} + static NTSTATUS waylanddrv_unix_init(void *arg) { /* Set the user driver functions now so that they are available during @@ -111,6 +119,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] = { waylanddrv_unix_init, waylanddrv_unix_read_events, + waylanddrv_unix_set_unaccelerated_pointer, };
C_ASSERT(ARRAYSIZE(__wine_unix_call_funcs) == waylanddrv_unix_func_count); @@ -121,6 +130,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = { waylanddrv_unix_init, waylanddrv_unix_read_events, + waylanddrv_unix_set_unaccelerated_pointer, };
C_ASSERT(ARRAYSIZE(__wine_unix_call_wow64_funcs) == waylanddrv_unix_func_count);
This merge request was closed by Grigory Vasilyev.