Commit 6b0d9ff1 authored by Alexandre Julliard's avatar Alexandre Julliard

server: Allow setting a zero-size clip rectangle.

parent b3946a0a
...@@ -1722,17 +1722,21 @@ BOOL WINAPI DECLSPEC_HOTPATCH ClipCursor( const RECT *rect ) ...@@ -1722,17 +1722,21 @@ BOOL WINAPI DECLSPEC_HOTPATCH ClipCursor( const RECT *rect )
TRACE( "Clipping to %s\n", wine_dbgstr_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 ) SERVER_START_REQ( set_cursor )
{ {
req->flags = SET_CURSOR_CLIP;
req->clip_msg = WM_WINE_CLIPCURSOR; req->clip_msg = WM_WINE_CLIPCURSOR;
if (rect) if (rect)
{ {
req->flags = SET_CURSOR_CLIP;
req->clip.left = rect->left; req->clip.left = rect->left;
req->clip.top = rect->top; req->clip.top = rect->top;
req->clip.right = rect->right; req->clip.right = rect->right;
req->clip.bottom = rect->bottom; req->clip.bottom = rect->bottom;
} }
else req->flags = SET_CURSOR_NOCLIP;
if ((ret = !wine_server_call( req ))) if ((ret = !wine_server_call( req )))
{ {
new_rect.left = reply->new_clip.left; new_rect.left = reply->new_clip.left;
......
...@@ -267,6 +267,14 @@ static void test_ChangeDisplaySettingsEx(void) ...@@ -267,6 +267,14 @@ static void test_ChangeDisplaySettingsEx(void)
ok(ClipCursor(&r1), "ClipCursor() failed\n"); ok(ClipCursor(&r1), "ClipCursor() failed\n");
ok(GetClipCursor(&r), "GetClipCursor() 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); 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); SetRect(&r1, virt.left - 10, virt.top - 10, virt.right + 20, virt.bottom + 20);
ok(ClipCursor(&r1), "ClipCursor() failed\n"); ok(ClipCursor(&r1), "ClipCursor() failed\n");
......
...@@ -417,7 +417,7 @@ static BOOL grab_clipping_window( const RECT *clip, BOOL only_with_xinput ) ...@@ -417,7 +417,7 @@ static BOOL grab_clipping_window( const RECT *clip, BOOL only_with_xinput )
if (msg_hwnd) XUnmapWindow( data->display, clip_window ); if (msg_hwnd) XUnmapWindow( data->display, clip_window );
XMoveResizeWindow( data->display, clip_window, XMoveResizeWindow( data->display, clip_window,
clip->left - virtual_screen_rect.left, clip->top - virtual_screen_rect.top, 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 ); XMapWindow( data->display, clip_window );
/* if the rectangle is shrinking we may get a pointer warp */ /* if the rectangle is shrinking we may get a pointer warp */
......
...@@ -4849,6 +4849,7 @@ struct set_cursor_reply ...@@ -4849,6 +4849,7 @@ struct set_cursor_reply
#define SET_CURSOR_COUNT 0x02 #define SET_CURSOR_COUNT 0x02
#define SET_CURSOR_POS 0x04 #define SET_CURSOR_POS 0x04
#define SET_CURSOR_CLIP 0x08 #define SET_CURSOR_CLIP 0x08
#define SET_CURSOR_NOCLIP 0x10
...@@ -5634,6 +5635,6 @@ union generic_reply ...@@ -5634,6 +5635,6 @@ union generic_reply
struct set_suspend_context_reply set_suspend_context_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 */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
...@@ -3351,6 +3351,7 @@ enum coords_relative ...@@ -3351,6 +3351,7 @@ enum coords_relative
#define SET_CURSOR_COUNT 0x02 #define SET_CURSOR_COUNT 0x02
#define SET_CURSOR_POS 0x04 #define SET_CURSOR_POS 0x04
#define SET_CURSOR_CLIP 0x08 #define SET_CURSOR_CLIP 0x08
#define SET_CURSOR_NOCLIP 0x10
/* Retrieve the suspended context of a thread */ /* Retrieve the suspended context of a thread */
......
...@@ -359,12 +359,22 @@ static void set_cursor_pos( struct desktop *desktop, int x, int y ) ...@@ -359,12 +359,22 @@ static void set_cursor_pos( struct desktop *desktop, int x, int y )
/* set the cursor clip rectangle */ /* set the cursor clip rectangle */
static void set_clip_rectangle( struct desktop *desktop, const rectangle_t *rect ) 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; int x, y;
get_top_window_rectangle( desktop, &top_rect ); get_top_window_rectangle( desktop, &top_rect );
if (!rect || !intersect_rect( &new_rect, &top_rect, rect )) new_rect = top_rect; if (rect)
desktop->cursor.clip = new_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) if (desktop->cursor.clip_msg)
post_desktop_message( desktop, desktop->cursor.clip_msg, rect != NULL, 0 ); post_desktop_message( desktop, desktop->cursor.clip_msg, rect != NULL, 0 );
...@@ -2861,7 +2871,7 @@ DECL_HANDLER(set_cursor) ...@@ -2861,7 +2871,7 @@ DECL_HANDLER(set_cursor)
{ {
set_cursor_pos( input->desktop, req->x, req->y ); 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; struct desktop *desktop = input->desktop;
...@@ -2869,7 +2879,7 @@ DECL_HANDLER(set_cursor) ...@@ -2869,7 +2879,7 @@ DECL_HANDLER(set_cursor)
if (req->clip_msg && get_top_window_owner(desktop) == current->process) if (req->clip_msg && get_top_window_owner(desktop) == current->process)
desktop->cursor.clip_msg = req->clip_msg; 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; reply->new_x = input->desktop->cursor.x;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment