[PATCH v10 7/9] winex11.drv: Implement native mouse-movement raw-input using RawMotion.

Derek Lesho dereklesho52 at gmail.com
Mon Aug 5 00:05:30 CDT 2019


> Not sure what this implies exactly, is it really needed for raw mouse
movements?

Maybe this isn't the right patch for it, but I found that since we
don't handle ButtonPress messages, it was causing an issue where mouse
movement didn't work while a mouse button was pressed.  I'm honestly
not sure why it's added to the mask in the first place.

On Fri, Aug 2, 2019 at 4:29 AM Rémi Bernon <rbernon at codeweavers.com> wrote:
>
> On 8/2/19 8:24 AM, Derek Lesho wrote:
> > Signed-off-by: Derek Lesho <dereklesho52 at Gmail.com>
> > ---
> >   dlls/winex11.drv/mouse.c       | 68 +++++++++++++++++++++++++---------
> >   dlls/winex11.drv/x11drv.h      |  4 +-
> >   dlls/winex11.drv/x11drv_main.c |  4 ++
> >   3 files changed, 58 insertions(+), 18 deletions(-)
> >
> > diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
> > index 578efa1931..2fd38db263 100644
> > --- a/dlls/winex11.drv/mouse.c
> > +++ b/dlls/winex11.drv/mouse.c
> > @@ -288,9 +288,9 @@ static void update_relative_valuators(XIAnyClassInfo **valuators, int n_valuator
> >
> >
> >   /***********************************************************************
> > - *              enable_xinput2
> > + *              X11DRV_XInput2_Enable
> >    */
> > -static void enable_xinput2(void)
> > +void X11DRV_XInput2_Enable(void)
> >   {
> >   #ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
> >       struct x11drv_thread_data *data = x11drv_thread_data();
> > @@ -322,7 +322,6 @@ static void enable_xinput2(void)
> >       mask.deviceid = XIAllMasterDevices;
> >       memset( mask_bits, 0, sizeof(mask_bits) );
> >       XISetMask( mask_bits, XI_RawMotion );
> > -    XISetMask( mask_bits, XI_ButtonPress );
>
> Not sure what this implies exactly, is it really needed for raw mouse
> movements?
>
> >
> >       /* XInput 2.0 has a problematic behavior where master pointer will
> >        * not send raw events to the root window whenever a grab is active
> > @@ -354,15 +353,15 @@ static void enable_xinput2(void)
> >   }
> >
> >   /***********************************************************************
> > - *              disable_xinput2
> > + *              X11DRV_XInput2_Disable
> >    */
> > -static void disable_xinput2(void)
> > +void X11DRV_XInput2_Disable(void)
> >   {
> >   #ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
> >       struct x11drv_thread_data *data = x11drv_thread_data();
> >       XIEventMask mask;
> >
> > -    if (data->xi2_state != xi_enabled) return;
> > +    if (data->xi2_state < xi_enabled) return;
> >
> >       TRACE( "disabling\n" );
> >       data->xi2_state = xi_disabled;
> > @@ -387,6 +386,21 @@ static void disable_xinput2(void)
> >   #endif
> >   }
> >
> > +static void use_xinput2_path(void)
> > +{
> > +    struct x11drv_thread_data *thread_data = x11drv_thread_data();
> > +
> > +    if (thread_data->xi2_state == xi_enabled)
> > +        thread_data->xi2_state = xi_extra;
> > +}
> > +
> > +static void disable_xinput2_path(void)
> > +{
> > +    struct x11drv_thread_data *thread_data = x11drv_thread_data();
> > +
> > +    if (thread_data->xi2_state == xi_extra)
> > +        thread_data->xi2_state = xi_enabled;
> > +}
> >
> >   /***********************************************************************
> >    *          grab_clipping_window
> > @@ -412,9 +426,9 @@ static BOOL grab_clipping_window( const RECT *clip )
> >           return TRUE;
> >
> >       /* enable XInput2 unless we are already clipping */
> > -    if (!data->clip_hwnd) enable_xinput2();
> > +    if (!data->clip_hwnd) use_xinput2_path();
> >
> > -    if (data->xi2_state != xi_enabled)
> > +    if (data->xi2_state < xi_extra)
> >       {
> >           WARN( "XInput2 not supported, refusing to clip to %s\n", wine_dbgstr_rect(clip) );
> >           DestroyWindow( msg_hwnd );
> > @@ -442,7 +456,7 @@ static BOOL grab_clipping_window( const RECT *clip )
> >
> >       if (!clipping_cursor)
> >       {
> > -        disable_xinput2();
> > +        disable_xinput2_path();
> >           DestroyWindow( msg_hwnd );
> >           return FALSE;
> >       }
> > @@ -508,7 +522,7 @@ LRESULT clip_cursor_notify( HWND hwnd, HWND new_clip_hwnd )
> >           TRACE( "clip hwnd reset from %p\n", hwnd );
> >           data->clip_hwnd = 0;
> >           data->clip_reset = GetTickCount();
> > -        disable_xinput2();
> > +        disable_xinput2_path();
> >           DestroyWindow( hwnd );
> >       }
> >       else if (hwnd == GetForegroundWindow())  /* request to clip */
>
> I would love to get rid of this "extra" level of enablement and always
> send "normal" inputs on RawMotion events, regardless of cursor clipping
> state, but I guess it's safer to keep old behaviour.
>
> > @@ -1743,16 +1757,18 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
> >   {
> >       XIRawEvent *event = xev->data;
> >       const double *values = event->valuators.values;
> > +    const double *raw_values = event->raw_values;
> >       RECT virtual_rect;
> >       INPUT input;
> > +    RAWINPUT raw_input;
> >       int i;
> > -    double dx = 0, dy = 0, val;
> > +    double dx = 0, dy = 0, raw_dx = 0, raw_dy = 0, val, raw_val;
> >       struct x11drv_thread_data *thread_data = x11drv_thread_data();
> >       struct x11drv_valuator_data *x_rel, *y_rel;
> >
> >       if (thread_data->x_rel_valuator.number < 0 || thread_data->y_rel_valuator.number < 0) return FALSE;
> >       if (!event->valuators.mask_len) return FALSE;
> > -    if (thread_data->xi2_state != xi_enabled) return FALSE;
> > +    if (thread_data->xi2_state < xi_enabled) return FALSE;
> >
> >       if (xinput2_version_major == 2 && xinput2_version_minor == 0)
> >       {
> > @@ -1784,12 +1800,20 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
> >       x_rel = &thread_data->x_rel_valuator;
> >       y_rel = &thread_data->y_rel_valuator;
> >
> > +    input.type = INPUT_MOUSE;
> >       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;
> > +    input.u.mi.dx = 0;
> > +    input.u.mi.dy = 0;
> > +
>
> Nitpick: the formatting change is superfluous (the input.type line is
> probably OK though).
>
> > +    raw_input.header.dwType = RIM_TYPEMOUSE;
> > +    raw_input.data.mouse.u.usButtonFlags = 0;
> > +    raw_input.data.mouse.u.usButtonData = 0;
> > +    raw_input.data.mouse.ulExtraInformation = 0;
> > +    raw_input.data.mouse.lLastX = 0;
> > +    raw_input.data.mouse.lLastY = 0;
> >
> >       virtual_rect = get_virtual_screen_rect();
> >
> > @@ -1797,12 +1821,15 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
> >       {
> >           if (!XIMaskIsSet( event->valuators.mask, i )) continue;
> >           val = *values++;
> > +        raw_val = *raw_values++;
> >           if (i == x_rel->number)
> >           {
> >               input.u.mi.dx = dx = val;
> >               if (x_rel->min < x_rel->max)
> >                   input.u.mi.dx = val * (virtual_rect.right - virtual_rect.left)
> >                                       / (x_rel->max - x_rel->min);
> > +
> > +            raw_input.data.mouse.lLastX = raw_dx = raw_val;
> >           }
> >           if (i == y_rel->number)
> >           {
> > @@ -1810,6 +1837,8 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
> >               if (y_rel->min < y_rel->max)
> >                   input.u.mi.dy = val * (virtual_rect.bottom - virtual_rect.top)
> >                                       / (y_rel->max - y_rel->min);
> > +
> > +            raw_input.data.mouse.lLastY = raw_dy = raw_val;
> >           }
> >       }
> >
> > @@ -1819,10 +1848,15 @@ static BOOL X11DRV_RawMotion( XGenericEventCookie *xev )
> >           return FALSE;
> >       }
> >
> > -    TRACE( "pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, dx, dy );
> > +    if (thread_data->xi2_state == xi_extra)
> > +    {
> > +        TRACE( "pos %d,%d (event %f,%f)\n", input.u.mi.dx, input.u.mi.dy, dx, dy );
> > +        __wine_send_input( 0, &input );
> > +    }
> > +
> > +    TRACE("raw event %f,%f\n",  raw_dx, raw_dy);
> > +    __wine_send_raw_input( &raw_input );
> >
> > -    input.type = INPUT_MOUSE;
> > -    __wine_send_input( 0, &input );
> >       return TRUE;
> >   }
> >
> > diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
> > index 0d3695bdcf..2223629c7b 100644
> > --- a/dlls/winex11.drv/x11drv.h
> > +++ b/dlls/winex11.drv/x11drv.h
> > @@ -194,6 +194,8 @@ extern BOOL CDECL X11DRV_UnrealizePalette( HPALETTE hpal ) DECLSPEC_HIDDEN;
> >
> >   extern void X11DRV_Xcursor_Init(void) DECLSPEC_HIDDEN;
> >   extern void X11DRV_XInput2_Init(void) DECLSPEC_HIDDEN;
> > +extern void X11DRV_XInput2_Enable(void) DECLSPEC_HIDDEN;
> > +extern void X11DRV_XInput2_Disable(void) DECLSPEC_HIDDEN;
> >
> >   extern DWORD copy_image_bits( BITMAPINFO *info, BOOL is_r8g8b8, XImage *image,
> >                                 const struct gdi_image_bits *src_bits, struct gdi_image_bits *dst_bits,
> > @@ -335,7 +337,7 @@ struct x11drv_thread_data
> >       HWND     clip_hwnd;            /* message window stored in desktop while clipping is active */
> >       DWORD    clip_reset;           /* time when clipping was last reset */
> >       HKL      kbd_layout;           /* active keyboard layout */
> > -    enum { xi_unavailable = -1, xi_unknown, xi_disabled, xi_enabled } xi2_state; /* XInput2 state */
> > +    enum { xi_unavailable = -1, xi_unknown, xi_disabled, xi_enabled, xi_extra } xi2_state; /* XInput2 state */
> >       void    *xi2_devices;          /* list of XInput2 devices (valid when state is enabled) */
> >       int      xi2_device_count;
> >       struct x11drv_valuator_data x_rel_valuator;
> > diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
> > index 21807af3f1..214c101b67 100644
> > --- a/dlls/winex11.drv/x11drv_main.c
> > +++ b/dlls/winex11.drv/x11drv_main.c
> > @@ -611,6 +611,8 @@ void CDECL X11DRV_ThreadDetach(void)
> >
> >       if (data)
> >       {
> > +        X11DRV_XInput2_Disable();
> > +
> >           if (data->xim) XCloseIM( data->xim );
> >           if (data->font_set) XFreeFontSet( data->display, data->font_set );
> >           XCloseDisplay( data->display );
> > @@ -681,6 +683,8 @@ struct x11drv_thread_data *x11drv_init_thread_data(void)
> >
> >       if (use_xim) X11DRV_SetupXIM();
> >
> > +    X11DRV_XInput2_Enable();
> > +
> >       return data;
> >   }
> >
> >
> --
> Rémi Bernon <rbernon at codeweavers.com>
>
>



More information about the wine-devel mailing list