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