From eed9c63ac7650293523da5c8d067c74258568ba8 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 20 Apr 2010 20:52:17 +0200 Subject: [PATCH] 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 c140ca3aa5d..152763bca0d 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 1621861bd8c..bf71cadd6c1 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 12ec2868b0c..cffb4ee4627 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 240e4d95876..fbe61849600 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 */ {