Alexandre Julliard : winex11: Update the cursor from the thread input status instead of caching it per-thread in x11drv .

Alexandre Julliard julliard at winehq.org
Wed Apr 21 10:40:18 CDT 2010


Module: wine
Branch: master
Commit: eed9c63ac7650293523da5c8d067c74258568ba8
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=eed9c63ac7650293523da5c8d067c74258568ba8

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Apr 20 20:52:17 2010 +0200

winex11: Update the cursor from the thread input status instead of caching it per-thread in x11drv.

---

 dlls/winex11.drv/mouse.c       |   51 ++++++++++++++++++----------------------
 dlls/winex11.drv/window.c      |   16 ++++--------
 dlls/winex11.drv/x11drv.h      |    5 ++-
 dlls/winex11.drv/x11drv_main.c |    5 +++-
 4 files changed, 35 insertions(+), 42 deletions(-)

diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index c140ca3..152763b 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -194,7 +194,7 @@ static Cursor get_empty_cursor(void)
 /***********************************************************************
  *		get_x11_cursor
  */
-static Cursor get_x11_cursor( HCURSOR handle )
+Cursor get_x11_cursor( HCURSOR handle )
 {
     Cursor cursor;
 
@@ -216,15 +216,7 @@ static void update_mouse_state( HWND hwnd, Window window, int x, int y, unsigned
 
     get_coords( hwnd, window, x, y, pt );
 
-    /* update the cursor */
-
-    if (data->cursor_window != window)
-    {
-        data->cursor_window = window;
-        wine_tsx11_lock();
-        if (data->cursor) XDefineCursor( data->display, window, data->cursor );
-        wine_tsx11_unlock();
-    }
+    data->cursor_window = hwnd;
 
     /* update the wine server Z-order */
 
@@ -279,6 +271,7 @@ static void queue_raw_mouse_message( UINT message, HWND hwnd, DWORD x, DWORD y,
                                      DWORD data, DWORD time, DWORD extra_info, UINT injected_flags )
 {
     MSLLHOOKSTRUCT hook;
+    HCURSOR cursor;
 
     hook.pt.x        = x;
     hook.pt.y        = y;
@@ -302,9 +295,20 @@ static void queue_raw_mouse_message( UINT message, HWND hwnd, DWORD x, DWORD y,
         req->time     = time;
         req->info     = extra_info;
         wine_server_call( req );
+        cursor = (reply->count >= 0) ? wine_server_ptr_handle(reply->cursor) : 0;
     }
     SERVER_END_REQ;
 
+    if (hwnd)
+    {
+        struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
+        if (data && cursor != data->cursor)
+        {
+            Cursor xcursor = get_x11_cursor( cursor );
+            if (xcursor) XDefineCursor( gdi_display, data->whole_window, xcursor );
+            data->cursor = cursor;
+        }
+    }
 }
 
 
@@ -1005,29 +1009,20 @@ void CDECL X11DRV_DestroyCursorIcon( HCURSOR handle )
  */
 void CDECL X11DRV_SetCursor( HCURSOR handle, CURSORICONINFO *lpCursor )
 {
-    struct x11drv_thread_data *data = x11drv_init_thread_data();
+    struct x11drv_thread_data *thread_data = x11drv_init_thread_data();
+    struct x11drv_win_data *data;
     Cursor cursor;
 
-    if (lpCursor)
-        TRACE("%ux%u, planes %u, bpp %u\n",
-              lpCursor->nWidth, lpCursor->nHeight, lpCursor->bPlanes, lpCursor->bBitsPerPixel);
-    else
-        TRACE("NULL\n");
-
-    /* set the same cursor for all top-level windows of the current thread */
+    if (!(data = X11DRV_get_win_data( thread_data->cursor_window ))) return;
 
     wine_tsx11_lock();
-    cursor = create_cursor( data->display, lpCursor );
-    if (cursor)
+    if ((cursor = get_x11_cursor( handle )))
     {
-        if (data->cursor) XFreeCursor( data->display, data->cursor );
-        data->cursor = cursor;
-        if (data->cursor_window)
-        {
-            XDefineCursor( data->display, data->cursor_window, cursor );
-            /* Make the change take effect immediately */
-            XFlush( data->display );
-        }
+        TRACE( "%p xid %lx\n", handle, cursor );
+        XDefineCursor( gdi_display, data->whole_window, cursor );
+        /* Make the change take effect immediately */
+        XFlush( gdi_display );
+        data->cursor = handle;
     }
     wine_tsx11_unlock();
 }
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index 1621861..bf71cad 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -328,7 +328,6 @@ static int get_window_attributes( Display *display, struct x11drv_win_data *data
     attr->override_redirect = !data->managed;
     attr->colormap          = X11DRV_PALETTE_PaletteXColormap;
     attr->save_under        = ((GetClassLongW( data->hwnd, GCL_STYLE ) & CS_SAVEBITS) != 0);
-    attr->cursor            = x11drv_thread_data()->cursor;
     attr->bit_gravity       = NorthWestGravity;
     attr->win_gravity       = StaticGravity;
     attr->backing_store     = NotUseful;
@@ -338,7 +337,7 @@ static int get_window_attributes( Display *display, struct x11drv_win_data *data
                                KeymapStateMask | StructureNotifyMask);
     if (data->managed) attr->event_mask |= PropertyChangeMask;
 
-    return (CWOverrideRedirect | CWSaveUnder | CWColormap | CWCursor |
+    return (CWOverrideRedirect | CWSaveUnder | CWColormap |
             CWEventMask | CWBitGravity | CWBackingStore);
 }
 
@@ -388,8 +387,6 @@ static Window create_client_window( Display *display, struct x11drv_win_data *da
 
     if (data->client_window)
     {
-        struct x11drv_thread_data *thread_data = x11drv_thread_data();
-        if (thread_data->cursor_window == data->client_window) thread_data->cursor_window = None;
         XDeleteContext( display, data->client_window, winContext );
         XDestroyWindow( display, data->client_window );
     }
@@ -800,8 +797,6 @@ static Window create_icon_window( Display *display, struct x11drv_win_data *data
 static void destroy_icon_window( Display *display, struct x11drv_win_data *data )
 {
     if (!data->icon_window) return;
-    if (x11drv_thread_data()->cursor_window == data->icon_window)
-        x11drv_thread_data()->cursor_window = None;
     wine_tsx11_lock();
     XDeleteContext( display, data->icon_window, winContext );
     XDestroyWindow( display, data->icon_window );
@@ -1057,6 +1052,7 @@ static void set_initial_wm_hints( Display *display, struct x11drv_win_data *data
     Atom dndVersion = WINE_XDND_VERSION;
     XClassHint *class_hints;
     char *process_name = get_process_name();
+    Cursor cursor;
 
     wine_tsx11_lock();
 
@@ -1089,6 +1085,9 @@ static void set_initial_wm_hints( Display *display, struct x11drv_win_data *data
     XChangeProperty( display, data->whole_window, x11drv_atom(XdndAware),
                      XA_ATOM, 32, PropModeReplace, (unsigned char*)&dndVersion, 1 );
 
+    if ((cursor = get_x11_cursor( data->cursor )))
+        XDefineCursor( gdi_display, data->whole_window, cursor );
+
     data->wm_hints = XAllocWMHints();
     wine_tsx11_unlock();
 
@@ -1694,14 +1693,9 @@ done:
  */
 static void destroy_whole_window( Display *display, struct x11drv_win_data *data, BOOL already_destroyed )
 {
-    struct x11drv_thread_data *thread_data = x11drv_thread_data();
-
     if (!data->whole_window) return;
 
     TRACE( "win %p xwin %lx/%lx\n", data->hwnd, data->whole_window, data->client_window );
-    if (thread_data->cursor_window == data->whole_window ||
-        thread_data->cursor_window == data->client_window)
-        thread_data->cursor_window = None;
     wine_tsx11_lock();
     XDeleteContext( display, data->whole_window, winContext );
     XDeleteContext( display, data->client_window, winContext );
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 12ec286..cffb4ee 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -548,8 +548,7 @@ struct x11drv_thread_data
 {
     Display *display;
     XEvent  *current_event;        /* event currently being processed */
-    Cursor   cursor;               /* current cursor */
-    Window   cursor_window;        /* current window that contains the cursor */
+    HWND     cursor_window;        /* current window that contains the cursor */
     Window   grab_window;          /* window that currently grabs the mouse */
     HWND     last_focus;           /* last window that had focus */
     XIM      xim;                  /* input method */
@@ -747,6 +746,7 @@ struct x11drv_win_data
     RECT        whole_rect;     /* X window rectangle for the whole window relative to parent */
     RECT        client_rect;    /* client area relative to parent */
     XIC         xic;            /* X input context */
+    HCURSOR     cursor;         /* current cursor */
     XWMHints   *wm_hints;       /* window manager hints */
     BOOL        managed : 1;    /* is window managed? */
     BOOL        mapped : 1;     /* is window mapped? (in either normal or iconic state) */
@@ -783,6 +783,7 @@ extern int CDECL X11DRV_AcquireClipboard(HWND hWndClipWindow);
 extern void X11DRV_Clipboard_Cleanup(void);
 extern void X11DRV_ResetSelectionOwner(void);
 extern void CDECL X11DRV_SetFocus( HWND hwnd );
+extern Cursor get_x11_cursor( HCURSOR handle );
 extern Cursor X11DRV_GetCursor( Display *display, struct tagCURSORICONINFO *ptr );
 extern void CDECL X11DRV_SetCursor( HCURSOR cursor, struct tagCURSORICONINFO *lpCursor );
 extern BOOL CDECL X11DRV_ClipCursor( LPCRECT clip );
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index 240e4d9..fbe6184 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -197,7 +197,10 @@ static inline BOOL ignore_error( Display *display, XErrorEvent *event )
     /* ignore a number of errors on gdi display caused by creating/destroying windows */
     if (display == gdi_display)
     {
-        if (event->error_code == BadDrawable || event->error_code == BadGC) return TRUE;
+        if (event->error_code == BadDrawable ||
+            event->error_code == BadGC ||
+            event->error_code == BadWindow)
+            return TRUE;
 #ifdef HAVE_X11_EXTENSIONS_XRENDER_H
         if (xrender_error_base)  /* check for XRender errors */
         {




More information about the wine-cvs mailing list