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 );



------------------------------------------------------------------------




Reply via email to