Alexandre Julliard : server: Allow setting a zero-size clip rectangle.

Alexandre Julliard julliard at winehq.org
Tue Jun 21 12:25:41 CDT 2011


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Jun 21 14:50:23 2011 +0200

server: Allow setting a zero-size clip rectangle.

---

 dlls/user32/cursoricon.c       |    6 +++++-
 dlls/user32/tests/monitor.c    |    8 ++++++++
 dlls/winex11.drv/mouse.c       |    2 +-
 include/wine/server_protocol.h |    3 ++-
 server/protocol.def            |    1 +
 server/queue.c                 |   20 +++++++++++++++-----
 6 files changed, 32 insertions(+), 8 deletions(-)

diff --git a/dlls/user32/cursoricon.c b/dlls/user32/cursoricon.c
index 014a4b9..4c7658d 100644
--- a/dlls/user32/cursoricon.c
+++ b/dlls/user32/cursoricon.c
@@ -1722,17 +1722,21 @@ BOOL WINAPI DECLSPEC_HOTPATCH ClipCursor( const RECT *rect )
 
     TRACE( "Clipping to %s\n", wine_dbgstr_rect(rect) );
 
+    if (rect && (rect->left > rect->right || rect->top > rect->bottom)) return FALSE;
+
     SERVER_START_REQ( set_cursor )
     {
-        req->flags    = SET_CURSOR_CLIP;
         req->clip_msg = WM_WINE_CLIPCURSOR;
         if (rect)
         {
+            req->flags       = SET_CURSOR_CLIP;
             req->clip.left   = rect->left;
             req->clip.top    = rect->top;
             req->clip.right  = rect->right;
             req->clip.bottom = rect->bottom;
         }
+        else req->flags = SET_CURSOR_NOCLIP;
+
         if ((ret = !wine_server_call( req )))
         {
             new_rect.left   = reply->new_clip.left;
diff --git a/dlls/user32/tests/monitor.c b/dlls/user32/tests/monitor.c
index daa3035..e31019f 100644
--- a/dlls/user32/tests/monitor.c
+++ b/dlls/user32/tests/monitor.c
@@ -267,6 +267,14 @@ static void test_ChangeDisplaySettingsEx(void)
             ok(ClipCursor(&r1), "ClipCursor() failed\n");
             ok(GetClipCursor(&r), "GetClipCursor() failed\n");
             ok(EqualRect(&r, &r1), "Invalid clip rect: (%d %d) x (%d %d)\n", r.left, r.top, r.right, r.bottom);
+            SetRect(&r1, 10, 10, 10, 10);
+            ok(ClipCursor(&r1), "ClipCursor() failed\n");
+            ok(GetClipCursor(&r), "GetClipCursor() failed\n");
+            ok(EqualRect(&r, &r1), "Invalid clip rect: (%d %d) x (%d %d)\n", r.left, r.top, r.right, r.bottom);
+            SetRect(&r1, 10, 10, 10, 9);
+            ok(!ClipCursor(&r1), "ClipCursor() succeeded\n");
+            /* Windows bug: further clipping fails once an empty rect is set, so we have to reset it */
+            ClipCursor(NULL);
 
             SetRect(&r1, virt.left - 10, virt.top - 10, virt.right + 20, virt.bottom + 20);
             ok(ClipCursor(&r1), "ClipCursor() failed\n");
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index 4a73acd..7f62658 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -417,7 +417,7 @@ static BOOL grab_clipping_window( const RECT *clip, BOOL only_with_xinput )
     if (msg_hwnd) XUnmapWindow( data->display, clip_window );
     XMoveResizeWindow( data->display, clip_window,
                        clip->left - virtual_screen_rect.left, clip->top - virtual_screen_rect.top,
-                       clip->right - clip->left, clip->bottom - clip->top );
+                       max( 1, clip->right - clip->left ), max( 1, clip->bottom - clip->top ) );
     XMapWindow( data->display, clip_window );
 
     /* if the rectangle is shrinking we may get a pointer warp */
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 5cb2467..ee438b4 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -4849,6 +4849,7 @@ struct set_cursor_reply
 #define SET_CURSOR_COUNT  0x02
 #define SET_CURSOR_POS    0x04
 #define SET_CURSOR_CLIP   0x08
+#define SET_CURSOR_NOCLIP 0x10
 
 
 
@@ -5634,6 +5635,6 @@ union generic_reply
     struct set_suspend_context_reply set_suspend_context_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 424
+#define SERVER_PROTOCOL_VERSION 425
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/protocol.def b/server/protocol.def
index 767be04..123f16a 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3351,6 +3351,7 @@ enum coords_relative
 #define SET_CURSOR_COUNT  0x02
 #define SET_CURSOR_POS    0x04
 #define SET_CURSOR_CLIP   0x08
+#define SET_CURSOR_NOCLIP 0x10
 
 
 /* Retrieve the suspended context of a thread */
diff --git a/server/queue.c b/server/queue.c
index ce773a1..6dee8f5 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -359,12 +359,22 @@ static void set_cursor_pos( struct desktop *desktop, int x, int y )
 /* set the cursor clip rectangle */
 static void set_clip_rectangle( struct desktop *desktop, const rectangle_t *rect )
 {
-    rectangle_t top_rect, new_rect;
+    rectangle_t top_rect;
     int x, y;
 
     get_top_window_rectangle( desktop, &top_rect );
-    if (!rect || !intersect_rect( &new_rect, &top_rect, rect )) new_rect = top_rect;
-    desktop->cursor.clip = new_rect;
+    if (rect)
+    {
+        rectangle_t new_rect = *rect;
+        if (new_rect.left   < top_rect.left)   new_rect.left   = top_rect.left;
+        if (new_rect.right  > top_rect.right)  new_rect.right  = top_rect.right;
+        if (new_rect.top    < top_rect.top)    new_rect.top    = top_rect.top;
+        if (new_rect.bottom > top_rect.bottom) new_rect.bottom = top_rect.bottom;
+        if (new_rect.left > new_rect.right || new_rect.top > new_rect.bottom) new_rect = top_rect;
+        desktop->cursor.clip = new_rect;
+    }
+    else desktop->cursor.clip = top_rect;
+
     if (desktop->cursor.clip_msg)
         post_desktop_message( desktop, desktop->cursor.clip_msg, rect != NULL, 0 );
 
@@ -2861,7 +2871,7 @@ DECL_HANDLER(set_cursor)
     {
         set_cursor_pos( input->desktop, req->x, req->y );
     }
-    if (req->flags & SET_CURSOR_CLIP)
+    if (req->flags & (SET_CURSOR_CLIP | SET_CURSOR_NOCLIP))
     {
         struct desktop *desktop = input->desktop;
 
@@ -2869,7 +2879,7 @@ DECL_HANDLER(set_cursor)
         if (req->clip_msg && get_top_window_owner(desktop) == current->process)
             desktop->cursor.clip_msg = req->clip_msg;
 
-        set_clip_rectangle( desktop, &req->clip );
+        set_clip_rectangle( desktop, (req->flags & SET_CURSOR_NOCLIP) ? NULL : &req->clip );
     }
 
     reply->new_x       = input->desktop->cursor.x;




More information about the wine-cvs mailing list