Module: wine Branch: master Commit: 6b0d9ff1cd6876f8181c95063b775d1cfe3a1d12 URL: http://source.winehq.org/git/wine.git/?a=commit;h=6b0d9ff1cd6876f8181c95063b...
Author: Alexandre Julliard julliard@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;