This is an alternative approach, to illustrate what I described here:
https://www.winehq.org/pipermail/wine-devel/2019-November/154283.html
This is more change that the two request flags in the previous implementation, but it may be righter. In particular, I'm thinking that it's good to reduce the native driver dependency on user32, for instance for the PE conversion, but that may not be the target.
I skipped the wait for message reply, I'm assuming here a bit blindly that it's alright: the events come from external source anyway so there should not be any synchronization requirement.
I also skipped the thread local key_state update on keyboard events, It can still be done in the drivers if it's an important optimization.
Rémi Bernon (6): wineandroid.drv: Replace __wine_send_input with direct send_hardware_message request. winemac.drv: Replace __wine_send_input with direct send_hardware_message request. winex11.drv: Replace __wine_send_input with direct send_hardware_message request. user32: Remove __wine_send_input function. server: Add src field to hw_input_t, replace SEND_HWMSG_INJECTED. server: Replace send_hardware_message SEND_HWMSG_INJECTED flag.
dlls/user32/input.c | 17 +--- dlls/user32/message.c | 10 ++- dlls/user32/user32.spec | 1 - dlls/user32/user_private.h | 2 +- dlls/wineandroid.drv/keyboard.c | 23 ++--- dlls/wineandroid.drv/window.c | 31 ++++++- dlls/winemac.drv/ime.c | 32 ++++--- dlls/winemac.drv/keyboard.c | 23 ++--- dlls/winemac.drv/mouse.c | 23 +++-- dlls/winex11.drv/keyboard.c | 23 ++--- dlls/winex11.drv/mouse.c | 145 ++++++++++++++------------------ include/winuser.h | 4 - server/protocol.def | 16 ++-- server/queue.c | 28 ++++-- server/trace.c | 20 +++-- 15 files changed, 216 insertions(+), 182 deletions(-)
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/wineandroid.drv/keyboard.c | 23 +++++++++++++---------- dlls/wineandroid.drv/window.c | 31 +++++++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 12 deletions(-)
diff --git a/dlls/wineandroid.drv/keyboard.c b/dlls/wineandroid.drv/keyboard.c index 2c37c42e0d4..5c9ed2442df 100644 --- a/dlls/wineandroid.drv/keyboard.c +++ b/dlls/wineandroid.drv/keyboard.c @@ -671,16 +671,19 @@ static BOOL get_async_key_state( BYTE state[256] )
static void send_keyboard_input( HWND hwnd, WORD vkey, WORD scan, DWORD flags ) { - INPUT input; - - input.type = INPUT_KEYBOARD; - input.u.ki.wVk = vkey; - input.u.ki.wScan = scan; - input.u.ki.dwFlags = flags; - input.u.ki.time = 0; - input.u.ki.dwExtraInfo = 0; - - __wine_send_input( hwnd, &input ); + SERVER_START_REQ( send_hardware_message ) + { + req->win = wine_server_user_handle( hwnd ); + req->flags = 0; + req->input.type = INPUT_KEYBOARD; + req->input.kbd.vkey = vkey; + req->input.kbd.scan = scan; + req->input.kbd.flags = flags; + req->input.kbd.time = 0; + req->input.kbd.info = 0; + wine_server_call( req ); + } + SERVER_END_REQ; }
/*********************************************************************** diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index eb05aaf2832..2b757636847 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -521,7 +521,21 @@ static int process_events( DWORD mask ) } SERVER_END_REQ; } - __wine_send_input( capture ? capture : event->data.motion.hwnd, &event->data.motion.input ); + + SERVER_START_REQ( send_hardware_message ) + { + req->win = wine_server_user_handle( capture ? capture : event->data.motion.hwnd ); + req->flags = 0; + req->input.type = INPUT_MOUSE; + req->input.mouse.x = event->data.motion.input.u.mi.dx; + req->input.mouse.y = event->data.motion.input.u.mi.dy; + req->input.mouse.data = event->data.motion.input.u.mi.mouseData; + req->input.mouse.flags = event->data.motion.input.u.mi.dwFlags; + req->input.mouse.time = event->data.motion.input.u.mi.time; + req->input.mouse.info = event->data.motion.input.u.mi.dwExtraInfo; + wine_server_call( req ); + } + SERVER_END_REQ; } break;
@@ -535,7 +549,20 @@ static int process_events( DWORD mask ) event->data.kbd.input.u.ki.wVk, event->data.kbd.input.u.ki.wVk, event->data.kbd.input.u.ki.wScan ); update_keyboard_lock_state( event->data.kbd.input.u.ki.wVk, event->data.kbd.lock_state ); - __wine_send_input( 0, &event->data.kbd.input ); + + SERVER_START_REQ( send_hardware_message ) + { + req->win = wine_server_user_handle( 0 ); + req->flags = 0; + req->input.type = INPUT_KEYBOARD; + req->input.kbd.vkey = event->data.kbd.input.u.ki.wVk; + req->input.kbd.scan = event->data.kbd.input.u.ki.wScan; + req->input.kbd.flags = event->data.kbd.input.u.ki.dwFlags; + req->input.kbd.time = event->data.kbd.input.u.ki.time; + req->input.kbd.info = event->data.kbd.input.u.ki.dwExtraInfo; + wine_server_call( req ); + } + SERVER_END_REQ; break;
default:
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winemac.drv/ime.c | 32 +++++++++++++++++++------------- dlls/winemac.drv/keyboard.c | 23 +++++++++++++---------- dlls/winemac.drv/mouse.c | 23 ++++++++++++++--------- 3 files changed, 46 insertions(+), 32 deletions(-)
diff --git a/dlls/winemac.drv/ime.c b/dlls/winemac.drv/ime.c index dabe6654f98..a8e114457ad 100644 --- a/dlls/winemac.drv/ime.c +++ b/dlls/winemac.drv/ime.c @@ -1384,6 +1384,23 @@ BOOL WINAPI ImeInquire(LPIMEINFO lpIMEInfo, LPWSTR lpszUIClass, LPCWSTR lpszOpti
/* Interfaces to other parts of the Mac driver */
+static void send_keyboard_char(HWND hwnd, int scan, int flags) +{ + SERVER_START_REQ(send_hardware_message) + { + req->win = wine_server_user_handle(hwnd); + req->flags = 0; + req->input.type = INPUT_KEYBOARD; + req->input.kbd.vkey = 0; + req->input.kbd.scan = scan; + req->input.kbd.flags = flags; + req->input.kbd.time = 0; + req->input.kbd.info = 0; + wine_server_call(req); + } + SERVER_END_REQ; +} + /*********************************************************************** * macdrv_im_set_text */ @@ -1415,22 +1432,11 @@ void macdrv_im_set_text(const macdrv_event *event) event->im_set_text.cursor_pos, !event->im_set_text.complete); else { - INPUT input; CFIndex i; - - input.type = INPUT_KEYBOARD; - input.ki.wVk = 0; - input.ki.time = 0; - input.ki.dwExtraInfo = 0; - for (i = 0; i < length; i++) { - input.ki.wScan = chars[i]; - input.ki.dwFlags = KEYEVENTF_UNICODE; - __wine_send_input(hwnd, &input); - - input.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP; - __wine_send_input(hwnd, &input); + send_keyboard_char(hwnd, chars[i], KEYEVENTF_UNICODE); + send_keyboard_char(hwnd, chars[i], KEYEVENTF_UNICODE | KEYEVENTF_KEYUP); } }
diff --git a/dlls/winemac.drv/keyboard.c b/dlls/winemac.drv/keyboard.c index aed4ff0d6e4..45848c3b28e 100644 --- a/dlls/winemac.drv/keyboard.c +++ b/dlls/winemac.drv/keyboard.c @@ -918,18 +918,21 @@ void macdrv_compute_keyboard_layout(struct macdrv_thread_data *thread_data) */ static void macdrv_send_keyboard_input(HWND hwnd, WORD vkey, WORD scan, DWORD flags, DWORD time) { - INPUT input; - TRACE_(key)("hwnd %p vkey=%04x scan=%04x flags=%04x\n", hwnd, vkey, scan, flags);
- input.type = INPUT_KEYBOARD; - input.ki.wVk = vkey; - input.ki.wScan = scan; - input.ki.dwFlags = flags; - input.ki.time = time; - input.ki.dwExtraInfo = 0; - - __wine_send_input(hwnd, &input); + SERVER_START_REQ(send_hardware_message) + { + req->win = wine_server_user_handle(hwnd); + req->flags = 0; + req->input.type = INPUT_KEYBOARD; + req->input.kbd.vkey = vkey; + req->input.kbd.scan = scan; + req->input.kbd.flags = flags; + req->input.kbd.time = time; + req->input.kbd.info = 0; + wine_server_call(req); + } + SERVER_END_REQ; }
diff --git a/dlls/winemac.drv/mouse.c b/dlls/winemac.drv/mouse.c index dd6443fe1ba..2d7a0b592a9 100644 --- a/dlls/winemac.drv/mouse.c +++ b/dlls/winemac.drv/mouse.c @@ -157,15 +157,20 @@ static void send_mouse_input(HWND hwnd, macdrv_window cocoa_window, UINT flags, SERVER_END_REQ; }
- input.type = INPUT_MOUSE; - input.mi.dx = x; - input.mi.dy = y; - input.mi.mouseData = mouse_data; - input.mi.dwFlags = flags; - input.mi.time = time; - input.mi.dwExtraInfo = 0; - - __wine_send_input(top_level_hwnd, &input); + SERVER_START_REQ(send_hardware_message) + { + req->win = wine_server_user_handle(top_level_hwnd); + req->flags = 0; + req->input.type = INPUT_MOUSE; + req->input.mouse.x = x; + req->input.mouse.y = y; + req->input.mouse.data = mouse_data; + req->input.mouse.flags = flags; + req->input.mouse.time = time; + req->input.mouse.info = 0; + wine_server_call(req); + } + SERVER_END_REQ; }
Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
Notes: Making the request directly also bypasses the wait for the reply, as well as some state update, but I think it should be alright as we should not care about native vs injected input processing order.
I'm not entirely sure of the implication of not waiting for the reply, but I think graphics drivers don't care about it. It also has a beneficial impact on performance in the case where we would have waited for the reply on each input.
dlls/winex11.drv/keyboard.c | 23 +++--- dlls/winex11.drv/mouse.c | 145 +++++++++++++++--------------------- 2 files changed, 75 insertions(+), 93 deletions(-)
diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c index 131c5f5442f..ad7f1266860 100644 --- a/dlls/winex11.drv/keyboard.c +++ b/dlls/winex11.drv/keyboard.c @@ -1137,18 +1137,21 @@ static WORD EVENT_event_to_vkey( XIC xic, XKeyEvent *e) */ static void X11DRV_send_keyboard_input( HWND hwnd, WORD vkey, WORD scan, DWORD flags, DWORD time ) { - INPUT input; - TRACE_(key)( "hwnd %p vkey=%04x scan=%04x flags=%04x\n", hwnd, vkey, scan, flags );
- input.type = INPUT_KEYBOARD; - input.u.ki.wVk = vkey; - input.u.ki.wScan = scan; - input.u.ki.dwFlags = flags; - input.u.ki.time = time; - input.u.ki.dwExtraInfo = 0; - - __wine_send_input( hwnd, &input ); + SERVER_START_REQ( send_hardware_message ) + { + req->win = wine_server_user_handle( hwnd ); + req->flags = 0; + req->input.type = INPUT_KEYBOARD; + req->input.kbd.vkey = vkey; + req->input.kbd.scan = scan; + req->input.kbd.flags = flags; + req->input.kbd.time = time; + req->input.kbd.info = 0; + wine_server_call( req ); + } + SERVER_END_REQ; }
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index 15e5c04a41e..7528588d0c4 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -593,18 +593,36 @@ static BOOL is_old_motion_event( unsigned long serial ) }
+static void send_mouse_input( HWND hwnd, LONG dx, LONG dy, DWORD data, DWORD flags, DWORD time ) +{ + SERVER_START_REQ( send_hardware_message ) + { + req->win = wine_server_user_handle( hwnd ); + req->flags = 0; + req->input.type = INPUT_MOUSE; + req->input.mouse.x = dx; + req->input.mouse.y = dy; + req->input.mouse.data = data; + req->input.mouse.flags = flags; + req->input.mouse.time = time; + req->input.mouse.info = 0; + wine_server_call( req ); + } + SERVER_END_REQ; +} + + /*********************************************************************** - * send_mouse_input + * handle_mouse_event * * Update the various window states on a mouse event. */ -static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPUT *input ) +static void handle_mouse_event( HWND hwnd, Window window, unsigned int state, LONG dx, LONG dy, + DWORD button_data, DWORD button_flags, DWORD time ) { struct x11drv_win_data *data; POINT pt;
- input->type = INPUT_MOUSE; - if (!hwnd) { struct x11drv_thread_data *thread_data = x11drv_thread_data(); @@ -613,23 +631,23 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU if (!clip_hwnd) return; if (thread_data->clip_window != window) return; if (InterlockedExchangePointer( (void **)&cursor_window, clip_hwnd ) != clip_hwnd || - input->u.mi.time - last_cursor_change > 100) + time - last_cursor_change > 100) { sync_window_cursor( window ); - last_cursor_change = input->u.mi.time; + last_cursor_change = time; } - input->u.mi.dx += clip_rect.left; - input->u.mi.dy += clip_rect.top; - __wine_send_input( hwnd, input ); + dx += clip_rect.left; + dy += clip_rect.top; + send_mouse_input( hwnd, dx, dy, button_data, button_flags, time ); return; }
if (window != root_window) { - pt.x = input->u.mi.dx; - pt.y = input->u.mi.dy; + pt.x = dx; + pt.y = dy; } - else pt = root_to_virtual_screen( input->u.mi.dx, input->u.mi.dy ); + else pt = root_to_virtual_screen( dx, dy );
if (!(data = get_win_data( hwnd ))) return;
@@ -644,17 +662,17 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU MapWindowPoints( hwnd, 0, &pt, 1 );
if (InterlockedExchangePointer( (void **)&cursor_window, hwnd ) != hwnd || - input->u.mi.time - last_cursor_change > 100) + time - last_cursor_change > 100) { sync_window_cursor( data->whole_window ); - last_cursor_change = input->u.mi.time; + last_cursor_change = time; } release_win_data( data );
if (hwnd != GetDesktopWindow()) { hwnd = GetAncestor( hwnd, GA_ROOT ); - if ((input->u.mi.dwFlags & (MOUSEEVENTF_LEFTDOWN|MOUSEEVENTF_RIGHTDOWN)) && hwnd == GetForegroundWindow()) + if ((button_flags & (MOUSEEVENTF_LEFTDOWN|MOUSEEVENTF_RIGHTDOWN)) && hwnd == GetForegroundWindow()) clip_fullscreen_window( hwnd, FALSE ); }
@@ -679,9 +697,9 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU SERVER_END_REQ; }
- input->u.mi.dx = pt.x; - input->u.mi.dy = pt.y; - __wine_send_input( hwnd, input ); + dx = pt.x; + dy = pt.y; + send_mouse_input( hwnd, dx, dy, button_data, button_flags, time ); }
#ifdef SONAME_LIBXCURSOR @@ -1611,7 +1629,6 @@ void move_resize_window( HWND hwnd, int dir ) for (;;) { MSG msg; - INPUT input; int x, y, rootX, rootY;
if (!XQueryPointer( display, root_window, &root, &child, &rootX, &rootY, &x, &y, &xstate )) break; @@ -1620,14 +1637,9 @@ void move_resize_window( HWND hwnd, int dir ) { /* fake a button release event */ pos = root_to_virtual_screen( x, y ); - input.type = INPUT_MOUSE; - input.u.mi.dx = pos.x; - input.u.mi.dy = pos.y; - input.u.mi.mouseData = button_up_data[button - 1]; - input.u.mi.dwFlags = button_up_flags[button - 1] | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE; - input.u.mi.time = GetTickCount(); - input.u.mi.dwExtraInfo = 0; - __wine_send_input( hwnd, &input ); + send_mouse_input( hwnd, pos.x, pos.y, button_up_data[button - 1], + button_up_flags[button - 1] | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, + GetTickCount() ); }
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) @@ -1655,21 +1667,15 @@ BOOL X11DRV_ButtonPress( HWND hwnd, XEvent *xev ) { XButtonEvent *event = &xev->xbutton; int buttonNum = event->button - 1; - INPUT input;
if (buttonNum >= NB_BUTTONS) return FALSE;
TRACE( "hwnd %p/%lx button %u pos %d,%d\n", hwnd, event->window, buttonNum, event->x, event->y );
- input.u.mi.dx = event->x; - input.u.mi.dy = event->y; - input.u.mi.mouseData = button_down_data[buttonNum]; - input.u.mi.dwFlags = button_down_flags[buttonNum] | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE; - input.u.mi.time = EVENT_x11_time_to_win32_time( event->time ); - input.u.mi.dwExtraInfo = 0; - update_user_time( event->time ); - send_mouse_input( hwnd, event->window, event->state, &input ); + handle_mouse_event( hwnd, event->window, event->state, event->x, event->y, + button_down_data[buttonNum], button_down_flags[buttonNum], + EVENT_x11_time_to_win32_time( event->time ) ); return TRUE; }
@@ -1681,20 +1687,14 @@ BOOL X11DRV_ButtonRelease( HWND hwnd, XEvent *xev ) { XButtonEvent *event = &xev->xbutton; int buttonNum = event->button - 1; - INPUT input;
if (buttonNum >= NB_BUTTONS || !button_up_flags[buttonNum]) return FALSE;
TRACE( "hwnd %p/%lx button %u pos %d,%d\n", hwnd, event->window, buttonNum, event->x, event->y );
- input.u.mi.dx = event->x; - input.u.mi.dy = event->y; - input.u.mi.mouseData = button_up_data[buttonNum]; - input.u.mi.dwFlags = button_up_flags[buttonNum] | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE; - input.u.mi.time = EVENT_x11_time_to_win32_time( event->time ); - input.u.mi.dwExtraInfo = 0; - - send_mouse_input( hwnd, event->window, event->state, &input ); + handle_mouse_event( hwnd, event->window, event->state, event->x, event->y, + button_up_data[buttonNum], button_up_flags[buttonNum], + EVENT_x11_time_to_win32_time( event->time ) ); return TRUE; }
@@ -1705,24 +1705,18 @@ BOOL X11DRV_ButtonRelease( HWND hwnd, XEvent *xev ) BOOL X11DRV_MotionNotify( HWND hwnd, XEvent *xev ) { XMotionEvent *event = &xev->xmotion; - INPUT input;
TRACE( "hwnd %p/%lx pos %d,%d is_hint %d serial %lu\n", hwnd, event->window, event->x, event->y, event->is_hint, event->serial );
- input.u.mi.dx = event->x; - input.u.mi.dy = event->y; - input.u.mi.mouseData = 0; - input.u.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE; - input.u.mi.time = EVENT_x11_time_to_win32_time( event->time ); - input.u.mi.dwExtraInfo = 0; - if (!hwnd && is_old_motion_event( event->serial )) { - TRACE( "pos %d,%d old serial %lu, ignoring\n", input.u.mi.dx, input.u.mi.dy, event->serial ); + TRACE( "pos %d,%d old serial %lu, ignoring\n", event->x, event->y, event->serial ); return FALSE; } - send_mouse_input( hwnd, event->window, event->state, &input ); + handle_mouse_event( hwnd, event->window, event->state, event->x, event->y, + 0, MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, + EVENT_x11_time_to_win32_time( event->time ) ); return TRUE; }
@@ -1733,7 +1727,6 @@ BOOL X11DRV_MotionNotify( HWND hwnd, XEvent *xev ) BOOL X11DRV_EnterNotify( HWND hwnd, XEvent *xev ) { XCrossingEvent *event = &xev->xcrossing; - INPUT input;
TRACE( "hwnd %p/%lx pos %d,%d detail %d\n", hwnd, event->window, event->x, event->y, event->detail );
@@ -1741,19 +1734,14 @@ BOOL X11DRV_EnterNotify( HWND hwnd, XEvent *xev ) if (hwnd == x11drv_thread_data()->grab_hwnd) return FALSE;
/* simulate a mouse motion event */ - input.u.mi.dx = event->x; - input.u.mi.dy = event->y; - input.u.mi.mouseData = 0; - input.u.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE; - input.u.mi.time = EVENT_x11_time_to_win32_time( event->time ); - input.u.mi.dwExtraInfo = 0; - if (is_old_motion_event( event->serial )) { - TRACE( "pos %d,%d old serial %lu, ignoring\n", input.u.mi.dx, input.u.mi.dy, event->serial ); + TRACE( "pos %d,%d old serial %lu, ignoring\n", event->x, event->y, event->serial ); return FALSE; } - send_mouse_input( hwnd, event->window, event->state, &input ); + handle_mouse_event( hwnd, event->window, event->state, event->x, event->y, + 0, MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, + EVENT_x11_time_to_win32_time( event->time ) ); return TRUE; }
@@ -1783,9 +1771,8 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev ) XIRawEvent *event = xev->data; const double *values = event->valuators.values; RECT virtual_rect; - INPUT input; - int i; - double dx = 0, dy = 0, val; + int i, dx = 0, dy = 0; + double x_val = 0, y_val = 0, val; struct x11drv_thread_data *thread_data = x11drv_thread_data(); struct x11drv_valuator_data *x_rel, *y_rel;
@@ -1816,13 +1803,6 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev ) x_rel = &thread_data->x_rel_valuator; y_rel = &thread_data->y_rel_valuator;
- input.u.mi.mouseData = 0; - input.u.mi.dwFlags = MOUSEEVENTF_MOVE; - input.u.mi.time = EVENT_x11_time_to_win32_time( event->time ); - input.u.mi.dwExtraInfo = 0; - input.u.mi.dx = 0; - input.u.mi.dy = 0; - virtual_rect = get_virtual_screen_rect();
for (i = 0; i <= max ( x_rel->number, y_rel->number ); i++) @@ -1831,30 +1811,29 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev ) val = *values++; if (i == x_rel->number) { - input.u.mi.dx = dx = val; + dx = x_val = val; if (x_rel->min < x_rel->max) - input.u.mi.dx = val * (virtual_rect.right - virtual_rect.left) + dx = x_val * (virtual_rect.right - virtual_rect.left) / (x_rel->max - x_rel->min); } if (i == y_rel->number) { - input.u.mi.dy = dy = val; + dy = y_val = val; if (y_rel->min < y_rel->max) - input.u.mi.dy = val * (virtual_rect.bottom - virtual_rect.top) + dy = y_val * (virtual_rect.bottom - virtual_rect.top) / (y_rel->max - y_rel->min); } }
if (broken_rawevents && is_old_motion_event( xev->serial )) { - TRACE( "pos %d,%d old serial %lu, ignoring\n", input.u.mi.dx, input.u.mi.dy, xev->serial ); + TRACE( "pos %d,%d old serial %lu, ignoring\n", dx, dy, xev->serial ); return FALSE; }
- TRACE( "pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, dx, dy ); + TRACE( "pos %d,%d (event %f,%f)\n", dx, dy, x_val, y_val );
- input.type = INPUT_MOUSE; - __wine_send_input( 0, &input ); + send_mouse_input( 0, dx, dy, 0, MOUSEEVENTF_MOVE, EVENT_x11_time_to_win32_time( event->time ) ); return TRUE; }
__wine_send_input was introduced at a time when SendInput was handled in the graphics drivers, we don't do that anymore and it makes little sense to go through user32 for user input now.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
Notes: Making the request directly also bypasses the wait for the reply, as well as some state update, but I think it should be alright as we should not care about native vs injected input processing order.
I'm not entirely sure of the implication of not waiting for the reply, but I think graphics drivers don't care about it. It also has a beneficial impact on performance in the case where we would have waited for the reply on each input.
dlls/user32/input.c | 17 ++--------------- dlls/user32/message.c | 8 ++++---- dlls/user32/user32.spec | 1 - dlls/user32/user_private.h | 2 +- include/winuser.h | 4 ---- 5 files changed, 7 insertions(+), 25 deletions(-)
diff --git a/dlls/user32/input.c b/dlls/user32/input.c index 8b2ae805aa7..4268a8c1d6c 100644 --- a/dlls/user32/input.c +++ b/dlls/user32/input.c @@ -117,19 +117,6 @@ BOOL set_capture_window( HWND hwnd, UINT gui_flags, HWND *prev_ret ) }
-/*********************************************************************** - * __wine_send_input (USER32.@) - * - * Internal SendInput function to allow the graphics driver to inject real events. - */ -BOOL CDECL __wine_send_input( HWND hwnd, const INPUT *input ) -{ - NTSTATUS status = send_hardware_message( hwnd, input, 0 ); - if (status) SetLastError( RtlNtStatusToDosError(status) ); - return !status; -} - - /*********************************************************************** * update_mouse_coords * @@ -192,9 +179,9 @@ UINT WINAPI SendInput( UINT count, LPINPUT inputs, int size ) /* we need to update the coordinates to what the server expects */ INPUT input = inputs[i]; update_mouse_coords( &input ); - status = send_hardware_message( 0, &input, SEND_HWMSG_INJECTED ); + status = inject_hardware_message( 0, &input ); } - else status = send_hardware_message( 0, &inputs[i], SEND_HWMSG_INJECTED ); + else status = inject_hardware_message( 0, &inputs[i] );
if (status) { diff --git a/dlls/user32/message.c b/dlls/user32/message.c index 1336865112a..2327d66cb05 100644 --- a/dlls/user32/message.c +++ b/dlls/user32/message.c @@ -3319,9 +3319,9 @@ static BOOL send_message( struct send_message_info *info, DWORD_PTR *res_ptr, BO
/*********************************************************************** - * send_hardware_message + * inject_hardware_message */ -NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags ) +NTSTATUS inject_hardware_message( HWND hwnd, const INPUT *input ) { struct user_key_state_info *key_state_info = get_user_thread_info()->key_state; struct send_message_info info; @@ -3339,7 +3339,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags ) SERVER_START_REQ( send_hardware_message ) { req->win = wine_server_user_handle( hwnd ); - req->flags = flags; + req->flags = SEND_HWMSG_INJECTED; req->input.type = input->type; switch (input->type) { @@ -3381,7 +3381,7 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags ) key_state_info->time = GetTickCount(); key_state_info->counter = counter; } - if ((flags & SEND_HWMSG_INJECTED) && (prev_x != new_x || prev_y != new_y)) + if ((prev_x != new_x || prev_y != new_y)) USER_Driver->pSetCursorPos( new_x, new_y ); }
diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec index f9a4ae26df4..55fb438c3b1 100644 --- a/dlls/user32/user32.spec +++ b/dlls/user32/user32.spec @@ -832,5 +832,4 @@ # All functions must be prefixed with '__wine_' (for internal functions) # or 'wine_' (for user-visible functions) to avoid namespace conflicts. # -@ cdecl __wine_send_input(long ptr) @ cdecl __wine_set_pixel_format(long long) diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index c11aae707c9..b11945c120f 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -249,7 +249,7 @@ extern RECT get_virtual_screen_rect(void) DECLSPEC_HIDDEN; extern LRESULT call_current_hook( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam ) DECLSPEC_HIDDEN; extern DWORD get_input_codepage( void ) DECLSPEC_HIDDEN; extern BOOL map_wparam_AtoW( UINT message, WPARAM *wparam, enum wm_char_mapping mapping ) DECLSPEC_HIDDEN; -extern NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, UINT flags ) DECLSPEC_HIDDEN; +extern NTSTATUS inject_hardware_message( HWND hwnd, const INPUT *input ) DECLSPEC_HIDDEN; extern LRESULT MSG_SendInternalMessageTimeout( DWORD dest_pid, DWORD dest_tid, UINT msg, WPARAM wparam, LPARAM lparam, UINT flags, UINT timeout, PDWORD_PTR res_ptr ) DECLSPEC_HIDDEN; diff --git a/include/winuser.h b/include/winuser.h index 51c73d25c2f..62d5f0dd110 100644 --- a/include/winuser.h +++ b/include/winuser.h @@ -4388,10 +4388,6 @@ static inline BOOL WINAPI SetRectEmpty(LPRECT rect) /* NOTE: This is SYSTEM.3, not USER.182, which is also named KillSystemTimer */ WORD WINAPI SYSTEM_KillSystemTimer( WORD );
-#ifdef __WINESRC__ -WINUSERAPI BOOL CDECL __wine_send_input( HWND hwnd, const INPUT *input ); -#endif - #ifdef __cplusplus } #endif
Rémi Bernon rbernon@codeweavers.com writes:
__wine_send_input was introduced at a time when SendInput was handled in the graphics drivers, we don't do that anymore and it makes little sense to go through user32 for user input now.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
Notes: Making the request directly also bypasses the wait for the reply, as well as some state update, but I think it should be alright as we should not care about native vs injected input processing order.
I'm not entirely sure of the implication of not waiting for the reply, but I think graphics drivers don't care about it. It also has a beneficial impact on performance in the case where we would have waited for the reply on each input.
The wait is necessary for hook processing. The state update is also needed to avoid redundant server calls. It doesn't look like this series is going in the right direction.
On 11/12/19 10:04 AM, Alexandre Julliard wrote:
Rémi Bernon rbernon@codeweavers.com writes:
__wine_send_input was introduced at a time when SendInput was handled in the graphics drivers, we don't do that anymore and it makes little sense to go through user32 for user input now.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
Notes: Making the request directly also bypasses the wait for the reply, as well as some state update, but I think it should be alright as we should not care about native vs injected input processing order.
I'm not entirely sure of the implication of not waiting for the reply, but I think graphics drivers don't care about it. It also has a beneficial impact on performance in the case where we would have waited for the reply on each input.
The wait is necessary for hook processing. The state update is also needed to avoid redundant server calls. It doesn't look like this series is going in the right direction.
Regarding the hooks, I assumed that if we are processing input events, it means that the current thread is already in a message processing loop, so the hooks would eventually be processed if they belong to the same thread. Although maybe that would depend on the message filters?
If they belong to another thread, it means that if for any reason that thread is not processing its messages, input events coming from the user would block the message loop instead of just being queued to the hooking thread. Maybe it's also something we expect?
Anyway, thanks for the comment, I'll drop this.
Rémi Bernon rbernon@codeweavers.com writes:
Regarding the hooks, I assumed that if we are processing input events, it means that the current thread is already in a message processing loop, so the hooks would eventually be processed if they belong to the same thread. Although maybe that would depend on the message filters?
If they belong to another thread, it means that if for any reason that thread is not processing its messages, input events coming from the user would block the message loop instead of just being queued to the hooking thread. Maybe it's also something we expect?
Yes, the low-level hooks work basically like SendMessage, and block the sender. There's a timeout in case the hooking thread is stuck.
On 11/12/19 2:59 PM, Alexandre Julliard wrote:
Rémi Bernon rbernon@codeweavers.com writes:
Regarding the hooks, I assumed that if we are processing input events, it means that the current thread is already in a message processing loop, so the hooks would eventually be processed if they belong to the same thread. Although maybe that would depend on the message filters?
If they belong to another thread, it means that if for any reason that thread is not processing its messages, input events coming from the user would block the message loop instead of just being queued to the hooking thread. Maybe it's also something we expect?
Yes, the low-level hooks work basically like SendMessage, and block the sender. There's a timeout in case the hooking thread is stuck.
Alright, I thought that the round trip from the message queue to the hooks was a wine implementation detail, but a quick test proves me wrong. The timeout on Windows seems much smaller though -but there's definitely one.
Thanks,
It allows graphics driver to split their input source into separate sources for raw input or window input events, in order for example to guarantee the consistency of the raw input message data.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/user32/message.c | 3 +++ dlls/wineandroid.drv/keyboard.c | 1 + dlls/wineandroid.drv/window.c | 2 ++ dlls/winemac.drv/ime.c | 1 + dlls/winemac.drv/keyboard.c | 1 + dlls/winemac.drv/mouse.c | 1 + dlls/winex11.drv/keyboard.c | 1 + dlls/winex11.drv/mouse.c | 1 + server/protocol.def | 13 +++++++++---- server/queue.c | 12 ++++++++++-- server/trace.c | 17 ++++++++++++----- 11 files changed, 42 insertions(+), 11 deletions(-)
diff --git a/dlls/user32/message.c b/dlls/user32/message.c index 2327d66cb05..8613fa5f971 100644 --- a/dlls/user32/message.c +++ b/dlls/user32/message.c @@ -3344,6 +3344,7 @@ NTSTATUS inject_hardware_message( HWND hwnd, const INPUT *input ) switch (input->type) { case INPUT_MOUSE: + req->input.mouse.src = HW_INPUT_SRC_INJECTED|HW_INPUT_SRC_WINDOW|HW_INPUT_SRC_RAWINPUT; req->input.mouse.x = input->u.mi.dx; req->input.mouse.y = input->u.mi.dy; req->input.mouse.data = input->u.mi.mouseData; @@ -3352,6 +3353,7 @@ NTSTATUS inject_hardware_message( HWND hwnd, const INPUT *input ) req->input.mouse.info = input->u.mi.dwExtraInfo; break; case INPUT_KEYBOARD: + req->input.kbd.src = HW_INPUT_SRC_INJECTED|HW_INPUT_SRC_WINDOW|HW_INPUT_SRC_RAWINPUT; req->input.kbd.vkey = input->u.ki.wVk; req->input.kbd.scan = input->u.ki.wScan; req->input.kbd.flags = input->u.ki.dwFlags; @@ -3359,6 +3361,7 @@ NTSTATUS inject_hardware_message( HWND hwnd, const INPUT *input ) req->input.kbd.info = input->u.ki.dwExtraInfo; break; case INPUT_HARDWARE: + req->input.hw.src = HW_INPUT_SRC_INJECTED|HW_INPUT_SRC_WINDOW|HW_INPUT_SRC_RAWINPUT; req->input.hw.msg = input->u.hi.uMsg; req->input.hw.lparam = MAKELONG( input->u.hi.wParamL, input->u.hi.wParamH ); break; diff --git a/dlls/wineandroid.drv/keyboard.c b/dlls/wineandroid.drv/keyboard.c index 5c9ed2442df..a714b38f5e4 100644 --- a/dlls/wineandroid.drv/keyboard.c +++ b/dlls/wineandroid.drv/keyboard.c @@ -676,6 +676,7 @@ static void send_keyboard_input( HWND hwnd, WORD vkey, WORD scan, DWORD flags ) req->win = wine_server_user_handle( hwnd ); req->flags = 0; req->input.type = INPUT_KEYBOARD; + req->input.kbd.src = HW_INPUT_SRC_WINDOW|HW_INPUT_SRC_RAWINPUT; req->input.kbd.vkey = vkey; req->input.kbd.scan = scan; req->input.kbd.flags = flags; diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index 2b757636847..2d88c1f9816 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -527,6 +527,7 @@ static int process_events( DWORD mask ) req->win = wine_server_user_handle( capture ? capture : event->data.motion.hwnd ); req->flags = 0; req->input.type = INPUT_MOUSE; + req->input.mouse.src = HW_INPUT_SRC_WINDOW|HW_INPUT_SRC_RAWINPUT; req->input.mouse.x = event->data.motion.input.u.mi.dx; req->input.mouse.y = event->data.motion.input.u.mi.dy; req->input.mouse.data = event->data.motion.input.u.mi.mouseData; @@ -555,6 +556,7 @@ static int process_events( DWORD mask ) req->win = wine_server_user_handle( 0 ); req->flags = 0; req->input.type = INPUT_KEYBOARD; + req->input.kbd.src = HW_INPUT_SRC_WINDOW|HW_INPUT_SRC_RAWINPUT; req->input.kbd.vkey = event->data.kbd.input.u.ki.wVk; req->input.kbd.scan = event->data.kbd.input.u.ki.wScan; req->input.kbd.flags = event->data.kbd.input.u.ki.dwFlags; diff --git a/dlls/winemac.drv/ime.c b/dlls/winemac.drv/ime.c index a8e114457ad..ebbb1e8ccb4 100644 --- a/dlls/winemac.drv/ime.c +++ b/dlls/winemac.drv/ime.c @@ -1391,6 +1391,7 @@ static void send_keyboard_char(HWND hwnd, int scan, int flags) req->win = wine_server_user_handle(hwnd); req->flags = 0; req->input.type = INPUT_KEYBOARD; + req->input.kbd.src = HW_INPUT_SRC_WINDOW|HW_INPUT_SRC_RAWINPUT; req->input.kbd.vkey = 0; req->input.kbd.scan = scan; req->input.kbd.flags = flags; diff --git a/dlls/winemac.drv/keyboard.c b/dlls/winemac.drv/keyboard.c index 45848c3b28e..bb09d1de1e0 100644 --- a/dlls/winemac.drv/keyboard.c +++ b/dlls/winemac.drv/keyboard.c @@ -925,6 +925,7 @@ static void macdrv_send_keyboard_input(HWND hwnd, WORD vkey, WORD scan, DWORD fl req->win = wine_server_user_handle(hwnd); req->flags = 0; req->input.type = INPUT_KEYBOARD; + req->input.kbd.src = HW_INPUT_SRC_WINDOW|HW_INPUT_SRC_RAWINPUT; req->input.kbd.vkey = vkey; req->input.kbd.scan = scan; req->input.kbd.flags = flags; diff --git a/dlls/winemac.drv/mouse.c b/dlls/winemac.drv/mouse.c index 2d7a0b592a9..388b5d8e460 100644 --- a/dlls/winemac.drv/mouse.c +++ b/dlls/winemac.drv/mouse.c @@ -162,6 +162,7 @@ static void send_mouse_input(HWND hwnd, macdrv_window cocoa_window, UINT flags, req->win = wine_server_user_handle(top_level_hwnd); req->flags = 0; req->input.type = INPUT_MOUSE; + req->input.mouse.src = HW_INPUT_SRC_WINDOW|HW_INPUT_SRC_RAWINPUT; req->input.mouse.x = x; req->input.mouse.y = y; req->input.mouse.data = mouse_data; diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c index ad7f1266860..2725266f4b3 100644 --- a/dlls/winex11.drv/keyboard.c +++ b/dlls/winex11.drv/keyboard.c @@ -1144,6 +1144,7 @@ static void X11DRV_send_keyboard_input( HWND hwnd, WORD vkey, WORD scan, DWORD f req->win = wine_server_user_handle( hwnd ); req->flags = 0; req->input.type = INPUT_KEYBOARD; + req->input.kbd.src = HW_INPUT_SRC_WINDOW|HW_INPUT_SRC_RAWINPUT; req->input.kbd.vkey = vkey; req->input.kbd.scan = scan; req->input.kbd.flags = flags; diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index 7528588d0c4..f98e6804dea 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -600,6 +600,7 @@ static void send_mouse_input( HWND hwnd, LONG dx, LONG dy, DWORD data, DWORD fla req->win = wine_server_user_handle( hwnd ); req->flags = 0; req->input.type = INPUT_MOUSE; + req->input.mouse.src = HW_INPUT_SRC_WINDOW|HW_INPUT_SRC_RAWINPUT; req->input.mouse.x = dx; req->input.mouse.y = dy; req->input.mouse.data = data; diff --git a/server/protocol.def b/server/protocol.def index 6af0ae0cff8..0e302235ca1 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -329,10 +329,11 @@ struct winevent_msg_data
typedef union { - int type; + short type; struct { - int type; /* INPUT_KEYBOARD */ + short type; /* INPUT_KEYBOARD */ + short src; /* input source (see below) */ unsigned short vkey; /* virtual key code */ unsigned short scan; /* scan code */ unsigned int flags; /* event flags */ @@ -341,7 +342,8 @@ typedef union } kbd; struct { - int type; /* INPUT_MOUSE */ + short type; /* INPUT_MOUSE */ + short src; /* input source (see below) */ int x; /* coordinates */ int y; unsigned int data; /* mouse data */ @@ -351,11 +353,14 @@ typedef union } mouse; struct { - int type; /* INPUT_HARDWARE */ + short type; /* INPUT_HARDWARE */ + short src; /* input source (see below) */ unsigned int msg; /* message code */ lparam_t lparam; /* message param */ } hw; } hw_input_t; +#define HW_INPUT_SRC_WINDOW 1 +#define HW_INPUT_SRC_RAWINPUT 2
typedef union { diff --git a/server/queue.c b/server/queue.c index b5e17be18fb..19da1f34c74 100644 --- a/server/queue.c +++ b/server/queue.c @@ -1651,7 +1651,8 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons y = desktop->cursor.y; }
- if ((device = current->process->rawinput_mouse)) + if ((device = current->process->rawinput_mouse) && + (input->mouse.src & HW_INPUT_SRC_RAWINPUT)) { if (!(msg = alloc_hardware_message( input->mouse.info, source, time ))) return 0; msg_data = msg->data; @@ -1670,6 +1671,9 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons queue_hardware_message( desktop, msg, 0 ); }
+ if (!(input->mouse.src & HW_INPUT_SRC_WINDOW)) + return 0; + for (i = 0; i < ARRAY_SIZE( messages ); i++) { if (!messages[i]) continue; @@ -1777,7 +1781,8 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c break; }
- if ((device = current->process->rawinput_kbd)) + if ((device = current->process->rawinput_kbd) && + (input->kbd.src & HW_INPUT_SRC_RAWINPUT)) { if (!(msg = alloc_hardware_message( input->kbd.info, source, time ))) return 0; msg_data = msg->data; @@ -1795,6 +1800,9 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c queue_hardware_message( desktop, msg, 0 ); }
+ if (!(input->kbd.src & HW_INPUT_SRC_WINDOW)) + return 0; + if (!(msg = alloc_hardware_message( input->kbd.info, source, time ))) return 0; msg_data = msg->data;
diff --git a/server/trace.c b/server/trace.c index 615542cff52..6674505bc1c 100644 --- a/server/trace.c +++ b/server/trace.c @@ -379,23 +379,30 @@ static void dump_irp_params( const char *prefix, const irp_params_t *data )
static void dump_hw_input( const char *prefix, const hw_input_t *input ) { + char src[] = "--"; switch (input->type) { case INPUT_MOUSE: - fprintf( stderr, "%s{type=MOUSE,x=%d,y=%d,data=%08x,flags=%08x,time=%u", - prefix, input->mouse.x, input->mouse.y, input->mouse.data, input->mouse.flags, + if (input->mouse.src & HW_INPUT_SRC_WINDOW) src[0] = 'w'; + if (input->mouse.src & HW_INPUT_SRC_RAWINPUT) src[1] = 'r'; + fprintf( stderr, "%s{type=MOUSE,src=%s,x=%d,y=%d,data=%08x,flags=%08x,time=%u", + prefix, src, input->mouse.x, input->mouse.y, input->mouse.data, input->mouse.flags, input->mouse.time ); dump_uint64( ",info=", &input->mouse.info ); fputc( '}', stderr ); break; case INPUT_KEYBOARD: - fprintf( stderr, "%s{type=KEYBOARD,vkey=%04hx,scan=%04hx,flags=%08x,time=%u", - prefix, input->kbd.vkey, input->kbd.scan, input->kbd.flags, input->kbd.time ); + if (input->kbd.src & HW_INPUT_SRC_WINDOW) src[0] = 'w'; + if (input->kbd.src & HW_INPUT_SRC_RAWINPUT) src[1] = 'r'; + fprintf( stderr, "%s{type=KEYBOARD,src=%s,vkey=%04hx,scan=%04hx,flags=%08x,time=%u", + prefix, src, input->kbd.vkey, input->kbd.scan, input->kbd.flags, input->kbd.time ); dump_uint64( ",info=", &input->kbd.info ); fputc( '}', stderr ); break; case INPUT_HARDWARE: - fprintf( stderr, "%s{type=HARDWARE,msg=%04x", prefix, input->hw.msg ); + if (input->hw.src & HW_INPUT_SRC_WINDOW) src[0] = 'w'; + if (input->hw.src & HW_INPUT_SRC_RAWINPUT) src[1] = 'r'; + fprintf( stderr, "%s{type=HARDWARE,src=%s,msg=%04x", prefix, src, input->hw.msg ); dump_uint64( ",lparam=", &input->hw.lparam ); fputc( '}', stderr ); break;
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=59849
Your paranoid android.
=== debian10 (build log) ===
../../../wine/dlls/user32/message.c:3347:38: error: ‘HW_INPUT_SRC_INJECTED’ undeclared (first use in this function); did you mean ‘HW_INPUT_SRC_WINDOW’? Task: The win32 build failed
=== debian10 (build log) ===
../../../wine/dlls/user32/message.c:3347:38: error: ‘HW_INPUT_SRC_INJECTED’ undeclared (first use in this function); did you mean ‘HW_INPUT_SRC_WINDOW’? Task: The wow64 build failed
Replace it with hw_input_t HW_INPUT_SRC_INJECTED src bit to indicate the injected nature of an input message.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/user32/message.c | 1 - dlls/wineandroid.drv/keyboard.c | 1 - dlls/wineandroid.drv/window.c | 2 -- dlls/winemac.drv/ime.c | 1 - dlls/winemac.drv/keyboard.c | 1 - dlls/winemac.drv/mouse.c | 1 - dlls/winex11.drv/keyboard.c | 1 - dlls/winex11.drv/mouse.c | 1 - server/protocol.def | 3 +-- server/queue.c | 16 +++++++++------- server/trace.c | 5 ++++- 11 files changed, 14 insertions(+), 19 deletions(-)
diff --git a/dlls/user32/message.c b/dlls/user32/message.c index 8613fa5f971..eaca6808597 100644 --- a/dlls/user32/message.c +++ b/dlls/user32/message.c @@ -3339,7 +3339,6 @@ NTSTATUS inject_hardware_message( HWND hwnd, const INPUT *input ) SERVER_START_REQ( send_hardware_message ) { req->win = wine_server_user_handle( hwnd ); - req->flags = SEND_HWMSG_INJECTED; req->input.type = input->type; switch (input->type) { diff --git a/dlls/wineandroid.drv/keyboard.c b/dlls/wineandroid.drv/keyboard.c index a714b38f5e4..c96c3db4bda 100644 --- a/dlls/wineandroid.drv/keyboard.c +++ b/dlls/wineandroid.drv/keyboard.c @@ -674,7 +674,6 @@ static void send_keyboard_input( HWND hwnd, WORD vkey, WORD scan, DWORD flags ) SERVER_START_REQ( send_hardware_message ) { req->win = wine_server_user_handle( hwnd ); - req->flags = 0; req->input.type = INPUT_KEYBOARD; req->input.kbd.src = HW_INPUT_SRC_WINDOW|HW_INPUT_SRC_RAWINPUT; req->input.kbd.vkey = vkey; diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index 2d88c1f9816..cebfd62719c 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -525,7 +525,6 @@ static int process_events( DWORD mask ) SERVER_START_REQ( send_hardware_message ) { req->win = wine_server_user_handle( capture ? capture : event->data.motion.hwnd ); - req->flags = 0; req->input.type = INPUT_MOUSE; req->input.mouse.src = HW_INPUT_SRC_WINDOW|HW_INPUT_SRC_RAWINPUT; req->input.mouse.x = event->data.motion.input.u.mi.dx; @@ -554,7 +553,6 @@ static int process_events( DWORD mask ) SERVER_START_REQ( send_hardware_message ) { req->win = wine_server_user_handle( 0 ); - req->flags = 0; req->input.type = INPUT_KEYBOARD; req->input.kbd.src = HW_INPUT_SRC_WINDOW|HW_INPUT_SRC_RAWINPUT; req->input.kbd.vkey = event->data.kbd.input.u.ki.wVk; diff --git a/dlls/winemac.drv/ime.c b/dlls/winemac.drv/ime.c index ebbb1e8ccb4..00dcb192804 100644 --- a/dlls/winemac.drv/ime.c +++ b/dlls/winemac.drv/ime.c @@ -1389,7 +1389,6 @@ static void send_keyboard_char(HWND hwnd, int scan, int flags) SERVER_START_REQ(send_hardware_message) { req->win = wine_server_user_handle(hwnd); - req->flags = 0; req->input.type = INPUT_KEYBOARD; req->input.kbd.src = HW_INPUT_SRC_WINDOW|HW_INPUT_SRC_RAWINPUT; req->input.kbd.vkey = 0; diff --git a/dlls/winemac.drv/keyboard.c b/dlls/winemac.drv/keyboard.c index bb09d1de1e0..4fd7bf71aca 100644 --- a/dlls/winemac.drv/keyboard.c +++ b/dlls/winemac.drv/keyboard.c @@ -923,7 +923,6 @@ static void macdrv_send_keyboard_input(HWND hwnd, WORD vkey, WORD scan, DWORD fl SERVER_START_REQ(send_hardware_message) { req->win = wine_server_user_handle(hwnd); - req->flags = 0; req->input.type = INPUT_KEYBOARD; req->input.kbd.src = HW_INPUT_SRC_WINDOW|HW_INPUT_SRC_RAWINPUT; req->input.kbd.vkey = vkey; diff --git a/dlls/winemac.drv/mouse.c b/dlls/winemac.drv/mouse.c index 388b5d8e460..57950217902 100644 --- a/dlls/winemac.drv/mouse.c +++ b/dlls/winemac.drv/mouse.c @@ -160,7 +160,6 @@ static void send_mouse_input(HWND hwnd, macdrv_window cocoa_window, UINT flags, SERVER_START_REQ(send_hardware_message) { req->win = wine_server_user_handle(top_level_hwnd); - req->flags = 0; req->input.type = INPUT_MOUSE; req->input.mouse.src = HW_INPUT_SRC_WINDOW|HW_INPUT_SRC_RAWINPUT; req->input.mouse.x = x; diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c index 2725266f4b3..1663b3d99ad 100644 --- a/dlls/winex11.drv/keyboard.c +++ b/dlls/winex11.drv/keyboard.c @@ -1142,7 +1142,6 @@ static void X11DRV_send_keyboard_input( HWND hwnd, WORD vkey, WORD scan, DWORD f SERVER_START_REQ( send_hardware_message ) { req->win = wine_server_user_handle( hwnd ); - req->flags = 0; req->input.type = INPUT_KEYBOARD; req->input.kbd.src = HW_INPUT_SRC_WINDOW|HW_INPUT_SRC_RAWINPUT; req->input.kbd.vkey = vkey; diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index f98e6804dea..346ae93b7b7 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -598,7 +598,6 @@ static void send_mouse_input( HWND hwnd, LONG dx, LONG dy, DWORD data, DWORD fla SERVER_START_REQ( send_hardware_message ) { req->win = wine_server_user_handle( hwnd ); - req->flags = 0; req->input.type = INPUT_MOUSE; req->input.mouse.src = HW_INPUT_SRC_WINDOW|HW_INPUT_SRC_RAWINPUT; req->input.mouse.x = dx; diff --git a/server/protocol.def b/server/protocol.def index 0e302235ca1..cbc0e9ceaad 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -361,6 +361,7 @@ typedef union } hw_input_t; #define HW_INPUT_SRC_WINDOW 1 #define HW_INPUT_SRC_RAWINPUT 2 +#define HW_INPUT_SRC_INJECTED 4
typedef union { @@ -2310,7 +2311,6 @@ 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) */ @REPLY int wait; /* do we need to wait for a reply? */ int prev_x; /* previous cursor position */ @@ -2319,7 +2319,6 @@ enum message_type int new_y; VARARG(keystate,bytes); /* global state array for all the keys */ @END -#define SEND_HWMSG_INJECTED 0x01
/* Get a message from the current queue */ diff --git a/server/queue.c b/server/queue.c index 19da1f34c74..95ffc8db7c3 100644 --- a/server/queue.c +++ b/server/queue.c @@ -1598,8 +1598,9 @@ static int send_hook_ll_message( struct desktop *desktop, struct message *hardwa
/* 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 ) + struct msg_queue *sender ) { + unsigned int origin = (input->mouse.src & HW_INPUT_SRC_INJECTED ? IMO_INJECTED : IMO_HARDWARE); const struct rawinput_device *device; struct hardware_msg_data *msg_data; struct message *msg; @@ -1705,8 +1706,9 @@ 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 ) + struct msg_queue *sender ) { + unsigned int origin = (input->kbd.src & HW_INPUT_SRC_INJECTED ? IMO_INJECTED : IMO_HARDWARE); struct hw_msg_source source = { IMDT_KEYBOARD, origin }; const struct rawinput_device *device; struct hardware_msg_data *msg_data; @@ -1836,8 +1838,9 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c
/* queue a hardware message for a custom type of event */ static void queue_custom_hardware_message( struct desktop *desktop, user_handle_t win, - unsigned int origin, const hw_input_t *input ) + const hw_input_t *input ) { + unsigned int origin = (input->hw.src & HW_INPUT_SRC_INJECTED ? IMO_INJECTED : IMO_HARDWARE); struct hw_msg_source source = { IMDT_UNAVAILABLE, origin }; struct message *msg;
@@ -2336,7 +2339,6 @@ DECL_HANDLER(send_hardware_message) { struct thread *thread = NULL; struct desktop *desktop; - unsigned int origin = (req->flags & SEND_HWMSG_INJECTED ? IMO_INJECTED : IMO_HARDWARE); struct msg_queue *sender = get_current_queue(); data_size_t size = min( 256, get_reply_max_size() );
@@ -2359,13 +2361,13 @@ 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, sender ); 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, sender ); break; case INPUT_HARDWARE: - queue_custom_hardware_message( desktop, req->win, origin, &req->input ); + queue_custom_hardware_message( desktop, req->win, &req->input ); break; default: set_error( STATUS_INVALID_PARAMETER ); diff --git a/server/trace.c b/server/trace.c index 6674505bc1c..61894e8af19 100644 --- a/server/trace.c +++ b/server/trace.c @@ -379,12 +379,13 @@ static void dump_irp_params( const char *prefix, const irp_params_t *data )
static void dump_hw_input( const char *prefix, const hw_input_t *input ) { - char src[] = "--"; + char src[] = "---"; switch (input->type) { case INPUT_MOUSE: if (input->mouse.src & HW_INPUT_SRC_WINDOW) src[0] = 'w'; if (input->mouse.src & HW_INPUT_SRC_RAWINPUT) src[1] = 'r'; + if (input->mouse.src & HW_INPUT_SRC_INJECTED) src[2] = 'i'; fprintf( stderr, "%s{type=MOUSE,src=%s,x=%d,y=%d,data=%08x,flags=%08x,time=%u", prefix, src, input->mouse.x, input->mouse.y, input->mouse.data, input->mouse.flags, input->mouse.time ); @@ -394,6 +395,7 @@ static void dump_hw_input( const char *prefix, const hw_input_t *input ) case INPUT_KEYBOARD: if (input->kbd.src & HW_INPUT_SRC_WINDOW) src[0] = 'w'; if (input->kbd.src & HW_INPUT_SRC_RAWINPUT) src[1] = 'r'; + if (input->kbd.src & HW_INPUT_SRC_INJECTED) src[2] = 'i'; fprintf( stderr, "%s{type=KEYBOARD,src=%s,vkey=%04hx,scan=%04hx,flags=%08x,time=%u", prefix, src, input->kbd.vkey, input->kbd.scan, input->kbd.flags, input->kbd.time ); dump_uint64( ",info=", &input->kbd.info ); @@ -402,6 +404,7 @@ static void dump_hw_input( const char *prefix, const hw_input_t *input ) case INPUT_HARDWARE: if (input->hw.src & HW_INPUT_SRC_WINDOW) src[0] = 'w'; if (input->hw.src & HW_INPUT_SRC_RAWINPUT) src[1] = 'r'; + if (input->hw.src & HW_INPUT_SRC_INJECTED) src[2] = 'i'; fprintf( stderr, "%s{type=HARDWARE,src=%s,msg=%04x", prefix, src, input->hw.msg ); dump_uint64( ",lparam=", &input->hw.lparam ); fputc( '}', stderr );