Module: wine Branch: master Commit: 0eb19126e5c0efe7e5e0cbd4811c19523601973a URL: http://source.winehq.org/git/wine.git/?a=commit;h=0eb19126e5c0efe7e5e0cbd481...
Author: Alexandre Julliard julliard@winehq.org Date: Fri Apr 22 16:22:09 2011 +0200
winex11: Store a message window with the desktop when the cursor is clipped.
This ensures that the thread can be notified when the clip rectangle is reset.
---
dlls/winex11.drv/event.c | 2 +- dlls/winex11.drv/mouse.c | 53 +++++++++++++++++++++++++++++++++++--------- dlls/winex11.drv/window.c | 2 + dlls/winex11.drv/x11drv.h | 5 ++- 4 files changed, 48 insertions(+), 14 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 75e7d8d..b338236 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -795,7 +795,7 @@ static void X11DRV_MapNotify( HWND hwnd, XEvent *event ) */ static void X11DRV_UnmapNotify( HWND hwnd, XEvent *event ) { - if (event->xany.window == x11drv_thread_data()->clip_window) clipping_window_unmapped(); + if (event->xany.window == x11drv_thread_data()->clip_window) clipping_cursor = 0; }
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index 2768d8e..4e622d7 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -348,25 +348,51 @@ static void disable_xinput2(void) }
/*********************************************************************** - * clipping_window_unmapped + * create_clipping_msg_window + */ +static HWND create_clipping_msg_window(void) +{ + static const WCHAR class_name[] = {'_','_','x','1','1','d','r','v','_','c','l','i','p','_','c','l','a','s','s',0}; + static ATOM clip_class; + + if (!clip_class) + { + WNDCLASSW class; + ATOM atom; + + memset( &class, 0, sizeof(class) ); + class.lpfnWndProc = DefWindowProcW; + class.hInstance = GetModuleHandleW(0); + class.lpszClassName = class_name; + if ((atom = RegisterClassW( &class ))) clip_class = atom; + } + return CreateWindowW( class_name, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, GetModuleHandleW(0), NULL ); +} + +/*********************************************************************** + * clip_cursor_notify * - * Turn off clipping when the window got unmapped. + * Notification function called upon receiving a WM_X11DRV_CLIP_CURSOR. */ -void clipping_window_unmapped(void) +LRESULT clip_cursor_notify( HWND hwnd, HWND new_clip_hwnd ) { - struct x11drv_thread_data *data = x11drv_thread_data(); + if (hwnd == GetDesktopWindow()) /* change the clip window stored in the desktop process */ + { + static HWND clip_hwnd;
- clipping_cursor = 0; - if (data->xi2_state == xi_enabled) + HWND prev = clip_hwnd; + clip_hwnd = new_clip_hwnd; + if (prev || new_clip_hwnd) TRACE( "clip hwnd changed from %p to %p\n", prev, new_clip_hwnd ); + if (prev) SendNotifyMessageW( prev, WM_X11DRV_CLIP_CURSOR, 0, 0 ); + } + else /* this is a notification that clipping has been reset */ { - RECT rect; - GetClipCursor( &rect ); - if (EqualRect( &rect, &clip_rect )) return; /* still clipped */ disable_xinput2(); + DestroyWindow( hwnd ); } + return 0; }
- /*********************************************************************** * send_mouse_input * @@ -1100,6 +1126,9 @@ BOOL CDECL X11DRV_ClipCursor( LPCRECT clip )
if (grab_pointer) { + HWND msg_hwnd = create_clipping_msg_window(); + + if (!msg_hwnd) return TRUE; TRACE( "clipping to %s\n", wine_dbgstr_rect(clip) ); wine_tsx11_lock(); XUnmapWindow( display, clip_window ); @@ -1118,8 +1147,10 @@ BOOL CDECL X11DRV_ClipCursor( LPCRECT clip ) enable_xinput2(); sync_window_cursor( clip_window ); clip_rect = *clip; + SendMessageW( GetDesktopWindow(), WM_X11DRV_CLIP_CURSOR, 0, (LPARAM)msg_hwnd ); return TRUE; } + DestroyWindow( msg_hwnd ); } }
@@ -1129,7 +1160,7 @@ BOOL CDECL X11DRV_ClipCursor( LPCRECT clip ) XUnmapWindow( display, clip_window ); wine_tsx11_unlock(); clipping_cursor = 0; - disable_xinput2(); + SendMessageW( GetDesktopWindow(), WM_X11DRV_CLIP_CURSOR, 0, 0 ); return TRUE; }
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 0a25afb..ba544cd 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -2719,6 +2719,8 @@ LRESULT CDECL X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) if ((data = X11DRV_get_win_data( hwnd )) && data->whole_window) set_window_cursor( data->whole_window, (HCURSOR)lp ); return 0; + case WM_X11DRV_CLIP_CURSOR: + return clip_cursor_notify( hwnd, (HWND)lp ); default: FIXME( "got window msg %x hwnd %p wp %lx lp %lx\n", msg, hwnd, wp, lp ); return 0; diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index cbc563b..2187d72 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -744,7 +744,8 @@ enum x11drv_window_messages WM_X11DRV_SET_WIN_FORMAT, WM_X11DRV_SET_WIN_REGION, WM_X11DRV_RESIZE_DESKTOP, - WM_X11DRV_SET_CURSOR + WM_X11DRV_SET_CURSOR, + WM_X11DRV_CLIP_CURSOR };
/* _NET_WM_STATE properties that we keep track of */ @@ -826,7 +827,7 @@ extern void X11DRV_ResetSelectionOwner(void); extern void CDECL X11DRV_SetFocus( HWND hwnd ); extern void set_window_cursor( Window window, HCURSOR handle ); extern void sync_window_cursor( Window window ); -extern void clipping_window_unmapped(void); +extern LRESULT clip_cursor_notify( HWND hwnd, HWND new_clip_hwnd ); extern BOOL CDECL X11DRV_ClipCursor( LPCRECT clip ); extern void X11DRV_InitKeyboard( Display *display ); extern DWORD CDECL X11DRV_MsgWaitForMultipleObjectsEx( DWORD count, const HANDLE *handles, DWORD timeout,