x11.drv: [2/2] Use internal cached cursor position for GetCursorPos.

Mirek thunder.m at czela.net
Tue Oct 3 15:29:27 CDT 2006


Why was not accepted those patches? With those patches is mouse moving 
in some games perfetly smooth and correct (Tomb Raider Legend, GTA San 
Andreas, NFS Most Wanted).

Mirek

Vitaliy Margolen napsal(a):
> ChangeLog:
> winex11.drv: Use internal cached cursor position for GetCursorPos.
> Query X directly only when cursor is outside process' windows.
> 
> We need to use cached cursor position in GetCursorPos() because it should
> return previous position inside hook handler. And get updated right after
> hook chain is finished and we sent appropriate mouse messages.
> 
> However we have a problem with synchronizing this cached cursor position
> between processes. To solve that we can either share that information between
> processes or query X the same we did before, if cursor is outside process'
> windows.
> 
>  dlls/winex11.drv/event.c  |    4 +--
>  dlls/winex11.drv/mouse.c  |   71 ++++++++++++++++++++++++++++++---------------
>  dlls/winex11.drv/window.c |    2 +
>  dlls/winex11.drv/x11drv.h |    1 +
>  4 files changed, 52 insertions(+), 26 deletions(-)
> 
> 
> 
> ------------------------------------------------------------------------
> 
> b81f98baf1ba0321f413a0a0c3a5cf90b07fab8c
> diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
> index 210d816..bbd1a0c 100644
> --- a/dlls/winex11.drv/event.c
> +++ b/dlls/winex11.drv/event.c
> @@ -87,7 +87,7 @@ static struct event_handler handlers[MAX
>      { ButtonRelease,    X11DRV_ButtonRelease },
>      { MotionNotify,     X11DRV_MotionNotify },
>      { EnterNotify,      X11DRV_EnterNotify },
> -    /* LeaveNotify */
> +    { LeaveNotify,      X11DRV_LeaveNotify },
>      { FocusIn,          EVENT_FocusIn },
>      { FocusOut,         EVENT_FocusOut },
>      { KeymapNotify,     X11DRV_KeymapNotify },
> @@ -116,7 +116,7 @@ static struct event_handler handlers[MAX
>      { MappingNotify,    X11DRV_MappingNotify },
>  };
>  
> -static int nb_event_handlers = 18;  /* change this if you add handlers above */
> +static int nb_event_handlers = 19;  /* change this if you add handlers above */
>  
>  
>  /* return the name of an X event */
> diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
> index 14ffcc7..470b9f1 100644
> --- a/dlls/winex11.drv/mouse.c
> +++ b/dlls/winex11.drv/mouse.c
> @@ -70,6 +70,7 @@ static const UINT button_up_flags[NB_BUT
>  };
>  
>  POINT cursor_pos;
> +static int mouse_inside_wine;
>  
>  static CRITICAL_SECTION cursor_CritSection;
>  static CRITICAL_SECTION_DEBUG critsect_debug =
> @@ -697,17 +698,29 @@ BOOL X11DRV_SetCursorPos( INT x, INT y )
>  {
>      Display *display = thread_display();
>  
> -    TRACE( "warping to (%d,%d)\n", x, y );
> +    /* Cursor position hasn't changed at all or not yet. */
> +    EnterCriticalSection(&cursor_CritSection);
> +    if (cursor_pos.x == x && cursor_pos.y == y)
> +    {
> +        LeaveCriticalSection(&cursor_CritSection);
>  
> -    wine_tsx11_lock();
> -    XWarpPointer( display, root_window, root_window, 0, 0, 0, 0, x, y );
> -    XFlush( display ); /* avoids bad mouse lag in games that do their own mouse warping */
> -    wine_tsx11_unlock();
> +        /* We still need to generate WM_MOUSEMOVE */
> +        queue_raw_mouse_message( WM_MOUSEMOVE, NULL, x, y, 0, GetCurrentTime(), 0, 0 );
> +        return TRUE;
> +    }
> +    LeaveCriticalSection(&cursor_CritSection);
> +
> +    TRACE( "warping to (%d,%d)\n", x, y );
>  
>      EnterCriticalSection( &cursor_CritSection );
>      cursor_pos.x = x;
>      cursor_pos.y = y;
>      LeaveCriticalSection( &cursor_CritSection );
> +
> +    wine_tsx11_lock();
> +    XWarpPointer( display, root_window, root_window, 0, 0, 0, 0, x, y );
> +    XFlush( display ); /* avoids bad mouse lag in games that do their own mouse warping */
> +    wine_tsx11_unlock();
>      return TRUE;
>  }
>  
> @@ -716,25 +729,28 @@ BOOL X11DRV_SetCursorPos( INT x, INT y )
>   */
>  BOOL X11DRV_GetCursorPos(LPPOINT pos)
>  {
> -    Display *display = thread_display();
> -    Window root, child;
> -    int rootX, rootY, winX, winY;
> -    unsigned int xstate;
> -    BOOL res;
> -
> -    wine_tsx11_lock();
> -    res = XQueryPointer( display, root_window, &root, &child,
> -                         &rootX, &rootY, &winX, &winY, &xstate );
> -    wine_tsx11_unlock();
> -    if (res)
> +    if (!mouse_inside_wine)
>      {
> -        update_key_state( xstate );
> -        update_button_state( xstate );
> -        TRACE("pointer at (%d,%d)\n", winX, winY );
> -        EnterCriticalSection( &cursor_CritSection );
> -        cursor_pos.x = winX;
> -        cursor_pos.y = winY;
> -        LeaveCriticalSection( &cursor_CritSection );
> +        Display *display = thread_display();
> +        Window root, child;
> +        int rootX, rootY, winX, winY;
> +        unsigned int xstate;
> +        Bool res;
> +
> +        wine_tsx11_lock();
> +        res = XQueryPointer( display, root_window, &root, &child,
> +                             &rootX, &rootY, &winX, &winY, &xstate );
> +        wine_tsx11_unlock();
> +        if (res)
> +        {
> +            update_key_state( xstate );
> +            update_button_state( xstate );
> +            TRACE("pointer at (%d,%d)\n", winX, winY );
> +            EnterCriticalSection( &cursor_CritSection );
> +            cursor_pos.x = winX;
> +            cursor_pos.y = winY;
> +            LeaveCriticalSection( &cursor_CritSection );
> +        }
>      }
>      EnterCriticalSection( &cursor_CritSection );
>      *pos = cursor_pos;
> @@ -838,6 +854,7 @@ void X11DRV_EnterNotify( HWND hwnd, XEve
>  
>      TRACE("hwnd %p, event->detail %d\n", hwnd, event->detail);
>  
> +    mouse_inside_wine = TRUE;
>      if (!hwnd) return;
>      if (event->detail == NotifyVirtual || event->detail == NotifyNonlinearVirtual) return;
>  
> @@ -847,3 +864,11 @@ void X11DRV_EnterNotify( HWND hwnd, XEve
>      X11DRV_send_mouse_input( hwnd, MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE,
>                               pt.x, pt.y, 0, EVENT_x11_time_to_win32_time(event->time), 0, 0 );
>  }
> +
> +/***********************************************************************
> + *           X11DRV_LeaveNotify
> + */
> +void X11DRV_LeaveNotify( HWND hwnd, XEvent *xev )
> +{
> +    mouse_inside_wine = FALSE;
> +}
> diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
> index fe07ddf..17ecc1e 100644
> --- a/dlls/winex11.drv/window.c
> +++ b/dlls/winex11.drv/window.c
> @@ -758,7 +758,7 @@ static Window create_whole_window( Displ
>      attr.event_mask    = (ExposureMask | PointerMotionMask |
>                            ButtonPressMask | ButtonReleaseMask | EnterWindowMask |
>                            KeyPressMask | KeyReleaseMask | StructureNotifyMask |
> -                          FocusChangeMask | KeymapStateMask);
> +                          FocusChangeMask | KeymapStateMask | LeaveWindowMask);
>      mask |= CWBitGravity | CWBackingStore | CWEventMask;
>  
>      wine_tsx11_lock();
> diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
> index b5bec51..2e1423e 100644
> --- a/dlls/winex11.drv/x11drv.h
> +++ b/dlls/winex11.drv/x11drv.h
> @@ -611,6 +611,7 @@ extern void X11DRV_ButtonPress( HWND hwn
>  extern void X11DRV_ButtonRelease( HWND hwnd, XEvent *event );
>  extern void X11DRV_MotionNotify( HWND hwnd, XEvent *event );
>  extern void X11DRV_EnterNotify( HWND hwnd, XEvent *event );
> +extern void X11DRV_LeaveNotify( HWND hwnd, XEvent *event );
>  extern void X11DRV_KeyEvent( HWND hwnd, XEvent *event );
>  extern void X11DRV_KeymapNotify( HWND hwnd, XEvent *event );
>  extern void X11DRV_Expose( HWND hwnd, XEvent *event );
> 
> 
> 
> ------------------------------------------------------------------------
> 
> 



More information about the wine-devel mailing list