server: Introduce and send new WM_WINE_SETCURSOR hardware message.

This commit is contained in:
Rémi Bernon 2023-06-10 12:52:01 +02:00 committed by Alexandre Julliard
parent b04ef19930
commit 25906eedd8
5 changed files with 60 additions and 22 deletions

View file

@ -74,6 +74,12 @@ static struct cursoricon_object *get_icon_ptr( HICON handle )
return obj;
}
BOOL process_wine_setcursor( HWND hwnd, HWND window, HCURSOR handle )
{
TRACE( "hwnd %p, window %p, hcursor %p\n", hwnd, window, handle );
return TRUE;
}
/***********************************************************************
* NtUserShowCursor (win32u.@)
*/

View file

@ -1274,6 +1274,9 @@ static LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPAR
case WM_WINE_CLIPCURSOR:
if (wparam && lparam) return clip_fullscreen_window( hwnd, FALSE );
return process_wine_clipcursor( hwnd, wparam, lparam );
case WM_WINE_SETCURSOR:
FIXME( "Unexpected non-hardware WM_WINE_SETCURSOR message\n" );
return FALSE;
case WM_WINE_UPDATEWINDOWSTATE:
update_window_state( hwnd );
return 0;
@ -1769,6 +1772,8 @@ static BOOL process_hardware_message( MSG *msg, UINT hw_id, const struct hardwar
ret = process_mouse_message( msg, hw_id, msg_data->info, hwnd_filter, first, last, remove );
else if (msg->message == WM_WINE_CLIPCURSOR)
process_wine_clipcursor( msg->hwnd, msg->wParam, msg->lParam );
else if (msg->message == WM_WINE_SETCURSOR)
process_wine_setcursor( msg->hwnd, (HWND)msg->wParam, (HCURSOR)msg->lParam );
else
ERR( "unknown message type %x\n", msg->message );
SetThreadDpiAwarenessContext( context );

View file

@ -38,6 +38,7 @@ extern UINT enum_clipboard_formats( UINT format ) DECLSPEC_HIDDEN;
extern void release_clipboard_owner( HWND hwnd ) DECLSPEC_HIDDEN;
/* cursoricon.c */
extern BOOL process_wine_setcursor( HWND hwnd, HWND window, HCURSOR handle ) DECLSPEC_HIDDEN;
extern HICON alloc_cursoricon_handle( BOOL is_icon ) DECLSPEC_HIDDEN;
extern ULONG_PTR get_icon_param( HICON handle ) DECLSPEC_HIDDEN;
extern ULONG_PTR set_icon_param( HICON handle, ULONG_PTR param ) DECLSPEC_HIDDEN;

View file

@ -483,6 +483,7 @@ enum wine_internal_message
WM_WINE_KEYBOARD_LL_HOOK,
WM_WINE_MOUSE_LL_HOOK,
WM_WINE_CLIPCURSOR,
WM_WINE_SETCURSOR,
WM_WINE_UPDATEWINDOWSTATE,
WM_WINE_FIRST_DRIVER_MSG = 0x80001000, /* range of messages reserved for the USER driver */
WM_WINE_LAST_DRIVER_MSG = 0x80001fff

View file

@ -404,10 +404,42 @@ static struct message *alloc_hardware_message( lparam_t info, struct hw_msg_sour
return msg;
}
static int is_cursor_clipped( struct desktop *desktop )
{
rectangle_t top_rect, clip_rect = desktop->cursor.clip;
get_top_window_rectangle( desktop, &top_rect );
return !is_rect_equal( &clip_rect, &top_rect );
}
static void queue_cursor_message( struct desktop *desktop, user_handle_t win, unsigned int message,
lparam_t wparam, lparam_t lparam )
{
static const struct hw_msg_source source = { IMDT_UNAVAILABLE, IMO_SYSTEM };
struct thread_input *input;
struct message *msg;
if (!(msg = alloc_hardware_message( 0, source, get_tick_count(), 0 ))) return;
msg->msg = message;
msg->wparam = wparam;
msg->lparam = lparam;
msg->x = desktop->cursor.x;
msg->y = desktop->cursor.y;
if (!(msg->win = win) && (input = desktop->foreground_input)) msg->win = input->active;
queue_hardware_message( desktop, msg, 1 );
}
static int update_desktop_cursor_window( struct desktop *desktop, user_handle_t win )
{
int updated = win != desktop->cursor.win;
user_handle_t handle = desktop->cursor.handle;
desktop->cursor.win = win;
if (updated)
{
/* when clipping send the message to the foreground window as well, as some driver have an artificial overlay window */
if (is_cursor_clipped( desktop )) queue_cursor_message( desktop, 0, WM_WINE_SETCURSOR, win, handle );
queue_cursor_message( desktop, win, WM_WINE_SETCURSOR, win, handle );
}
return updated;
}
@ -433,7 +465,15 @@ static int update_desktop_cursor_pos( struct desktop *desktop, user_handle_t win
static void update_desktop_cursor_handle( struct desktop *desktop, user_handle_t handle )
{
int updated = desktop->cursor.handle != handle;
user_handle_t win = desktop->cursor.win;
desktop->cursor.handle = handle;
if (updated)
{
/* when clipping send the message to the foreground window as well, as some driver have an artificial overlay window */
if (is_cursor_clipped( desktop )) queue_cursor_message( desktop, 0, WM_WINE_SETCURSOR, win, handle );
queue_cursor_message( desktop, win, WM_WINE_SETCURSOR, win, handle );
}
}
/* set the cursor position and queue the corresponding mouse message */
@ -467,23 +507,6 @@ static void get_message_defaults( struct msg_queue *queue, int *x, int *y, unsig
*time = get_tick_count();
}
static void queue_clip_cursor_msg( struct desktop *desktop, lparam_t wparam, lparam_t lparam )
{
static const struct hw_msg_source source = { IMDT_UNAVAILABLE, IMO_SYSTEM };
struct thread_input *input;
struct message *msg;
if (!(msg = alloc_hardware_message( 0, source, get_tick_count(), 0 ))) return;
msg->msg = WM_WINE_CLIPCURSOR;
msg->wparam = wparam;
msg->lparam = lparam;
msg->x = desktop->cursor.x;
msg->y = desktop->cursor.y;
if ((input = desktop->foreground_input)) msg->win = input->active;
queue_hardware_message( desktop, msg, 1 );
}
/* set the cursor clip rectangle */
void set_clip_rectangle( struct desktop *desktop, const rectangle_t *rect, int reset )
{
@ -512,7 +535,7 @@ void set_clip_rectangle( struct desktop *desktop, const rectangle_t *rect, int r
if (reset) post_desktop_message( desktop, WM_WINE_CLIPCURSOR, TRUE, FALSE );
/* notify foreground thread, of reset, or to apply new cursor clipping rect */
queue_clip_cursor_msg( desktop, rect == NULL, reset );
queue_cursor_message( desktop, 0, WM_WINE_CLIPCURSOR, rect == NULL, reset );
}
/* change the foreground input and reset the cursor clip rect */
@ -598,6 +621,7 @@ static inline int get_hardware_msg_bit( unsigned int message )
if (message == WM_MOUSEMOVE || message == WM_NCMOUSEMOVE) return QS_MOUSEMOVE;
if (message >= WM_KEYFIRST && message <= WM_KEYLAST) return QS_KEY;
if (message == WM_WINE_CLIPCURSOR) return QS_RAWINPUT;
if (message == WM_WINE_SETCURSOR) return QS_RAWINPUT;
return QS_MOUSEBUTTON;
}
@ -650,13 +674,13 @@ static int merge_mousemove( struct thread_input *input, const struct message *ms
return 1;
}
/* try to merge a WM_WINE_CLIPCURSOR message with the last in the list; return 1 if successful */
static int merge_wine_clipcursor( struct thread_input *input, const struct message *msg )
/* try to merge a unique message with the last in the list; return 1 if successful */
static int merge_unique_message( struct thread_input *input, unsigned int message, const struct message *msg )
{
struct message *prev;
LIST_FOR_EACH_ENTRY_REV( prev, &input->msg_list, struct message, entry )
if (prev->msg == WM_WINE_CLIPCURSOR) break;
if (prev->msg == message) break;
if (&prev->entry == &input->msg_list) return 0;
if (prev->result) return 0;
@ -679,7 +703,8 @@ static int merge_wine_clipcursor( struct thread_input *input, const struct messa
static int merge_message( struct thread_input *input, const struct message *msg )
{
if (msg->msg == WM_MOUSEMOVE) return merge_mousemove( input, msg );
if (msg->msg == WM_WINE_CLIPCURSOR) return merge_wine_clipcursor( input, msg );
if (msg->msg == WM_WINE_CLIPCURSOR) return merge_unique_message( input, WM_WINE_CLIPCURSOR, msg );
if (msg->msg == WM_WINE_SETCURSOR) return merge_unique_message( input, WM_WINE_SETCURSOR, msg );
return 0;
}