[RFC PATCH 3/6] winex11.drv: Replace __wine_send_input with direct send_hardware_message request.

Rémi Bernon rbernon at codeweavers.com
Mon Nov 11 14:23:00 CST 2019


Signed-off-by: Rémi Bernon <rbernon at 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;
 }
 
-- 
2.24.0.rc2




More information about the wine-devel mailing list