Alexandre Julliard : winex11: Store a message window with the desktop when the cursor is clipped.
Alexandre Julliard
julliard at winehq.org
Fri Apr 22 12:27:43 CDT 2011
Module: wine
Branch: master
Commit: 0eb19126e5c0efe7e5e0cbd4811c19523601973a
URL: http://source.winehq.org/git/wine.git/?a=commit;h=0eb19126e5c0efe7e5e0cbd4811c19523601973a
Author: Alexandre Julliard <julliard at 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,
More information about the wine-cvs
mailing list