[PATCH v9 7/8] winex11.drv: Implement native mouse-button raw-input using RawButton*.

Derek Lesho dereklesho52 at gmail.com
Fri Jul 26 18:19:59 CDT 2019


Signed-off-by: Derek Lesho <dereklesho52 at Gmail.com>
---
 dlls/winex11.drv/mouse.c  | 97 +++++++++++++++++++++++++++++++++++++--
 dlls/winex11.drv/x11drv.h |  1 +
 2 files changed, 93 insertions(+), 5 deletions(-)

diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index 7423f946b9..9259907eb5 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -257,6 +257,7 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
 
     thread_data->x_rel_valuator.number = -1;
     thread_data->y_rel_valuator.number = -1;
+    thread_data->wheel_valuator.number = -1;
 
     for (i = 0; i < n_valuators; i++)
     {
@@ -274,6 +275,10 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
         {
             valuator_data = &thread_data->y_rel_valuator;
         }
+        else if (class->number == 3) /* scroll wheel */
+        {
+            valuator_data = &thread_data->wheel_valuator;
+        }
 
         if (valuator_data) {
             valuator_data->number = class->number;
@@ -285,6 +290,21 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
 #endif
 
 
+/***********************************************************************
+ *              inform_wineserver
+ */
+static void inform_wineserver(void)
+{
+    static int once = 0;
+    if (!once)
+    {
+        RAWINPUT raw_input;
+        raw_input.header.dwType = RIM_ENABLE_NATIVE_MOUSE;
+        __wine_send_raw_input(&raw_input);
+        once = 1;
+    }
+}
+
 /***********************************************************************
  *              X11DRV_XInput2_Enable
  */
@@ -318,6 +338,8 @@ void X11DRV_XInput2_Enable(void)
     mask.deviceid = XIAllMasterDevices;
     memset( mask_bits, 0, sizeof(mask_bits) );
     XISetMask( mask_bits, XI_RawMotion );
+    XISetMask( mask_bits, XI_RawButtonPress );
+    XISetMask( mask_bits, XI_RawButtonRelease );
 
     pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask, 1 );
 
@@ -326,6 +348,8 @@ void X11DRV_XInput2_Enable(void)
     pXIFreeDeviceInfo( pointer_info );
 
     data->xi2_state = xi_enabled;
+
+    inform_wineserver();
 #endif
 }
 
@@ -350,6 +374,7 @@ void X11DRV_XInput2_Disable(void)
     pXISelectEvents( data->display, DefaultRootWindow( data->display ), &mask, 1 );
     data->x_rel_valuator.number = -1;
     data->y_rel_valuator.number = -1;
+    data->wheel_valuator.number = -1;
 #endif
 }
 
@@ -1713,16 +1738,17 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
     INPUT input;
     RAWINPUT raw_input;
     int i;
-    double dx = 0, dy = 0, raw_dx = 0, raw_dy = 0, val, raw_val;
+    double dx = 0, dy = 0, raw_dx = 0, raw_dy = 0, dwheel = 0, val, raw_val;
     struct x11drv_thread_data *thread_data = x11drv_thread_data();
-    struct x11drv_valuator_data *x_rel, *y_rel;
+    struct x11drv_valuator_data *x_rel, *y_rel, *wheel;
 
-    if (thread_data->x_rel_valuator.number < 0 || thread_data->y_rel_valuator.number < 0) return FALSE;
+    if (thread_data->x_rel_valuator.number < 0 || thread_data->y_rel_valuator.number < 0 || thread_data->wheel_valuator.number < 0) return FALSE;
     if (!event->valuators.mask_len) return FALSE;
     if (thread_data->xi2_state < xi_enabled) return FALSE;
 
     x_rel = &thread_data->x_rel_valuator;
     y_rel = &thread_data->y_rel_valuator;
+    wheel = &thread_data->wheel_valuator;
 
     input.type = INPUT_MOUSE;
     input.u.mi.mouseData   = 0;
@@ -1741,7 +1767,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
 
     virtual_rect = get_virtual_screen_rect();
 
-    for (i = 0; i <= max ( x_rel->number, y_rel->number ); i++)
+    for (i = 0; i <= max( wheel->number, max( x_rel->number, y_rel->number ) ); i++)
     {
         if (!XIMaskIsSet( event->valuators.mask, i )) continue;
         val = *values++;
@@ -1764,6 +1790,8 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
 
             raw_input.data.mouse.lLastY = raw_dy = raw_val;
         }
+        if (i == wheel->number)
+            dwheel = raw_val;
     }
 
     if (broken_rawevents && is_old_motion_event( xev->serial ))
@@ -1778,12 +1806,66 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
         __wine_send_input( 0, &input );
     }
 
-    TRACE("raw event %f,%f\n",  raw_dx, raw_dy);
+    if (dwheel)
+    {
+        raw_input.data.mouse.u.usButtonFlags = RI_MOUSE_WHEEL;
+        raw_input.data.mouse.u.usButtonData  = dwheel;
+    }
+
+    TRACE("raw event %f,%f + %f\n",  raw_dx, raw_dy, dwheel);
     __wine_send_raw_input( &raw_input );
 
     return TRUE;
 }
 
+/***********************************************************************
+ *           X11DRV_RawButton
+ */
+static BOOL X11DRV_RawButton( XGenericEventCookie *xev )
+{
+    RAWINPUT ri;
+
+    static const unsigned short raw_button_press_flags[] = {
+        0,                              /* 0 = unused */
+        RI_MOUSE_LEFT_BUTTON_DOWN,      /* 1 */
+        RI_MOUSE_MIDDLE_BUTTON_DOWN,    /* 2 */
+        RI_MOUSE_RIGHT_BUTTON_DOWN,     /* 3 */
+        0,                              /* 4 = unknown */
+        0,                              /* 5 = unknown */
+        0,                              /* 6 = unknown */
+        0,                              /* 7 = unknown */
+        RI_MOUSE_BUTTON_4_DOWN,         /* 8 */
+        RI_MOUSE_BUTTON_5_DOWN          /* 9 */
+    };
+
+    static const unsigned short raw_button_release_flags[] = {
+        0,                            /* 0 = unused */
+        RI_MOUSE_LEFT_BUTTON_UP,      /* 1 */
+        RI_MOUSE_MIDDLE_BUTTON_UP,    /* 2 */
+        RI_MOUSE_RIGHT_BUTTON_UP,     /* 3 */
+        0,                            /* 4 = unknown */
+        0,                            /* 5 = unknown */
+        0,                            /* 6 = unknown */
+        0,                            /* 7 = unknown */
+        RI_MOUSE_BUTTON_4_UP,         /* 8 */
+        RI_MOUSE_BUTTON_5_UP          /* 9 */
+    };
+
+    int detail = ((XIRawEvent*)xev->data)->detail;
+    if (detail > 9) return TRUE;
+
+    ri.header.dwType = RIM_TYPEMOUSE;
+    ri.data.mouse.u.usButtonFlags = xev->evtype == XI_RawButtonPress ? raw_button_press_flags[detail] : raw_button_release_flags[detail] ;
+    ri.data.mouse.u.usButtonData = 0;
+    ri.data.mouse.lLastX = 0;
+    ri.data.mouse.lLastY = 0;
+    ri.data.mouse.ulExtraInformation = 0;
+
+    __wine_send_raw_input( &ri );
+
+    return TRUE;
+}
+
 #endif /* HAVE_X11_EXTENSIONS_XINPUT2_H */
 
 
@@ -1845,6 +1927,11 @@ BOOL X11DRV_GenericEvent( HWND hwnd, XEvent *xev )
     case XI_RawMotion:
         ret = X11DRV_RawMotion( event );
         break;
+    case XI_RawButtonPress:
+        /* fall through */
+    case XI_RawButtonRelease:
+        ret = X11DRV_RawButton( event );
+        break;
 
     default:
         TRACE( "Unhandled event %#x\n", event->evtype );
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index a6d64f4383..8af2ebfcef 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -340,6 +340,7 @@ struct x11drv_thread_data
     enum { xi_unavailable = -1, xi_unknown, xi_disabled, xi_enabled, xi_extra } xi2_state; /* XInput2 state */
     struct x11drv_valuator_data x_rel_valuator;
     struct x11drv_valuator_data y_rel_valuator;
+    struct x11drv_valuator_data wheel_valuator;
 };
 
 extern struct x11drv_thread_data *x11drv_init_thread_data(void) DECLSPEC_HIDDEN;
-- 
2.22.0




More information about the wine-devel mailing list