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 );