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

Derek Lesho dereklesho52 at gmail.com
Fri Aug 2 01:24:34 CDT 2019


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

diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index 2fd38db263..650e81204d 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -259,6 +259,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++)
     {
@@ -276,6 +277,11 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
         {
             valuator_data = &thread_data->y_rel_valuator;
         }
+        else if (class->label == x11drv_atom( Rel_Vert_Scroll ) ||
+                 (!class->label && class->number == 3 && class->mode == XIModeRelative))
+        {
+            valuator_data = &thread_data->wheel_valuator;
+        }
 
         if (valuator_data) {
             valuator_data->number = class->number;
@@ -322,6 +328,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 );
 
     /* XInput 2.0 has a problematic behavior where master pointer will
      * not send raw events to the root window whenever a grab is active
@@ -380,6 +388,7 @@ void X11DRV_XInput2_Disable(void)
     pXIFreeDeviceInfo( data->xi2_devices );
     data->x_rel_valuator.number = -1;
     data->y_rel_valuator.number = -1;
+    data->wheel_valuator.number = -1;
     data->xi2_devices = NULL;
     data->xi2_core_pointer = 0;
     data->xi2_current_slave = 0;
@@ -1762,11 +1771,11 @@ 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;
 
@@ -1799,6 +1808,7 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
 
     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;
@@ -1817,7 +1827,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++;
@@ -1840,6 +1850,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 ))
@@ -1854,12 +1866,67 @@ 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 * 8;
+    }
+
+    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;
+
+    if (ri.data.mouse.u.usButtonFlags)
+        __wine_send_raw_input( &ri );
+
+    return TRUE;
+}
+
 #endif /* HAVE_X11_EXTENSIONS_XINPUT2_H */
 
 
@@ -1924,6 +1991,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 2223629c7b..c74f1493c0 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -342,6 +342,7 @@ struct x11drv_thread_data
     int      xi2_device_count;
     struct x11drv_valuator_data x_rel_valuator;
     struct x11drv_valuator_data y_rel_valuator;
+    struct x11drv_valuator_data wheel_valuator;
     int      xi2_core_pointer;     /* XInput2 core pointer id */
     int      xi2_current_slave;    /* Current slave driving the Core pointer */
 };
@@ -427,6 +428,7 @@ enum x11drv_atoms
     XATOM_RAW_CAP_HEIGHT,
     XATOM_Rel_X,
     XATOM_Rel_Y,
+    XATOM_Rel_Vert_Scroll,
     XATOM_WM_PROTOCOLS,
     XATOM_WM_DELETE_WINDOW,
     XATOM_WM_STATE,
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index 214c101b67..86b6efac08 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -120,6 +120,7 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
     "RAW_CAP_HEIGHT",
     "Rel X",
     "Rel Y",
+    "Rel Vert Scroll",
     "WM_PROTOCOLS",
     "WM_DELETE_WINDOW",
     "WM_STATE",
-- 
2.22.0




More information about the wine-devel mailing list