Instead of synchronizing the cursor in winex11 whenever the mouse moves.
From: Rémi Bernon rbernon@codeweavers.com
--- server/queue.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-)
diff --git a/server/queue.c b/server/queue.c index 57067dd6f51..74462ebedee 100644 --- a/server/queue.c +++ b/server/queue.c @@ -404,8 +404,16 @@ static struct message *alloc_hardware_message( lparam_t info, struct hw_msg_sour return msg; }
-static int update_desktop_cursor_pos( struct desktop *desktop, int x, int y ) +static int update_desktop_cursor_window( struct desktop *desktop, user_handle_t win ) { + int updated = win != desktop->cursor.win; + desktop->cursor.win = win; + return updated; +} + +static int update_desktop_cursor_pos( struct desktop *desktop, user_handle_t win, int x, int y ) +{ + struct thread_input *input; int updated;
x = max( min( x, desktop->cursor.clip.right - 1 ), desktop->cursor.clip.left ); @@ -415,6 +423,11 @@ static int update_desktop_cursor_pos( struct desktop *desktop, int x, int y ) desktop->cursor.y = y; desktop->cursor.last_change = get_tick_count();
+ if (!win && (input = desktop->foreground_input)) win = input->capture; + if (!win || !is_window_visible( win ) || is_window_transparent( win )) + win = shallow_window_from_point( desktop, x, y ); + if (update_desktop_cursor_window( desktop, win )) updated = 1; + return updated; }
@@ -427,7 +440,7 @@ static void set_cursor_pos( struct desktop *desktop, int x, int y )
if ((device = current->process->rawinput_mouse) && (device->flags & RIDEV_NOLEGACY)) { - update_desktop_cursor_pos( desktop, x, y ); + update_desktop_cursor_pos( desktop, 0, x, y ); return; }
@@ -1457,11 +1470,8 @@ static void update_input_key_state( struct desktop *desktop, unsigned char *keys }
/* update the desktop key state according to a mouse message flags */ -static void update_desktop_mouse_state( struct desktop *desktop, unsigned int flags, - int x, int y, lparam_t wparam ) +static void update_desktop_mouse_state( struct desktop *desktop, unsigned int flags, lparam_t wparam ) { - if (flags & MOUSEEVENTF_MOVE) - update_desktop_cursor_pos( desktop, x, y ); if (flags & MOUSEEVENTF_LEFTDOWN) update_input_key_state( desktop, desktop->keystate, WM_LBUTTONDOWN, wparam ); if (flags & MOUSEEVENTF_LEFTUP) @@ -1630,7 +1640,7 @@ static void queue_hardware_message( struct desktop *desktop, struct message *msg break; case QS_MOUSEMOVE: prepend_cursor_history( msg->x, msg->y, msg->time, msg_data->info ); - if (update_desktop_cursor_pos( desktop, msg->x, msg->y )) always_queue = 1; + if (update_desktop_cursor_pos( desktop, msg->win, msg->x, msg->y )) always_queue = 1; /* fallthrough */ case QS_MOUSEBUTTON: if (desktop->keystate[VK_LBUTTON] & 0x80) msg->wparam |= MK_LBUTTON; @@ -1661,9 +1671,6 @@ static void queue_hardware_message( struct desktop *desktop, struct message *msg } input = thread->queue->input;
- if (win != desktop->cursor.win) always_queue = 1; - desktop->cursor.win = win; - if (!always_queue || merge_message( input, msg )) free_message( msg ); else { @@ -1887,7 +1894,8 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons
if ((device = current->process->rawinput_mouse) && (device->flags & RIDEV_NOLEGACY)) { - update_desktop_mouse_state( desktop, flags, x, y, input->mouse.data << 16 ); + if (flags & MOUSEEVENTF_MOVE) update_desktop_cursor_pos( desktop, win, x, y ); + update_desktop_mouse_state( desktop, flags, input->mouse.data << 16 ); return 0; }
From: Rémi Bernon rbernon@codeweavers.com
--- server/queue.c | 11 +++++++++++ server/user.h | 1 + 2 files changed, 12 insertions(+)
diff --git a/server/queue.c b/server/queue.c index 74462ebedee..7428685f94f 100644 --- a/server/queue.c +++ b/server/queue.c @@ -431,6 +431,11 @@ static int update_desktop_cursor_pos( struct desktop *desktop, user_handle_t win return updated; }
+static void update_desktop_cursor_handle( struct desktop *desktop, user_handle_t handle ) +{ + desktop->cursor.handle = handle; +} + /* set the cursor position and queue the corresponding mouse message */ static void set_cursor_pos( struct desktop *desktop, int x, int y ) { @@ -3356,6 +3361,12 @@ DECL_HANDLER(set_cursor) if (req->flags & SET_CURSOR_CLIP) set_clip_rectangle( desktop, &req->clip, 0 ); if (req->flags & SET_CURSOR_NOCLIP) set_clip_rectangle( desktop, NULL, 0 );
+ if (req->flags & (SET_CURSOR_HANDLE | SET_CURSOR_COUNT)) + { + if (input->cursor_count < 0) update_desktop_cursor_handle( desktop, 0 ); + else update_desktop_cursor_handle( desktop, input->cursor ); + } + reply->new_x = desktop->cursor.x; reply->new_y = desktop->cursor.y; reply->new_clip = desktop->cursor.clip; diff --git a/server/user.h b/server/user.h index a18c94ec89d..f67e710938f 100644 --- a/server/user.h +++ b/server/user.h @@ -59,6 +59,7 @@ struct global_cursor rectangle_t clip; /* cursor clip rectangle */ unsigned int last_change; /* time of last position change */ user_handle_t win; /* window that contains the cursor */ + user_handle_t handle; /* last set cursor handle */ };
struct desktop
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/cursoricon.c | 6 ++++ dlls/win32u/message.c | 5 +++ dlls/win32u/win32u_private.h | 1 + include/ntuser.h | 1 + server/queue.c | 69 ++++++++++++++++++++++++------------ 5 files changed, 60 insertions(+), 22 deletions(-)
diff --git a/dlls/win32u/cursoricon.c b/dlls/win32u/cursoricon.c index ae9dc6f6b8b..409f1346ca0 100644 --- a/dlls/win32u/cursoricon.c +++ b/dlls/win32u/cursoricon.c @@ -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.@) */ diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index e10350fcd3b..cb44e0037d9 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -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 ); diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 44baf546182..3bd41a4ffa8 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -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; diff --git a/include/ntuser.h b/include/ntuser.h index 13c0147f9a4..31317026cd8 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -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 diff --git a/server/queue.c b/server/queue.c index 7428685f94f..ec8ddcbee5c 100644 --- a/server/queue.c +++ b/server/queue.c @@ -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; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/cursoricon.c | 6 +++--- dlls/win32u/driver.c | 6 +++--- dlls/wineandroid.drv/android.h | 3 +-- dlls/wineandroid.drv/window.c | 2 +- dlls/winemac.drv/macdrv.h | 2 +- dlls/winemac.drv/mouse.c | 4 ++-- dlls/winex11.drv/mouse.c | 2 +- dlls/winex11.drv/x11drv.h | 2 +- include/wine/gdi_driver.h | 2 +- 9 files changed, 14 insertions(+), 15 deletions(-)
diff --git a/dlls/win32u/cursoricon.c b/dlls/win32u/cursoricon.c index 409f1346ca0..23bb4354c2a 100644 --- a/dlls/win32u/cursoricon.c +++ b/dlls/win32u/cursoricon.c @@ -101,8 +101,8 @@ INT WINAPI NtUserShowCursor( BOOL show )
TRACE("%d, count=%d\n", show, count );
- if (show && !count) user_driver->pSetCursor( cursor ); - else if (!show && count == -1) user_driver->pSetCursor( 0 ); + if (show && !count) user_driver->pSetCursor( 0, cursor ); + else if (!show && count == -1) user_driver->pSetCursor( 0, 0 );
return count; } @@ -132,7 +132,7 @@ HCURSOR WINAPI NtUserSetCursor( HCURSOR cursor ) SERVER_END_REQ; if (!ret) return 0;
- user_driver->pSetCursor( show_count >= 0 ? cursor : 0 ); + user_driver->pSetCursor( 0, show_count >= 0 ? cursor : 0 );
if (!(obj = get_icon_ptr( old_cursor ))) return 0; release_user_handle_ptr( obj ); diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index 26bdbe7baf6..ed2e0973d39 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -738,7 +738,7 @@ static void nulldrv_DestroyCursorIcon( HCURSOR cursor ) { }
-static void nulldrv_SetCursor( HCURSOR cursor ) +static void nulldrv_SetCursor( HWND hwnd, HCURSOR cursor ) { }
@@ -1118,9 +1118,9 @@ static INT loaderdrv_GetDisplayDepth( LPCWSTR name, BOOL is_primary ) return load_driver()->pGetDisplayDepth( name, is_primary ); }
-static void loaderdrv_SetCursor( HCURSOR cursor ) +static void loaderdrv_SetCursor( HWND hwnd, HCURSOR cursor ) { - load_driver()->pSetCursor( cursor ); + load_driver()->pSetCursor( hwnd, cursor ); }
static BOOL loaderdrv_GetCursorPos( POINT *pt ) diff --git a/dlls/wineandroid.drv/android.h b/dlls/wineandroid.drv/android.h index d12cfa28f04..2eb6a288a72 100644 --- a/dlls/wineandroid.drv/android.h +++ b/dlls/wineandroid.drv/android.h @@ -86,13 +86,12 @@ extern pthread_mutex_t win_data_mutex DECLSPEC_HIDDEN; extern INT ANDROID_GetKeyNameText( LONG lparam, LPWSTR buffer, INT size ) DECLSPEC_HIDDEN; extern UINT ANDROID_MapVirtualKeyEx( UINT code, UINT maptype, HKL hkl ) DECLSPEC_HIDDEN; extern SHORT ANDROID_VkKeyScanEx( WCHAR ch, HKL hkl ) DECLSPEC_HIDDEN; -extern void ANDROID_SetCursor( HCURSOR handle ) DECLSPEC_HIDDEN; +extern void ANDROID_SetCursor( HWND hwnd, HCURSOR handle ) DECLSPEC_HIDDEN; extern BOOL ANDROID_CreateDesktop( const WCHAR *name, UINT width, UINT height ) DECLSPEC_HIDDEN; extern BOOL ANDROID_CreateWindow( HWND hwnd ) DECLSPEC_HIDDEN; extern void ANDROID_DestroyWindow( HWND hwnd ) DECLSPEC_HIDDEN; extern BOOL ANDROID_ProcessEvents( DWORD mask ) DECLSPEC_HIDDEN; extern LRESULT ANDROID_DesktopWindowProc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) DECLSPEC_HIDDEN; -extern void ANDROID_SetCursor( HCURSOR handle ) DECLSPEC_HIDDEN; extern void ANDROID_SetLayeredWindowAttributes( HWND hwnd, COLORREF key, BYTE alpha, DWORD flags ) DECLSPEC_HIDDEN; extern void ANDROID_SetParent( HWND hwnd, HWND parent, HWND old_parent ) DECLSPEC_HIDDEN; diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index 2b65f804938..d6eb0165d49 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -1446,7 +1446,7 @@ static BOOL get_icon_info( HICON handle, ICONINFOEXW *ret ) /*********************************************************************** * ANDROID_SetCursor */ -void ANDROID_SetCursor( HCURSOR handle ) +void ANDROID_SetCursor( HWND hwnd, HCURSOR handle ) { static HCURSOR last_cursor; static DWORD last_cursor_change; diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index d857a7d0919..35ee6425b86 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -159,7 +159,7 @@ extern void macdrv_WindowPosChanged(HWND hwnd, HWND insert_after, UINT swp_flags extern void macdrv_DestroyCursorIcon(HCURSOR cursor) DECLSPEC_HIDDEN; extern BOOL macdrv_GetCursorPos(LPPOINT pos) DECLSPEC_HIDDEN; extern void macdrv_SetCapture(HWND hwnd, UINT flags) DECLSPEC_HIDDEN; -extern void macdrv_SetCursor(HCURSOR cursor) DECLSPEC_HIDDEN; +extern void macdrv_SetCursor(HWND hwnd, HCURSOR cursor) DECLSPEC_HIDDEN; extern BOOL macdrv_SetCursorPos(INT x, INT y) DECLSPEC_HIDDEN; extern BOOL macdrv_RegisterHotKey(HWND hwnd, UINT mod_flags, UINT vkey) DECLSPEC_HIDDEN; extern void macdrv_UnregisterHotKey(HWND hwnd, UINT modifiers, UINT vkey) DECLSPEC_HIDDEN; diff --git a/dlls/winemac.drv/mouse.c b/dlls/winemac.drv/mouse.c index 1ff0f631fe6..5c04c71e1dc 100644 --- a/dlls/winemac.drv/mouse.c +++ b/dlls/winemac.drv/mouse.c @@ -744,12 +744,12 @@ static BOOL get_icon_info(HICON handle, ICONINFOEXW *ret) /*********************************************************************** * SetCursor (MACDRV.@) */ -void macdrv_SetCursor(HCURSOR cursor) +void macdrv_SetCursor(HWND hwnd, HCURSOR cursor) { CFStringRef cursor_name = NULL; CFArrayRef cursor_frames = NULL;
- TRACE("%p\n", cursor); + TRACE("%p %p\n", hwnd, cursor);
if (cursor) { diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index 33256e5880c..330f3d67fc2 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -1402,7 +1402,7 @@ void X11DRV_DestroyCursorIcon( HCURSOR handle ) /*********************************************************************** * SetCursor (X11DRV.@) */ -void X11DRV_SetCursor( HCURSOR handle ) +void X11DRV_SetCursor( HWND hwnd, HCURSOR handle ) { if (InterlockedExchangePointer( (void **)&last_cursor, handle ) != handle || NtGetTickCount() - last_cursor_change > 100) diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 1055bcc7117..8bb47cd1207 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -213,7 +213,7 @@ extern UINT X11DRV_ImeToAsciiEx( UINT vkey, UINT vsc, const BYTE *state, extern SHORT X11DRV_VkKeyScanEx( WCHAR wChar, HKL hkl ) DECLSPEC_HIDDEN; extern void X11DRV_NotifyIMEStatus( HWND hwnd, UINT status ) DECLSPEC_HIDDEN; extern void X11DRV_DestroyCursorIcon( HCURSOR handle ) DECLSPEC_HIDDEN; -extern void X11DRV_SetCursor( HCURSOR handle ) DECLSPEC_HIDDEN; +extern void X11DRV_SetCursor( HWND hwnd, HCURSOR handle ) DECLSPEC_HIDDEN; extern BOOL X11DRV_SetCursorPos( INT x, INT y ) DECLSPEC_HIDDEN; extern BOOL X11DRV_GetCursorPos( LPPOINT pos ) DECLSPEC_HIDDEN; extern BOOL X11DRV_ClipCursor( const RECT *clip, BOOL reset ) DECLSPEC_HIDDEN; diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index ff7d61a1274..c4e859f21e5 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -298,7 +298,7 @@ struct user_driver_funcs void (*pNotifyIMEStatus)(HWND,UINT); /* cursor/icon functions */ void (*pDestroyCursorIcon)(HCURSOR); - void (*pSetCursor)(HCURSOR); + void (*pSetCursor)(HWND,HCURSOR); BOOL (*pGetCursorPos)(LPPOINT); BOOL (*pSetCursorPos)(INT,INT); BOOL (*pClipCursor)(const RECT*,BOOL);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/cursoricon.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-)
diff --git a/dlls/win32u/cursoricon.c b/dlls/win32u/cursoricon.c index 23bb4354c2a..51226ed81a5 100644 --- a/dlls/win32u/cursoricon.c +++ b/dlls/win32u/cursoricon.c @@ -77,6 +77,7 @@ static struct cursoricon_object *get_icon_ptr( HICON handle ) BOOL process_wine_setcursor( HWND hwnd, HWND window, HCURSOR handle ) { TRACE( "hwnd %p, window %p, hcursor %p\n", hwnd, window, handle ); + user_driver->pSetCursor( window, handle ); return TRUE; }
@@ -85,7 +86,6 @@ BOOL process_wine_setcursor( HWND hwnd, HWND window, HCURSOR handle ) */ INT WINAPI NtUserShowCursor( BOOL show ) { - HCURSOR cursor; int increment = show ? 1 : -1; int count;
@@ -94,16 +94,11 @@ INT WINAPI NtUserShowCursor( BOOL show ) req->flags = SET_CURSOR_COUNT; req->show_count = increment; wine_server_call( req ); - cursor = wine_server_ptr_handle( reply->prev_handle ); count = reply->prev_count + increment; } SERVER_END_REQ;
TRACE("%d, count=%d\n", show, count ); - - if (show && !count) user_driver->pSetCursor( 0, cursor ); - else if (!show && count == -1) user_driver->pSetCursor( 0, 0 ); - return count; }
@@ -114,7 +109,6 @@ HCURSOR WINAPI NtUserSetCursor( HCURSOR cursor ) { struct cursoricon_object *obj; HCURSOR old_cursor; - int show_count; BOOL ret;
TRACE( "%p\n", cursor ); @@ -124,16 +118,11 @@ HCURSOR WINAPI NtUserSetCursor( HCURSOR cursor ) req->flags = SET_CURSOR_HANDLE; req->handle = wine_server_user_handle( cursor ); if ((ret = !wine_server_call_err( req ))) - { old_cursor = wine_server_ptr_handle( reply->prev_handle ); - show_count = reply->prev_count; - } } SERVER_END_REQ; if (!ret) return 0;
- user_driver->pSetCursor( 0, show_count >= 0 ? cursor : 0 ); - if (!(obj = get_icon_ptr( old_cursor ))) return 0; release_user_handle_ptr( obj ); return old_cursor;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/wineandroid.drv/window.c | 47 ++++++++++++++--------------------- 1 file changed, 19 insertions(+), 28 deletions(-)
diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index d6eb0165d49..3a61a2d44d9 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -1448,42 +1448,33 @@ static BOOL get_icon_info( HICON handle, ICONINFOEXW *ret ) */ void ANDROID_SetCursor( HWND hwnd, HCURSOR handle ) { - static HCURSOR last_cursor; - static DWORD last_cursor_change; - - if (InterlockedExchangePointer( (void **)&last_cursor, handle ) != handle || - NtGetTickCount() - last_cursor_change > 100) + if (handle) { - last_cursor_change = NtGetTickCount(); + unsigned int width = 0, height = 0, *bits = NULL; + ICONINFOEXW info; + int id;
- if (handle) - { - unsigned int width = 0, height = 0, *bits = NULL; - ICONINFOEXW info; - int id; + if (!get_icon_info( handle, &info )) return;
- if (!get_icon_info( handle, &info )) return; + if (!(id = get_cursor_system_id( &info ))) + { + HDC hdc = NtGdiCreateCompatibleDC( 0 ); + bits = get_bitmap_argb( hdc, info.hbmColor, info.hbmMask, &width, &height ); + NtGdiDeleteObjectApp( hdc );
- if (!(id = get_cursor_system_id( &info ))) + /* make sure hotspot is valid */ + if (info.xHotspot >= width || info.yHotspot >= height) { - HDC hdc = NtGdiCreateCompatibleDC( 0 ); - bits = get_bitmap_argb( hdc, info.hbmColor, info.hbmMask, &width, &height ); - NtGdiDeleteObjectApp( hdc ); - - /* make sure hotspot is valid */ - if (info.xHotspot >= width || info.yHotspot >= height) - { - info.xHotspot = width / 2; - info.yHotspot = height / 2; - } + info.xHotspot = width / 2; + info.yHotspot = height / 2; } - ioctl_set_cursor( id, width, height, info.xHotspot, info.yHotspot, bits ); - free( bits ); - NtGdiDeleteObjectApp( info.hbmColor ); - NtGdiDeleteObjectApp( info.hbmMask ); } - else ioctl_set_cursor( 0, 0, 0, 0, 0, NULL ); + ioctl_set_cursor( id, width, height, info.xHotspot, info.yHotspot, bits ); + free( bits ); + NtGdiDeleteObjectApp( info.hbmColor ); + NtGdiDeleteObjectApp( info.hbmMask ); } + else ioctl_set_cursor( 0, 0, 0, 0, 0, NULL ); }
From: Rémi Bernon rbernon@codeweavers.com
Instead of synchronizing the cursor on mouse changes. The SetCursor call should now only be made when cursor or window handle have changed. --- dlls/winex11.drv/mouse.c | 61 ++++++++++++--------------------------- dlls/winex11.drv/window.c | 23 --------------- dlls/winex11.drv/x11drv.h | 2 -- 3 files changed, 19 insertions(+), 67 deletions(-)
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c index 330f3d67fc2..46d26726264 100644 --- a/dlls/winex11.drv/mouse.c +++ b/dlls/winex11.drv/mouse.c @@ -123,9 +123,6 @@ static const UINT button_up_data[NB_BUTTONS] =
XContext cursor_context = 0;
-static HWND cursor_window; -static HCURSOR last_cursor; -static DWORD last_cursor_change; static RECT last_clip_rect; static HWND last_clip_foreground_window; static BOOL last_clip_refused; @@ -231,24 +228,6 @@ void set_window_cursor( Window window, HCURSOR handle ) XFlush( gdi_display ); }
-/*********************************************************************** - * sync_window_cursor - */ -void sync_window_cursor( Window window ) -{ - HCURSOR cursor; - - SERVER_START_REQ( set_cursor ) - { - req->flags = 0; - wine_server_call( req ); - cursor = reply->prev_count >= 0 ? wine_server_ptr_handle( reply->prev_handle ) : 0; - } - SERVER_END_REQ; - - set_window_cursor( window, cursor ); -} - #ifdef HAVE_X11_EXTENSIONS_XINPUT2_H /*********************************************************************** * update_relative_valuators @@ -377,6 +356,7 @@ static BOOL grab_clipping_window( const RECT *clip ) UNICODE_STRING class_name = RTL_CONSTANT_STRING( messageW ); Window clip_window; HWND msg_hwnd = 0; + HCURSOR cursor; POINT pos;
if (NtUserGetWindowThread( NtUserGetDesktopWindow(), NULL ) == GetCurrentThreadId()) @@ -432,6 +412,17 @@ static BOOL grab_clipping_window( const RECT *clip ) GrabModeAsync, GrabModeAsync, clip_window, None, CurrentTime )) clipping_cursor = TRUE;
+ SERVER_START_REQ( set_cursor ) + { + req->flags = 0; + wine_server_call( req ); + if (reply->prev_count < 0) cursor = 0; + else cursor = wine_server_ptr_handle( reply->prev_handle ); + } + SERVER_END_REQ; + + set_window_cursor( clip_window, cursor ); + if (!clipping_cursor) { disable_xinput2(); @@ -439,8 +430,6 @@ static BOOL grab_clipping_window( const RECT *clip ) return FALSE; } clip_rect = *clip; - if (!data->clip_hwnd) sync_window_cursor( clip_window ); - InterlockedExchangePointer( (void **)&cursor_window, msg_hwnd ); data->clip_hwnd = msg_hwnd; return TRUE; #else @@ -554,7 +543,6 @@ static void map_event_coords( HWND hwnd, Window window, Window event_root, int x static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPUT *input ) { struct x11drv_win_data *data; - Window win = 0;
input->type = INPUT_MOUSE;
@@ -565,25 +553,12 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU
if (!clip_hwnd) return; if (thread_data->clip_window != window) return; - if (InterlockedExchangePointer( (void **)&cursor_window, clip_hwnd ) != clip_hwnd || - input->u.mi.time - last_cursor_change > 100) - { - sync_window_cursor( window ); - last_cursor_change = input->u.mi.time; - } __wine_send_input( hwnd, input, NULL ); return; }
if (!(data = get_win_data( hwnd ))) return; - win = data->whole_window; release_win_data( data ); - if (InterlockedExchangePointer( (void **)&cursor_window, hwnd ) != hwnd || - input->u.mi.time - last_cursor_change > 100) - { - sync_window_cursor( win ); - last_cursor_change = input->u.mi.time; - }
/* update the wine server Z-order */
@@ -1404,13 +1379,15 @@ void X11DRV_DestroyCursorIcon( HCURSOR handle ) */ void X11DRV_SetCursor( HWND hwnd, HCURSOR handle ) { - if (InterlockedExchangePointer( (void **)&last_cursor, handle ) != handle || - NtGetTickCount() - last_cursor_change > 100) + struct x11drv_win_data *data; + + if ((data = get_win_data( hwnd ))) { - last_cursor_change = NtGetTickCount(); - if (cursor_window) send_notify_message( cursor_window, WM_X11DRV_SET_CURSOR, - GetCurrentThreadId(), (LPARAM)handle ); + set_window_cursor( data->whole_window, handle ); + release_win_data( data ); } + + if (clipping_cursor) set_window_cursor( x11drv_thread_data()->clip_window, handle ); }
/*********************************************************************** diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index e139b06d634..974bd376fe6 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1666,8 +1666,6 @@ static void create_whole_window( struct x11drv_win_data *data )
XFlush( data->display ); /* make sure the window exists before we start painting to it */
- sync_window_cursor( data->whole_window ); - done: if (win_rgn) NtGdiDeleteObjectApp( win_rgn ); } @@ -3064,27 +3062,6 @@ LRESULT X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) release_win_data( data ); } return 0; - case WM_X11DRV_SET_CURSOR: - { - Window win = 0; - - if ((data = get_win_data( hwnd ))) - { - win = data->whole_window; - release_win_data( data ); - } - else if (hwnd == x11drv_thread_data()->clip_hwnd) - win = x11drv_thread_data()->clip_window; - - if (win) - { - if (wp == GetCurrentThreadId()) - set_window_cursor( win, (HCURSOR)lp ); - else - sync_window_cursor( win ); - } - return 0; - } case WM_X11DRV_DELETE_TAB: taskbar_delete_tab( hwnd ); return 0; diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 8bb47cd1207..8827d0cc0c2 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -586,7 +586,6 @@ enum x11drv_window_messages WM_X11DRV_UPDATE_CLIPBOARD = 0x80001000, WM_X11DRV_SET_WIN_REGION, WM_X11DRV_DESKTOP_RESIZED, - WM_X11DRV_SET_CURSOR, WM_X11DRV_DELETE_TAB, WM_X11DRV_ADD_TAB }; @@ -679,7 +678,6 @@ extern XContext cursor_context DECLSPEC_HIDDEN;
extern void X11DRV_SetFocus( HWND hwnd ) DECLSPEC_HIDDEN; extern void set_window_cursor( Window window, HCURSOR handle ) DECLSPEC_HIDDEN; -extern void sync_window_cursor( Window window ) DECLSPEC_HIDDEN; extern void retry_grab_clipping_window(void) DECLSPEC_HIDDEN; extern void move_resize_window( HWND hwnd, int dir ) DECLSPEC_HIDDEN; extern void X11DRV_InitKeyboard( Display *display ) DECLSPEC_HIDDEN;
This merge request was approved by Huw Davies.