From 21e86f60ec44bbb61c87b97abb6fa7a9843e42b2 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 31 Mar 2011 20:27:29 +0200 Subject: [PATCH] server: Post a message to the desktop window when the cursor clip rectangle changes. --- dlls/user32/cursoricon.c | 3 ++- dlls/user32/message.c | 6 ++++++ dlls/user32/user_private.h | 1 + dlls/winex11.drv/xinerama.c | 1 - include/wine/server_protocol.h | 4 +++- programs/explorer/desktop.c | 1 + server/protocol.def | 1 + server/queue.c | 25 ++++++++++++++++++++----- server/request.h | 3 ++- server/trace.c | 1 + server/user.h | 1 + 11 files changed, 38 insertions(+), 9 deletions(-) diff --git a/dlls/user32/cursoricon.c b/dlls/user32/cursoricon.c index 7a9c78add1a..476aa51b58a 100644 --- a/dlls/user32/cursoricon.c +++ b/dlls/user32/cursoricon.c @@ -1717,7 +1717,8 @@ BOOL WINAPI DECLSPEC_HOTPATCH ClipCursor( const RECT *rect ) SERVER_START_REQ( set_cursor ) { - req->flags = SET_CURSOR_CLIP; + req->flags = SET_CURSOR_CLIP; + req->clip_msg = WM_WINE_CLIPCURSOR; if (rect) { req->clip.left = rect->left; diff --git a/dlls/user32/message.c b/dlls/user32/message.c index 59f2e49799c..51691ab15c6 100644 --- a/dlls/user32/message.c +++ b/dlls/user32/message.c @@ -1869,6 +1869,12 @@ static LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPAR return call_current_hook( h_extra->handle, HC_ACTION, wparam, h_extra->lparam ); } + case WM_WINE_CLIPCURSOR: + { + RECT rect; + GetClipCursor( &rect ); + return USER_Driver->pClipCursor( &rect ); + } default: if (msg >= WM_WINE_FIRST_DRIVER_MSG && msg <= WM_WINE_LAST_DRIVER_MSG) return USER_Driver->pWindowMessage( hwnd, msg, wparam, lparam ); diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index 6d668ba7e75..bd7d39e5d29 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -47,6 +47,7 @@ enum wine_internal_message WM_WINE_SETACTIVEWINDOW, WM_WINE_KEYBOARD_LL_HOOK, WM_WINE_MOUSE_LL_HOOK, + WM_WINE_CLIPCURSOR, WM_WINE_FIRST_DRIVER_MSG = 0x80001000, /* range of messages reserved for the USER driver */ WM_WINE_LAST_DRIVER_MSG = 0x80001fff }; diff --git a/dlls/winex11.drv/xinerama.c b/dlls/winex11.drv/xinerama.c index 2a66df59bcd..b2014ed7500 100644 --- a/dlls/winex11.drv/xinerama.c +++ b/dlls/winex11.drv/xinerama.c @@ -197,7 +197,6 @@ void xinerama_init( unsigned int width, unsigned int height ) wine_dbgstr_rect(&rect), screen_width, screen_height ); wine_tsx11_unlock(); - ClipCursor( NULL ); /* reset the cursor clip rectangle */ } diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 70e539be8d7..d321a80abed 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -4798,6 +4798,8 @@ struct set_cursor_request int x; int y; rectangle_t clip; + unsigned int clip_msg; + char __pad_52[4]; }; struct set_cursor_reply { @@ -5561,6 +5563,6 @@ union generic_reply struct set_cursor_reply set_cursor_reply; }; -#define SERVER_PROTOCOL_VERSION 418 +#define SERVER_PROTOCOL_VERSION 419 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/programs/explorer/desktop.c b/programs/explorer/desktop.c index 78ff3890922..b2f77304984 100644 --- a/programs/explorer/desktop.c +++ b/programs/explorer/desktop.c @@ -334,6 +334,7 @@ void manage_desktop( WCHAR *arg ) if (name) set_desktop_window_title( hwnd, name ); SystemParametersInfoA( SPI_SETDESKPATTERN, -1, NULL, FALSE ); SetDeskWallPaper( (LPSTR)-1 ); + ClipCursor( NULL ); initialize_display_settings( hwnd ); initialize_appbar(); initialize_systray( using_root ); diff --git a/server/protocol.def b/server/protocol.def index f8fc82b1494..8aaf2d3ff20 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -3318,6 +3318,7 @@ enum coords_relative int x; /* cursor position */ int y; rectangle_t clip; /* cursor clip rectangle */ + unsigned int clip_msg; /* message to post on cursor clip changes */ @REPLY user_handle_t prev_handle; /* previous handle */ int prev_count; /* previous show count */ diff --git a/server/queue.c b/server/queue.c index 35448e5c033..14086ebec28 100644 --- a/server/queue.c +++ b/server/queue.c @@ -318,11 +318,23 @@ static int assign_thread_input( struct thread *thread, struct thread_input *new_ return 1; } +/* set the cursor clip rectangle */ +static void set_clip_rectangle( struct desktop *desktop, const rectangle_t *rect ) +{ + rectangle_t top_rect, new_rect; + + get_top_window_rectangle( desktop, &top_rect ); + if (!rect || !intersect_rect( &new_rect, &top_rect, rect )) new_rect = top_rect; + if (!memcmp( &desktop->cursor.clip, &new_rect, sizeof(new_rect) )) return; + desktop->cursor.clip = new_rect; + if (desktop->cursor.clip_msg) post_desktop_message( desktop, desktop->cursor.clip_msg, 0, 0 ); +} + /* change the foreground input and reset the cursor clip rect */ static void set_foreground_input( struct desktop *desktop, struct thread_input *input ) { if (desktop->foreground_input == input) return; - get_top_window_rectangle( desktop, &desktop->cursor.clip ); + set_clip_rectangle( desktop, NULL ); desktop->foreground_input = input; } @@ -2620,10 +2632,13 @@ DECL_HANDLER(set_cursor) } if (req->flags & SET_CURSOR_CLIP) { - rectangle_t top_rect; - get_top_window_rectangle( input->desktop, &top_rect ); - if (!intersect_rect( &input->desktop->cursor.clip, &top_rect, &req->clip )) - input->desktop->cursor.clip = top_rect; + struct desktop *desktop = input->desktop; + + /* only the desktop owner can set the message */ + if (req->clip_msg && get_top_window_owner(desktop) == current->process) + desktop->cursor.clip_msg = req->clip_msg; + + set_clip_rectangle( desktop, &req->clip ); } reply->new_x = input->desktop->cursor.x; diff --git a/server/request.h b/server/request.h index c2104e93d30..0133af7ad5d 100644 --- a/server/request.h +++ b/server/request.h @@ -2097,7 +2097,8 @@ C_ASSERT( FIELD_OFFSET(struct set_cursor_request, show_count) == 20 ); C_ASSERT( FIELD_OFFSET(struct set_cursor_request, x) == 24 ); C_ASSERT( FIELD_OFFSET(struct set_cursor_request, y) == 28 ); C_ASSERT( FIELD_OFFSET(struct set_cursor_request, clip) == 32 ); -C_ASSERT( sizeof(struct set_cursor_request) == 48 ); +C_ASSERT( FIELD_OFFSET(struct set_cursor_request, clip_msg) == 48 ); +C_ASSERT( sizeof(struct set_cursor_request) == 56 ); C_ASSERT( FIELD_OFFSET(struct set_cursor_reply, prev_handle) == 8 ); C_ASSERT( FIELD_OFFSET(struct set_cursor_reply, prev_count) == 12 ); C_ASSERT( FIELD_OFFSET(struct set_cursor_reply, new_x) == 16 ); diff --git a/server/trace.c b/server/trace.c index 553ba4d1ceb..06fe545c55a 100644 --- a/server/trace.c +++ b/server/trace.c @@ -3896,6 +3896,7 @@ static void dump_set_cursor_request( const struct set_cursor_request *req ) fprintf( stderr, ", x=%d", req->x ); fprintf( stderr, ", y=%d", req->y ); dump_rectangle( ", clip=", &req->clip ); + fprintf( stderr, ", clip_msg=%08x", req->clip_msg ); } static void dump_set_cursor_reply( const struct set_cursor_reply *req ) diff --git a/server/user.h b/server/user.h index 2a3f36985cf..9b86031601e 100644 --- a/server/user.h +++ b/server/user.h @@ -56,6 +56,7 @@ struct global_cursor int x; /* cursor position */ int y; rectangle_t clip; /* cursor clip rectangle */ + unsigned int clip_msg; /* message to post for cursor clip changes */ unsigned int last_change; /* time of last position change */ };