Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/user32/input.c | 254 ----------------------------------- dlls/user32/scroll.c | 8 +- dlls/user32/user32.spec | 2 +- dlls/user32/user_main.c | 1 - dlls/user32/user_private.h | 1 - dlls/win32u/gdiobj.c | 1 + dlls/win32u/input.c | 218 ++++++++++++++++++++++++++++++ dlls/win32u/message.c | 3 +- dlls/win32u/ntuser_private.h | 1 - dlls/win32u/win32u.spec | 2 +- dlls/win32u/win32u_private.h | 2 + dlls/win32u/wrappers.c | 6 + include/ntuser.h | 1 + 13 files changed, 235 insertions(+), 265 deletions(-)
diff --git a/dlls/user32/input.c b/dlls/user32/input.c index 4ef33ab2838..dcb46df22b5 100644 --- a/dlls/user32/input.c +++ b/dlls/user32/input.c @@ -49,32 +49,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(win); WINE_DECLARE_DEBUG_CHANNEL(keyboard);
-/*********************************************************************** - * get_key_state - */ -static WORD get_key_state(void) -{ - WORD ret = 0; - - if (GetSystemMetrics( SM_SWAPBUTTON )) - { - if (NtUserGetAsyncKeyState(VK_RBUTTON) & 0x80) ret |= MK_LBUTTON; - if (NtUserGetAsyncKeyState(VK_LBUTTON) & 0x80) ret |= MK_RBUTTON; - } - else - { - if (NtUserGetAsyncKeyState(VK_LBUTTON) & 0x80) ret |= MK_LBUTTON; - if (NtUserGetAsyncKeyState(VK_RBUTTON) & 0x80) ret |= MK_RBUTTON; - } - if (NtUserGetAsyncKeyState(VK_MBUTTON) & 0x80) ret |= MK_MBUTTON; - if (NtUserGetAsyncKeyState(VK_SHIFT) & 0x80) ret |= MK_SHIFT; - if (NtUserGetAsyncKeyState(VK_CONTROL) & 0x80) ret |= MK_CONTROL; - if (NtUserGetAsyncKeyState(VK_XBUTTON1) & 0x80) ret |= MK_XBUTTON1; - if (NtUserGetAsyncKeyState(VK_XBUTTON2) & 0x80) ret |= MK_XBUTTON2; - return ret; -} - - /*********************************************************************** * get_locale_kbd_layout */ @@ -520,234 +494,6 @@ BOOL WINAPI UnloadKeyboardLayout( HKL layout ) return FALSE; }
-typedef struct __TRACKINGLIST { - TRACKMOUSEEVENT tme; - POINT pos; /* center of hover rectangle */ -} _TRACKINGLIST; - -/* FIXME: move tracking stuff into a per thread data */ -static _TRACKINGLIST tracking_info; - -static void check_mouse_leave(HWND hwnd, int hittest) -{ - if (tracking_info.tme.hwndTrack != hwnd) - { - if (tracking_info.tme.dwFlags & TME_NONCLIENT) - PostMessageW(tracking_info.tme.hwndTrack, WM_NCMOUSELEAVE, 0, 0); - else - PostMessageW(tracking_info.tme.hwndTrack, WM_MOUSELEAVE, 0, 0); - - /* remove the TME_LEAVE flag */ - tracking_info.tme.dwFlags &= ~TME_LEAVE; - } - else - { - if (hittest == HTCLIENT) - { - if (tracking_info.tme.dwFlags & TME_NONCLIENT) - { - PostMessageW(tracking_info.tme.hwndTrack, WM_NCMOUSELEAVE, 0, 0); - /* remove the TME_LEAVE flag */ - tracking_info.tme.dwFlags &= ~TME_LEAVE; - } - } - else - { - if (!(tracking_info.tme.dwFlags & TME_NONCLIENT)) - { - PostMessageW(tracking_info.tme.hwndTrack, WM_MOUSELEAVE, 0, 0); - /* remove the TME_LEAVE flag */ - tracking_info.tme.dwFlags &= ~TME_LEAVE; - } - } - } -} - -void CDECL update_mouse_tracking_info( HWND hwnd ) -{ - POINT pos; - INT hoverwidth = 0, hoverheight = 0, hittest; - - TRACE( "hwnd %p\n", hwnd ); - - GetCursorPos(&pos); - hwnd = WINPOS_WindowFromPoint(hwnd, pos, &hittest); - - TRACE("point %s hwnd %p hittest %d\n", wine_dbgstr_point(&pos), hwnd, hittest); - - SystemParametersInfoW(SPI_GETMOUSEHOVERWIDTH, 0, &hoverwidth, 0); - SystemParametersInfoW(SPI_GETMOUSEHOVERHEIGHT, 0, &hoverheight, 0); - - TRACE("tracked pos %s, current pos %s, hover width %d, hover height %d\n", - wine_dbgstr_point(&tracking_info.pos), wine_dbgstr_point(&pos), - hoverwidth, hoverheight); - - /* see if this tracking event is looking for TME_LEAVE and that the */ - /* mouse has left the window */ - if (tracking_info.tme.dwFlags & TME_LEAVE) - { - check_mouse_leave(hwnd, hittest); - } - - if (tracking_info.tme.hwndTrack != hwnd) - { - /* mouse is gone, stop tracking mouse hover */ - tracking_info.tme.dwFlags &= ~TME_HOVER; - } - - /* see if we are tracking hovering for this hwnd */ - if (tracking_info.tme.dwFlags & TME_HOVER) - { - /* has the cursor moved outside the rectangle centered around pos? */ - if ((abs(pos.x - tracking_info.pos.x) > (hoverwidth / 2)) || - (abs(pos.y - tracking_info.pos.y) > (hoverheight / 2))) - { - /* record this new position as the current position */ - tracking_info.pos = pos; - } - else - { - if (hittest == HTCLIENT) - { - ScreenToClient(hwnd, &pos); - TRACE("client cursor pos %s\n", wine_dbgstr_point(&pos)); - - PostMessageW(tracking_info.tme.hwndTrack, WM_MOUSEHOVER, - get_key_state(), MAKELPARAM( pos.x, pos.y )); - } - else - { - if (tracking_info.tme.dwFlags & TME_NONCLIENT) - PostMessageW(tracking_info.tme.hwndTrack, WM_NCMOUSEHOVER, - hittest, MAKELPARAM( pos.x, pos.y )); - } - - /* stop tracking mouse hover */ - tracking_info.tme.dwFlags &= ~TME_HOVER; - } - } - - /* stop the timer if the tracking list is empty */ - if (!(tracking_info.tme.dwFlags & (TME_HOVER | TME_LEAVE))) - { - KillSystemTimer( tracking_info.tme.hwndTrack, SYSTEM_TIMER_TRACK_MOUSE ); - tracking_info.tme.hwndTrack = 0; - tracking_info.tme.dwFlags = 0; - tracking_info.tme.dwHoverTime = 0; - } -} - - -/*********************************************************************** - * TrackMouseEvent [USER32] - * - * Requests notification of mouse events - * - * During mouse tracking WM_MOUSEHOVER or WM_MOUSELEAVE events are posted - * to the hwnd specified in the ptme structure. After the event message - * is posted to the hwnd, the entry in the queue is removed. - * - * If the current hwnd isn't ptme->hwndTrack the TME_HOVER flag is completely - * ignored. The TME_LEAVE flag results in a WM_MOUSELEAVE message being posted - * immediately and the TME_LEAVE flag being ignored. - * - * PARAMS - * ptme [I,O] pointer to TRACKMOUSEEVENT information structure. - * - * RETURNS - * Success: non-zero - * Failure: zero - * - */ - -BOOL WINAPI -TrackMouseEvent (TRACKMOUSEEVENT *ptme) -{ - HWND hwnd; - POINT pos; - DWORD hover_time; - INT hittest; - - TRACE("%x, %x, %p, %u\n", ptme->cbSize, ptme->dwFlags, ptme->hwndTrack, ptme->dwHoverTime); - - if (ptme->cbSize != sizeof(TRACKMOUSEEVENT)) { - WARN("wrong TRACKMOUSEEVENT size from app\n"); - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - /* fill the TRACKMOUSEEVENT struct with the current tracking for the given hwnd */ - if (ptme->dwFlags & TME_QUERY ) - { - *ptme = tracking_info.tme; - /* set cbSize in the case it's not initialized yet */ - ptme->cbSize = sizeof(TRACKMOUSEEVENT); - - return TRUE; /* return here, TME_QUERY is retrieving information */ - } - - if (!IsWindow(ptme->hwndTrack)) - { - SetLastError(ERROR_INVALID_WINDOW_HANDLE); - return FALSE; - } - - hover_time = (ptme->dwFlags & TME_HOVER) ? ptme->dwHoverTime : HOVER_DEFAULT; - - /* if HOVER_DEFAULT was specified replace this with the system's current value. - * TME_LEAVE doesn't need to specify hover time so use default */ - if (hover_time == HOVER_DEFAULT || hover_time == 0) - SystemParametersInfoW(SPI_GETMOUSEHOVERTIME, 0, &hover_time, 0); - - GetCursorPos(&pos); - hwnd = WINPOS_WindowFromPoint(ptme->hwndTrack, pos, &hittest); - TRACE("point %s hwnd %p hittest %d\n", wine_dbgstr_point(&pos), hwnd, hittest); - - if (ptme->dwFlags & ~(TME_CANCEL | TME_HOVER | TME_LEAVE | TME_NONCLIENT)) - FIXME("Unknown flag(s) %08x\n", ptme->dwFlags & ~(TME_CANCEL | TME_HOVER | TME_LEAVE | TME_NONCLIENT)); - - if (ptme->dwFlags & TME_CANCEL) - { - if (tracking_info.tme.hwndTrack == ptme->hwndTrack) - { - tracking_info.tme.dwFlags &= ~(ptme->dwFlags & ~TME_CANCEL); - - /* if we aren't tracking on hover or leave remove this entry */ - if (!(tracking_info.tme.dwFlags & (TME_HOVER | TME_LEAVE))) - { - KillSystemTimer( tracking_info.tme.hwndTrack, SYSTEM_TIMER_TRACK_MOUSE ); - tracking_info.tme.hwndTrack = 0; - tracking_info.tme.dwFlags = 0; - tracking_info.tme.dwHoverTime = 0; - } - } - } else { - /* In our implementation it's possible that another window will receive a - * WM_MOUSEMOVE and call TrackMouseEvent before TrackMouseEventProc is - * called. In such a situation post the WM_MOUSELEAVE now */ - if (tracking_info.tme.dwFlags & TME_LEAVE && tracking_info.tme.hwndTrack != NULL) - check_mouse_leave(hwnd, hittest); - - KillSystemTimer( tracking_info.tme.hwndTrack, SYSTEM_TIMER_TRACK_MOUSE ); - tracking_info.tme.hwndTrack = 0; - tracking_info.tme.dwFlags = 0; - tracking_info.tme.dwHoverTime = 0; - - if (ptme->hwndTrack == hwnd) - { - /* Adding new mouse event to the tracking list */ - tracking_info.tme = *ptme; - tracking_info.tme.dwHoverTime = hover_time; - - /* Initialize HoverInfo variables even if not hover tracking */ - tracking_info.pos = pos; - - NtUserSetSystemTimer( tracking_info.tme.hwndTrack, SYSTEM_TIMER_TRACK_MOUSE, hover_time ); - } - } - - return TRUE; -}
/*********************************************************************** * EnableMouseInPointer (USER32.@) diff --git a/dlls/user32/scroll.c b/dlls/user32/scroll.c index 45980b75b2c..8f085364dab 100644 --- a/dlls/user32/scroll.c +++ b/dlls/user32/scroll.c @@ -864,12 +864,12 @@ void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt )
tme.cbSize = sizeof(tme); tme.dwFlags = TME_QUERY; - TrackMouseEvent( &tme ); + NtUserTrackMouseEvent( &tme ); if (!(tme.dwFlags & TME_LEAVE) || tme.hwndTrack != hwnd) { tme.dwFlags = TME_LEAVE; tme.hwndTrack = hwnd; - TrackMouseEvent( &tme ); + NtUserTrackMouseEvent( &tme ); }
break; @@ -883,12 +883,12 @@ void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt )
tme.cbSize = sizeof(tme); tme.dwFlags = TME_QUERY; - TrackMouseEvent( &tme ); + NtUserTrackMouseEvent( &tme ); if (((tme.dwFlags & (TME_NONCLIENT | TME_LEAVE)) != (TME_NONCLIENT | TME_LEAVE)) || tme.hwndTrack != hwnd) { tme.dwFlags = TME_NONCLIENT | TME_LEAVE; tme.hwndTrack = hwnd; - TrackMouseEvent( &tme ); + NtUserTrackMouseEvent( &tme ); }
break; diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec index a7b2f7e0681..f7f41621812 100644 --- a/dlls/user32/user32.spec +++ b/dlls/user32/user32.spec @@ -762,7 +762,7 @@ @ stdcall ToAsciiEx(long long ptr ptr long long) @ stdcall ToUnicode(long long ptr ptr long long) @ stdcall ToUnicodeEx(long long ptr ptr long long long) NtUserToUnicodeEx -@ stdcall TrackMouseEvent(ptr) +@ stdcall TrackMouseEvent(ptr) NtUserTrackMouseEvent @ stdcall TrackPopupMenu(long long long long long long ptr) @ stdcall TrackPopupMenuEx(long long long long long ptr) @ stdcall TranslateAccelerator(long long ptr) TranslateAcceleratorA diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c index 08f2833ee3f..6e0722e4750 100644 --- a/dlls/user32/user_main.c +++ b/dlls/user32/user_main.c @@ -179,7 +179,6 @@ static const struct user_callbacks user_funcs = SCROLL_SetStandardScrollPainted, toggle_caret, unpack_dde_message, - update_mouse_tracking_info, register_imm, unregister_imm, }; diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index 54b11f2a8ef..96c47a71753 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -100,7 +100,6 @@ extern void SYSPARAMS_Init(void) DECLSPEC_HIDDEN; extern void USER_CheckNotLock(void) DECLSPEC_HIDDEN; extern BOOL USER_IsExitingThread( DWORD tid ) DECLSPEC_HIDDEN; extern void CDECL toggle_caret( HWND hwnd ) DECLSPEC_HIDDEN; -extern void CDECL update_mouse_tracking_info( HWND hwnd ) DECLSPEC_HIDDEN;
typedef LRESULT (*winproc_callback_t)( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp, LRESULT *result, void *arg ); diff --git a/dlls/win32u/gdiobj.c b/dlls/win32u/gdiobj.c index fbaf61a52f6..ed483d8f205 100644 --- a/dlls/win32u/gdiobj.c +++ b/dlls/win32u/gdiobj.c @@ -1213,6 +1213,7 @@ static struct unix_funcs unix_funcs = NtUserSystemParametersInfo, NtUserSystemParametersInfoForDpi, NtUserToUnicodeEx, + NtUserTrackMouseEvent, NtUserTranslateMessage, NtUserUnregisterClass, NtUserUnregisterHotKey, diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index dd28170b1f0..61de034d7c8 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -1171,6 +1171,224 @@ int WINAPI NtUserGetMouseMovePointsEx( UINT size, MOUSEMOVEPOINT *ptin, MOUSEMOV return copied; }
+static WORD get_key_state(void) +{ + WORD ret = 0; + + if (get_system_metrics( SM_SWAPBUTTON )) + { + if (NtUserGetAsyncKeyState(VK_RBUTTON) & 0x80) ret |= MK_LBUTTON; + if (NtUserGetAsyncKeyState(VK_LBUTTON) & 0x80) ret |= MK_RBUTTON; + } + else + { + if (NtUserGetAsyncKeyState(VK_LBUTTON) & 0x80) ret |= MK_LBUTTON; + if (NtUserGetAsyncKeyState(VK_RBUTTON) & 0x80) ret |= MK_RBUTTON; + } + if (NtUserGetAsyncKeyState(VK_MBUTTON) & 0x80) ret |= MK_MBUTTON; + if (NtUserGetAsyncKeyState(VK_SHIFT) & 0x80) ret |= MK_SHIFT; + if (NtUserGetAsyncKeyState(VK_CONTROL) & 0x80) ret |= MK_CONTROL; + if (NtUserGetAsyncKeyState(VK_XBUTTON1) & 0x80) ret |= MK_XBUTTON1; + if (NtUserGetAsyncKeyState(VK_XBUTTON2) & 0x80) ret |= MK_XBUTTON2; + return ret; +} + +struct tracking_list +{ + TRACKMOUSEEVENT info; + POINT pos; /* center of hover rectangle */ +}; + +/* FIXME: move tracking stuff into per-thread data */ +static struct tracking_list tracking_info; + +static void check_mouse_leave( HWND hwnd, int hittest ) +{ + if (tracking_info.info.hwndTrack != hwnd) + { + if (tracking_info.info.dwFlags & TME_NONCLIENT) + NtUserPostMessage( tracking_info.info.hwndTrack, WM_NCMOUSELEAVE, 0, 0 ); + else + NtUserPostMessage( tracking_info.info.hwndTrack, WM_MOUSELEAVE, 0, 0 ); + + tracking_info.info.dwFlags &= ~TME_LEAVE; + } + else + { + if (hittest == HTCLIENT) + { + if (tracking_info.info.dwFlags & TME_NONCLIENT) + { + NtUserPostMessage( tracking_info.info.hwndTrack, WM_NCMOUSELEAVE, 0, 0 ); + tracking_info.info.dwFlags &= ~TME_LEAVE; + } + } + else + { + if (!(tracking_info.info.dwFlags & TME_NONCLIENT)) + { + NtUserPostMessage( tracking_info.info.hwndTrack, WM_MOUSELEAVE, 0, 0 ); + tracking_info.info.dwFlags &= ~TME_LEAVE; + } + } + } +} + +void update_mouse_tracking_info( HWND hwnd ) +{ + int hover_width = 0, hover_height = 0, hittest; + POINT pos; + + TRACE( "hwnd %p\n", hwnd ); + + get_cursor_pos( &pos ); + hwnd = window_from_point( hwnd, pos, &hittest ); + + TRACE( "point %s hwnd %p hittest %d\n", wine_dbgstr_point(&pos), hwnd, hittest ); + + NtUserSystemParametersInfo( SPI_GETMOUSEHOVERWIDTH, 0, &hover_width, 0 ); + NtUserSystemParametersInfo( SPI_GETMOUSEHOVERHEIGHT, 0, &hover_height, 0 ); + + TRACE( "tracked pos %s, current pos %s, hover width %d, hover height %d\n", + wine_dbgstr_point(&tracking_info.pos), wine_dbgstr_point(&pos), + hover_width, hover_height ); + + if (tracking_info.info.dwFlags & TME_LEAVE) + check_mouse_leave(hwnd, hittest); + + if (tracking_info.info.hwndTrack != hwnd) + tracking_info.info.dwFlags &= ~TME_HOVER; + + if (tracking_info.info.dwFlags & TME_HOVER) + { + /* has the cursor moved outside the rectangle centered around pos? */ + if ((abs( pos.x - tracking_info.pos.x ) > (hover_width / 2)) || + (abs( pos.y - tracking_info.pos.y ) > (hover_height / 2))) + { + tracking_info.pos = pos; + } + else + { + if (hittest == HTCLIENT) + { + screen_to_client(hwnd, &pos); + TRACE( "client cursor pos %s\n", wine_dbgstr_point(&pos) ); + + NtUserPostMessage( tracking_info.info.hwndTrack, WM_MOUSEHOVER, + get_key_state(), MAKELPARAM( pos.x, pos.y ) ); + } + else + { + if (tracking_info.info.dwFlags & TME_NONCLIENT) + NtUserPostMessage( tracking_info.info.hwndTrack, WM_NCMOUSEHOVER, + hittest, MAKELPARAM( pos.x, pos.y ) ); + } + + /* stop tracking mouse hover */ + tracking_info.info.dwFlags &= ~TME_HOVER; + } + } + + /* stop the timer if the tracking list is empty */ + if (!(tracking_info.info.dwFlags & (TME_HOVER | TME_LEAVE))) + { + kill_system_timer( tracking_info.info.hwndTrack, SYSTEM_TIMER_TRACK_MOUSE ); + tracking_info.info.hwndTrack = 0; + tracking_info.info.dwFlags = 0; + tracking_info.info.dwHoverTime = 0; + } +} + +/*********************************************************************** + * NtUserTrackMouseEvent (win32u.@) + */ +BOOL WINAPI NtUserTrackMouseEvent( TRACKMOUSEEVENT *info ) +{ + DWORD hover_time; + int hittest; + HWND hwnd; + POINT pos; + + TRACE( "size %u, flags %#x, hwnd %p, time %u\n", + info->cbSize, info->dwFlags, info->hwndTrack, info->dwHoverTime ); + + if (info->cbSize != sizeof(TRACKMOUSEEVENT)) + { + WARN( "wrong size %u\n", info->cbSize ); + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + if (info->dwFlags & TME_QUERY) + { + *info = tracking_info.info; + info->cbSize = sizeof(TRACKMOUSEEVENT); + return TRUE; + } + + if (!is_window( info->hwndTrack )) + { + SetLastError( ERROR_INVALID_WINDOW_HANDLE ); + return FALSE; + } + + hover_time = (info->dwFlags & TME_HOVER) ? info->dwHoverTime : HOVER_DEFAULT; + + if (hover_time == HOVER_DEFAULT || hover_time == 0) + NtUserSystemParametersInfo( SPI_GETMOUSEHOVERTIME, 0, &hover_time, 0 ); + + get_cursor_pos( &pos ); + hwnd = window_from_point( info->hwndTrack, pos, &hittest ); + TRACE( "point %s hwnd %p hittest %d\n", wine_dbgstr_point(&pos), hwnd, hittest ); + + if (info->dwFlags & ~(TME_CANCEL | TME_HOVER | TME_LEAVE | TME_NONCLIENT)) + FIXME( "ignoring flags %#x\n", info->dwFlags & ~(TME_CANCEL | TME_HOVER | TME_LEAVE | TME_NONCLIENT) ); + + if (info->dwFlags & TME_CANCEL) + { + if (tracking_info.info.hwndTrack == info->hwndTrack) + { + tracking_info.info.dwFlags &= ~(info->dwFlags & ~TME_CANCEL); + + /* if we aren't tracking on hover or leave remove this entry */ + if (!(tracking_info.info.dwFlags & (TME_HOVER | TME_LEAVE))) + { + kill_system_timer( tracking_info.info.hwndTrack, SYSTEM_TIMER_TRACK_MOUSE ); + tracking_info.info.hwndTrack = 0; + tracking_info.info.dwFlags = 0; + tracking_info.info.dwHoverTime = 0; + } + } + } + else + { + /* In our implementation, it's possible that another window will receive + * WM_MOUSEMOVE and call TrackMouseEvent before TrackMouseEventProc is + * called. In such a situation, post the WM_MOUSELEAVE now. */ + if ((tracking_info.info.dwFlags & TME_LEAVE) && tracking_info.info.hwndTrack != NULL) + check_mouse_leave(hwnd, hittest); + + kill_system_timer( tracking_info.info.hwndTrack, SYSTEM_TIMER_TRACK_MOUSE ); + tracking_info.info.hwndTrack = 0; + tracking_info.info.dwFlags = 0; + tracking_info.info.dwHoverTime = 0; + + if (info->hwndTrack == hwnd) + { + /* Adding new mouse event to the tracking list */ + tracking_info.info = *info; + tracking_info.info.dwHoverTime = hover_time; + + /* Initialize HoverInfo variables even if not hover tracking */ + tracking_info.pos = pos; + + NtUserSetSystemTimer( tracking_info.info.hwndTrack, SYSTEM_TIMER_TRACK_MOUSE, hover_time ); + } + } + + return TRUE; +} + /********************************************************************** * set_capture_window */ diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 02644e71929..8ad4a0271b3 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -2479,8 +2479,7 @@ LRESULT dispatch_message( const MSG *msg, BOOL ansi ) return 0;
case SYSTEM_TIMER_TRACK_MOUSE: - if (!user_callbacks) break; - user_callbacks->update_mouse_tracking_info( msg->hwnd ); + update_mouse_tracking_info( msg->hwnd ); return 0; } } diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index 604817708c7..cad038dbff6 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -54,7 +54,6 @@ struct user_callbacks void (CDECL *toggle_caret)( HWND hwnd ); BOOL (CDECL *unpack_dde_message)( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lparam, void **buffer, size_t size ); - void (CDECL *update_mouse_tracking_info)( HWND hwnd ); BOOL (WINAPI *register_imm)( HWND hwnd ); void (WINAPI *unregister_imm)( HWND hwnd ); }; diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index aa40be5f652..265e2ca808b 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -1277,7 +1277,7 @@ @ stdcall -syscall NtUserThunkedMenuInfo(long ptr) @ stub NtUserThunkedMenuItemInfo @ stdcall NtUserToUnicodeEx(long long ptr ptr long long long) -@ stub NtUserTrackMouseEvent +@ stdcall NtUserTrackMouseEvent(ptr) @ stub NtUserTrackPopupMenuEx @ stub NtUserTransformPoint @ stub NtUserTransformRect diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 4c1b0a7b45b..d13958e8449 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -287,6 +287,7 @@ struct unix_funcs UINT winini, UINT dpi ); INT (WINAPI *pNtUserToUnicodeEx)( UINT virt, UINT scan, const BYTE *state, WCHAR *str, int size, UINT flags, HKL layout ); + BOOL (WINAPI *pNtUserTrackMouseEvent)( TRACKMOUSEEVENT *info ); BOOL (WINAPI *pNtUserTranslateMessage)( const MSG *msg, UINT flags ); BOOL (WINAPI *pNtUserUnregisterClass)( UNICODE_STRING *name, HINSTANCE instance, struct client_menu_name *client_menu_name ); @@ -357,6 +358,7 @@ extern DWORD get_input_state(void) DECLSPEC_HIDDEN; extern BOOL WINAPI release_capture(void) DECLSPEC_HIDDEN; extern BOOL set_capture_window( HWND hwnd, UINT gui_flags, HWND *prev_ret ) DECLSPEC_HIDDEN; extern BOOL set_foreground_window( HWND hwnd, BOOL mouse ) DECLSPEC_HIDDEN; +extern void update_mouse_tracking_info( HWND hwnd ) DECLSPEC_HIDDEN;
/* menu.c */ extern HMENU create_menu( BOOL is_popup ) DECLSPEC_HIDDEN; diff --git a/dlls/win32u/wrappers.c b/dlls/win32u/wrappers.c index d3497d29f03..8ac82139dd0 100644 --- a/dlls/win32u/wrappers.c +++ b/dlls/win32u/wrappers.c @@ -1210,6 +1210,12 @@ INT WINAPI NtUserToUnicodeEx( UINT virt, UINT scan, const BYTE *state, return unix_funcs->pNtUserToUnicodeEx( virt, scan, state, str, size, flags, layout ); }
+BOOL WINAPI NtUserTrackMouseEvent( TRACKMOUSEEVENT *info ) +{ + if (!unix_funcs) return FALSE; + return unix_funcs->pNtUserTrackMouseEvent( info ); +} + BOOL WINAPI NtUserTranslateMessage( const MSG *msg, UINT flags ) { if (!unix_funcs) return 0; diff --git a/include/ntuser.h b/include/ntuser.h index d06b76ab605..aa2683fc451 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -586,6 +586,7 @@ BOOL WINAPI NtUserSystemParametersInfoForDpi( UINT action, UINT val, PVOID pt BOOL WINAPI NtUserThunkedMenuInfo( HMENU menu, const MENUINFO *info ); INT WINAPI NtUserToUnicodeEx( UINT virt, UINT scan, const BYTE *state, WCHAR *str, int size, UINT flags, HKL layout ); +BOOL WINAPI NtUserTrackMouseEvent( TRACKMOUSEEVENT *info ); INT WINAPI NtUserTranslateAccelerator( HWND hwnd, HACCEL accel, MSG *msg ); BOOL WINAPI NtUserTranslateMessage( const MSG *msg, UINT flags ); BOOL WINAPI NtUserUnhookWinEvent( HWINEVENTHOOK hEventHook );
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/user32/caret.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/dlls/user32/caret.c b/dlls/user32/caret.c index bdc7780bf8f..7b21e03c764 100644 --- a/dlls/user32/caret.c +++ b/dlls/user32/caret.c @@ -96,6 +96,24 @@ void CDECL toggle_caret( HWND hwnd ) }
+static unsigned int get_caret_registry_timeout(void) +{ + unsigned int ret = 500; + WCHAR value[11]; + DWORD size; + HKEY key; + + if (RegOpenKeyExW( HKEY_CURRENT_USER, L"Control Panel\Desktop", 0, KEY_READ, &key )) + return ret; + + size = sizeof(value); + if (!RegQueryValueExW( key, L"CursorBlinkRate", NULL, NULL, (BYTE *)value, &size )) + ret = wcstoul( value, NULL, 10 ); + RegCloseKey( key ); + return ret; +} + + /***************************************************************** * CreateCaret (USER32.@) */ @@ -185,7 +203,8 @@ BOOL WINAPI CreateCaret( HWND hwnd, HBITMAP bitmap, INT width, INT height )
if (Caret.hBmp) DeleteObject( Caret.hBmp ); Caret.hBmp = hBmp; - Caret.timeout = GetProfileIntA( "windows", "CursorBlinkRate", 500 ); + + Caret.timeout = get_caret_registry_timeout(); return TRUE; }
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- This patch is unfortunately huge, but difficult to break up due to the use of a global variable.
dlls/user32/caret.c | 371 +-------------------------------- dlls/user32/edit.c | 8 +- dlls/user32/menu.c | 4 +- dlls/user32/painting.c | 4 +- dlls/user32/scroll.c | 20 +- dlls/user32/user32.spec | 10 +- dlls/user32/user_main.c | 4 - dlls/user32/user_private.h | 1 - dlls/win32u/dce.c | 4 +- dlls/win32u/gdiobj.c | 3 + dlls/win32u/input.c | 384 +++++++++++++++++++++++++++++++++++ dlls/win32u/message.c | 3 +- dlls/win32u/ntgdi_private.h | 1 - dlls/win32u/ntuser_private.h | 4 - dlls/win32u/syscall.c | 2 + dlls/win32u/sysparams.c | 9 + dlls/win32u/win32u.spec | 10 +- dlls/win32u/win32u_private.h | 10 + dlls/win32u/window.c | 13 +- dlls/win32u/wrappers.c | 18 ++ dlls/wow64win/syscall.h | 2 + dlls/wow64win/user.c | 12 ++ include/ntuser.h | 23 +++ 23 files changed, 503 insertions(+), 417 deletions(-)
diff --git a/dlls/user32/caret.c b/dlls/user32/caret.c index 7b21e03c764..9e0ff5ca48c 100644 --- a/dlls/user32/caret.c +++ b/dlls/user32/caret.c @@ -31,222 +31,12 @@ #include "wine/server.h" #include "wine/debug.h"
-WINE_DEFAULT_DEBUG_CHANNEL(caret); - -typedef struct -{ - HBITMAP hBmp; - UINT timeout; -} CARET; - -static CARET Caret = { 0, 500 }; - - -/***************************************************************** - * CARET_DisplayCaret - */ -static void CARET_DisplayCaret( HWND hwnd, const RECT *r ) -{ - HDC hdc; - HDC hCompDC; - - /* do not use DCX_CACHE here, for x,y,width,height are in logical units */ - if (!(hdc = NtUserGetDCEx( hwnd, 0, DCX_USESTYLE /*| DCX_CACHE*/ ))) return; - hCompDC = CreateCompatibleDC(hdc); - if (hCompDC) - { - HBITMAP hPrevBmp; - - hPrevBmp = SelectObject(hCompDC, Caret.hBmp); - BitBlt(hdc, r->left, r->top, r->right-r->left, r->bottom-r->top, hCompDC, 0, 0, SRCINVERT); - SelectObject(hCompDC, hPrevBmp); - DeleteDC(hCompDC); - } - NtUserReleaseDC( hwnd, hdc ); -} - - -void CDECL toggle_caret( HWND hwnd ) -{ - BOOL ret; - RECT r; - int hidden = 0; - - SERVER_START_REQ( set_caret_info ) - { - req->flags = SET_CARET_STATE; - req->handle = wine_server_user_handle( hwnd ); - req->x = 0; - req->y = 0; - req->hide = 0; - req->state = CARET_STATE_TOGGLE; - if ((ret = !wine_server_call( req ))) - { - hwnd = wine_server_ptr_handle( reply->full_handle ); - r.left = reply->old_rect.left; - r.top = reply->old_rect.top; - r.right = reply->old_rect.right; - r.bottom = reply->old_rect.bottom; - hidden = reply->old_hide; - } - } - SERVER_END_REQ; - - if (ret && !hidden) CARET_DisplayCaret( hwnd, &r ); -} - - -static unsigned int get_caret_registry_timeout(void) -{ - unsigned int ret = 500; - WCHAR value[11]; - DWORD size; - HKEY key; - - if (RegOpenKeyExW( HKEY_CURRENT_USER, L"Control Panel\Desktop", 0, KEY_READ, &key )) - return ret; - - size = sizeof(value); - if (!RegQueryValueExW( key, L"CursorBlinkRate", NULL, NULL, (BYTE *)value, &size )) - ret = wcstoul( value, NULL, 10 ); - RegCloseKey( key ); - return ret; -} - - -/***************************************************************** - * CreateCaret (USER32.@) - */ -BOOL WINAPI CreateCaret( HWND hwnd, HBITMAP bitmap, INT width, INT height ) -{ - BOOL ret; - RECT r; - int old_state = 0; - int hidden = 0; - HBITMAP hBmp = 0; - HWND prev = 0; - - TRACE("hwnd=%p\n", hwnd); - - if (!hwnd) return FALSE; - - if (bitmap && (bitmap != (HBITMAP)1)) - { - BITMAP bmp; - if (!GetObjectA( bitmap, sizeof(bmp), &bmp )) return FALSE; - width = bmp.bmWidth; - height = bmp.bmHeight; - bmp.bmBits = NULL; - hBmp = CreateBitmapIndirect(&bmp); - if (hBmp) - { - /* copy the bitmap */ - LPBYTE buf = HeapAlloc(GetProcessHeap(), 0, bmp.bmWidthBytes * bmp.bmHeight); - GetBitmapBits(bitmap, bmp.bmWidthBytes * bmp.bmHeight, buf); - SetBitmapBits(hBmp, bmp.bmWidthBytes * bmp.bmHeight, buf); - HeapFree(GetProcessHeap(), 0, buf); - } - } - else - { - HDC hdc; - - if (!width) width = GetSystemMetrics(SM_CXBORDER); - if (!height) height = GetSystemMetrics(SM_CYBORDER); - - /* create the uniform bitmap on the fly */ - hdc = GetDC(hwnd); - if (hdc) - { - HDC hMemDC = CreateCompatibleDC(hdc); - if (hMemDC) - { - if ((hBmp = CreateCompatibleBitmap(hMemDC, width, height ))) - { - HBITMAP hPrevBmp = SelectObject(hMemDC, hBmp); - SetRect( &r, 0, 0, width, height ); - FillRect(hMemDC, &r, bitmap ? GetStockObject(GRAY_BRUSH) : GetStockObject(WHITE_BRUSH)); - SelectObject(hMemDC, hPrevBmp); - } - DeleteDC(hMemDC); - } - NtUserReleaseDC(hwnd, hdc); - } - } - if (!hBmp) return FALSE; - - SERVER_START_REQ( set_caret_window ) - { - req->handle = wine_server_user_handle( hwnd ); - req->width = width; - req->height = height; - if ((ret = !wine_server_call_err( req ))) - { - prev = wine_server_ptr_handle( reply->previous ); - r.left = reply->old_rect.left; - r.top = reply->old_rect.top; - r.right = reply->old_rect.right; - r.bottom = reply->old_rect.bottom; - old_state = reply->old_state; - hidden = reply->old_hide; - } - } - SERVER_END_REQ; - if (!ret) return FALSE; - - if (prev && !hidden) /* hide the previous one */ - { - /* FIXME: won't work if prev belongs to a different process */ - KillSystemTimer( prev, SYSTEM_TIMER_CARET ); - if (old_state) CARET_DisplayCaret( prev, &r ); - } - - if (Caret.hBmp) DeleteObject( Caret.hBmp ); - Caret.hBmp = hBmp; - - Caret.timeout = get_caret_registry_timeout(); - return TRUE; -} - - /***************************************************************** * DestroyCaret (USER32.@) */ BOOL WINAPI DestroyCaret(void) { - BOOL ret; - HWND prev = 0; - RECT r; - int old_state = 0; - int hidden = 0; - - SERVER_START_REQ( set_caret_window ) - { - req->handle = 0; - req->width = 0; - req->height = 0; - if ((ret = !wine_server_call_err( req ))) - { - prev = wine_server_ptr_handle( reply->previous ); - r.left = reply->old_rect.left; - r.top = reply->old_rect.top; - r.right = reply->old_rect.right; - r.bottom = reply->old_rect.bottom; - old_state = reply->old_state; - hidden = reply->old_hide; - } - } - SERVER_END_REQ; - - if (ret && prev && !hidden) - { - /* FIXME: won't work if prev belongs to a different process */ - KillSystemTimer( prev, SYSTEM_TIMER_CARET ); - if (old_state) CARET_DisplayCaret( prev, &r ); - } - if (Caret.hBmp) DeleteObject( Caret.hBmp ); - Caret.hBmp = 0; - return ret; + return NtUserDestroyCaret(); }
@@ -255,167 +45,14 @@ BOOL WINAPI DestroyCaret(void) */ BOOL WINAPI SetCaretPos( INT x, INT y ) { - BOOL ret; - HWND hwnd = 0; - RECT r; - int old_state = 0; - int hidden = 0; - - SERVER_START_REQ( set_caret_info ) - { - req->flags = SET_CARET_POS|SET_CARET_STATE; - req->handle = 0; - req->x = x; - req->y = y; - req->hide = 0; - req->state = CARET_STATE_ON_IF_MOVED; - if ((ret = !wine_server_call_err( req ))) - { - hwnd = wine_server_ptr_handle( reply->full_handle ); - r.left = reply->old_rect.left; - r.top = reply->old_rect.top; - r.right = reply->old_rect.right; - r.bottom = reply->old_rect.bottom; - old_state = reply->old_state; - hidden = reply->old_hide; - } - } - SERVER_END_REQ; - if (ret && !hidden && (x != r.left || y != r.top)) - { - if (old_state) CARET_DisplayCaret( hwnd, &r ); - r.right += x - r.left; - r.bottom += y - r.top; - r.left = x; - r.top = y; - CARET_DisplayCaret( hwnd, &r ); - NtUserSetSystemTimer( hwnd, SYSTEM_TIMER_CARET, Caret.timeout ); - } - return ret; -} - - -/***************************************************************** - * HideCaret (USER32.@) - */ -BOOL WINAPI HideCaret( HWND hwnd ) -{ - BOOL ret; - RECT r; - int old_state = 0; - int hidden = 0; - - SERVER_START_REQ( set_caret_info ) - { - req->flags = SET_CARET_HIDE|SET_CARET_STATE; - req->handle = wine_server_user_handle( hwnd ); - req->x = 0; - req->y = 0; - req->hide = 1; - req->state = CARET_STATE_OFF; - if ((ret = !wine_server_call_err( req ))) - { - hwnd = wine_server_ptr_handle( reply->full_handle ); - r.left = reply->old_rect.left; - r.top = reply->old_rect.top; - r.right = reply->old_rect.right; - r.bottom = reply->old_rect.bottom; - old_state = reply->old_state; - hidden = reply->old_hide; - } - } - SERVER_END_REQ; - - if (ret && !hidden) - { - if (old_state) CARET_DisplayCaret( hwnd, &r ); - KillSystemTimer( hwnd, SYSTEM_TIMER_CARET ); - } - return ret; -} - - -/***************************************************************** - * ShowCaret (USER32.@) - */ -BOOL WINAPI ShowCaret( HWND hwnd ) -{ - BOOL ret; - RECT r; - int hidden = 0; - - SERVER_START_REQ( set_caret_info ) - { - req->flags = SET_CARET_HIDE|SET_CARET_STATE; - req->handle = wine_server_user_handle( hwnd ); - req->x = 0; - req->y = 0; - req->hide = -1; - req->state = CARET_STATE_ON; - if ((ret = !wine_server_call_err( req ))) - { - hwnd = wine_server_ptr_handle( reply->full_handle ); - r.left = reply->old_rect.left; - r.top = reply->old_rect.top; - r.right = reply->old_rect.right; - r.bottom = reply->old_rect.bottom; - hidden = reply->old_hide; - } - } - SERVER_END_REQ; - - if (ret && (hidden == 1)) /* hidden was 1 so it's now 0 */ - { - CARET_DisplayCaret( hwnd, &r ); - NtUserSetSystemTimer( hwnd, SYSTEM_TIMER_CARET, Caret.timeout ); - } - return ret; -} - - -/***************************************************************** - * GetCaretPos (USER32.@) - */ -BOOL WINAPI GetCaretPos( LPPOINT pt ) -{ - BOOL ret; - - SERVER_START_REQ( set_caret_info ) - { - req->flags = 0; /* don't set anything */ - req->handle = 0; - req->x = 0; - req->y = 0; - req->hide = 0; - req->state = 0; - if ((ret = !wine_server_call_err( req ))) - { - pt->x = reply->old_rect.left; - pt->y = reply->old_rect.top; - } - } - SERVER_END_REQ; - return ret; + return NtUserSetCaretPos( x, y ); }
/***************************************************************** * SetCaretBlinkTime (USER32.@) */ -BOOL WINAPI SetCaretBlinkTime( UINT msecs ) +BOOL WINAPI SetCaretBlinkTime( unsigned int time ) { - TRACE("msecs=%d\n", msecs); - - Caret.timeout = msecs; -/* if (Caret.hwnd) CARET_SetTimer(); FIXME */ - return TRUE; -} - - -/***************************************************************** - * GetCaretBlinkTime (USER32.@) - */ -UINT WINAPI GetCaretBlinkTime(void) -{ - return Caret.timeout; + return NtUserSetCaretBlinkTime( time ); } diff --git a/dlls/user32/edit.c b/dlls/user32/edit.c index 242ef4abeb2..4bf884b4140 100644 --- a/dlls/user32/edit.c +++ b/dlls/user32/edit.c @@ -3807,10 +3807,10 @@ static void EDIT_WM_SetFocus(EDITSTATE *es) NtUserReleaseDC( es->hwndSelf, hdc ); }
- CreateCaret(es->hwndSelf, 0, 1, es->line_height); + NtUserCreateCaret( es->hwndSelf, 0, 1, es->line_height ); EDIT_SetCaretPos(es, es->selection_end, es->flags & EF_AFTER_WRAP); - ShowCaret(es->hwndSelf); + NtUserShowCaret( es->hwndSelf ); EDIT_NOTIFY_PARENT(es, EN_SETFOCUS); }
@@ -3890,10 +3890,10 @@ static void EDIT_WM_SetFont(EDITSTATE *es, HFONT font, BOOL redraw) EDIT_UpdateText(es, NULL, TRUE); if (es->flags & EF_FOCUSED) { DestroyCaret(); - CreateCaret(es->hwndSelf, 0, 1, es->line_height); + NtUserCreateCaret( es->hwndSelf, 0, 1, es->line_height ); EDIT_SetCaretPos(es, es->selection_end, es->flags & EF_AFTER_WRAP); - ShowCaret(es->hwndSelf); + NtUserShowCaret( es->hwndSelf ); } }
diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c index 6fb9422cf9d..cc6c5c953e9 100644 --- a/dlls/user32/menu.c +++ b/dlls/user32/menu.c @@ -3300,7 +3300,7 @@ static BOOL MENU_InitTracking(HWND hWnd, HMENU hMenu, BOOL bPopup, UINT wFlags)
TRACE("hwnd=%p hmenu=%p\n", hWnd, hMenu);
- HideCaret(0); + NtUserHideCaret( 0 );
if (!(menu = MENU_GetMenu( hMenu ))) return FALSE;
@@ -3342,7 +3342,7 @@ static BOOL MENU_ExitTracking(HWND hWnd, BOOL bPopup) TRACE("hwnd=%p\n", hWnd);
SendMessageW( hWnd, WM_EXITMENULOOP, bPopup, 0 ); - ShowCaret(0); + NtUserShowCaret( 0 ); top_popup = 0; top_popup_hmenu = NULL; return TRUE; diff --git a/dlls/user32/painting.c b/dlls/user32/painting.c index 94e462605dd..29450e6e984 100644 --- a/dlls/user32/painting.c +++ b/dlls/user32/painting.c @@ -285,7 +285,7 @@ static INT scroll_window( HWND hwnd, INT dx, INT dy, const RECT *rect, const REC
hwndCaret = fix_caret(hwnd, &rc, dx, dy, flags, &moveCaret, &newCaretPos); if (hwndCaret) - HideCaret(hwndCaret); + NtUserHideCaret( hwndCaret );
if (is_ex) dcxflags |= DCX_CACHE; if( style & WS_CLIPSIBLINGS) dcxflags |= DCX_CLIPSIBLINGS; @@ -388,7 +388,7 @@ static INT scroll_window( HWND hwnd, INT dx, INT dy, const RECT *rect, const REC if( moveCaret ) SetCaretPos( newCaretPos.x, newCaretPos.y ); if( hwndCaret ) - ShowCaret( hwndCaret ); + NtUserShowCaret( hwndCaret );
if( bOwnRgn && hrgnUpdate ) DeleteObject( hrgnUpdate );
diff --git a/dlls/user32/scroll.c b/dlls/user32/scroll.c index 8f085364dab..efe115246f2 100644 --- a/dlls/user32/scroll.c +++ b/dlls/user32/scroll.c @@ -756,7 +756,7 @@ static void SCROLL_HandleKbdEvent(HWND hwnd, WPARAM wParam, LPARAM lParam)
/* hide caret on first KEYDOWN to prevent flicker */ if ((lParam & PFD_DOUBLEBUFFER_DONTCARE) == 0) - HideCaret(hwnd); + NtUserHideCaret( hwnd );
switch(wParam) { @@ -814,7 +814,7 @@ void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt ) switch(msg) { case WM_LBUTTONDOWN: /* Initialise mouse tracking */ - HideCaret(hwnd); /* hide caret while holding down LBUTTON */ + NtUserHideCaret( hwnd ); /* hide caret while holding down LBUTTON */ NtUserSetCapture( hwnd ); prevPt = pt; g_tracking_info.hit_test = hittest = SCROLL_THUMB; @@ -826,7 +826,7 @@ void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt ) case WM_LBUTTONUP: ReleaseCapture(); g_tracking_info.hit_test = hittest = SCROLL_NOWHERE; - if (hwnd==GetFocus()) ShowCaret(hwnd); + if (hwnd == GetFocus()) NtUserShowCaret( hwnd ); break; case WM_SYSTIMER: pt = prevPt; @@ -844,7 +844,7 @@ void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt ) switch(msg) { case WM_LBUTTONDOWN: /* Initialise mouse tracking */ - HideCaret(hwnd); /* hide caret while holding down LBUTTON */ + NtUserHideCaret( hwnd ); /* hide caret while holding down LBUTTON */ g_tracking_info.vertical = vertical; g_tracking_info.hit_test = hittest = SCROLL_HitTest( hwnd, nBar, pt, FALSE ); lastClickPos = vertical ? (pt.y - rect.top) : (pt.x - rect.left); @@ -911,7 +911,7 @@ void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt ) hittest = SCROLL_NOWHERE; ReleaseCapture(); /* if scrollbar has focus, show back caret */ - if (hwnd==GetFocus()) ShowCaret(hwnd); + if (hwnd == GetFocus()) NtUserShowCaret( hwnd ); break;
case WM_SYSTIMER: @@ -1468,7 +1468,7 @@ LRESULT WINAPI USER_ScrollBarProc( HWND hwnd, UINT message, WPARAM wParam, LPARA break;
case WM_KEYUP: - ShowCaret(hwnd); + NtUserShowCaret( hwnd ); break;
case WM_SETFOCUS: @@ -1480,15 +1480,15 @@ LRESULT WINAPI USER_ScrollBarProc( HWND hwnd, UINT message, WPARAM wParam, LPARA &arrowSize, &thumbSize, &thumbPos ); if (!vertical) { - CreateCaret(hwnd, (HBITMAP)1, thumbSize-2, rect.bottom-rect.top-2); + NtUserCreateCaret( hwnd, (HBITMAP)1, thumbSize - 2, rect.bottom - rect.top - 2 ); SetCaretPos(thumbPos+1, rect.top+1); } else { - CreateCaret(hwnd, (HBITMAP)1, rect.right-rect.left-2,thumbSize-2); + NtUserCreateCaret( hwnd, (HBITMAP)1, rect.right - rect.left - 2, thumbSize - 2); SetCaretPos(rect.top+1, thumbPos+1); } - ShowCaret(hwnd); + NtUserShowCaret( hwnd ); } break;
@@ -1506,7 +1506,7 @@ LRESULT WINAPI USER_ScrollBarProc( HWND hwnd, UINT message, WPARAM wParam, LPARA rect.top=thumbPos+1; rect.bottom=rect.top+thumbSize; } - HideCaret(hwnd); + NtUserHideCaret( hwnd ); InvalidateRect(hwnd,&rect,0); DestroyCaret(); } diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec index f7f41621812..e5510d2435b 100644 --- a/dlls/user32/user32.spec +++ b/dlls/user32/user32.spec @@ -86,7 +86,7 @@ @ stdcall CountClipboardFormats() NtUserCountClipboardFormats @ stdcall CreateAcceleratorTableA(ptr long) @ stdcall CreateAcceleratorTableW(ptr long) NtUserCreateAcceleratorTable -@ stdcall CreateCaret(long long long long) +@ stdcall CreateCaret(long long long long) NtUserCreateCaret @ stdcall CreateCursor(long long long long long ptr ptr) @ stdcall CreateDesktopA(str str ptr long long ptr) @ stdcall CreateDesktopW(wstr wstr ptr long long ptr) @@ -259,8 +259,8 @@ @ stdcall GetAutoRotationState(ptr) @ stdcall GetAwarenessFromDpiAwarenessContext(long) @ stdcall GetCapture() -@ stdcall GetCaretBlinkTime() -@ stdcall GetCaretPos(ptr) +@ stdcall GetCaretBlinkTime() NtUserGetCaretBlinkTime +@ stdcall GetCaretPos(ptr) NtUserGetCaretPos @ stdcall GetClassInfoA(long str ptr) @ stdcall GetClassInfoExA(long str ptr) @ stdcall GetClassInfoExW(long wstr ptr) @@ -425,7 +425,7 @@ @ stdcall GrayStringA(long long ptr long long long long long long) @ stdcall GrayStringW(long long ptr long long long long long long) # @ stub HasSystemSleepStarted -@ stdcall HideCaret(long) +@ stdcall HideCaret(long) NtUserHideCaret @ stdcall HiliteMenuItem(long long long long) # @ stub IMPGetIMEA # @ stub IMPGetIMEW @@ -736,7 +736,7 @@ @ stdcall SetWindowsHookExA(long long long long) @ stdcall SetWindowsHookExW(long long long long) @ stdcall SetWindowsHookW(long ptr) -@ stdcall ShowCaret(long) +@ stdcall ShowCaret(long) NtUserShowCaret @ stdcall -import ShowCursor(long) NtUserShowCursor @ stdcall ShowOwnedPopups(long long) @ stdcall ShowScrollBar(long long long) diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c index 6e0722e4750..e672c87dca4 100644 --- a/dlls/user32/user_main.c +++ b/dlls/user32/user_main.c @@ -161,13 +161,10 @@ static const struct user_callbacks user_funcs = { AdjustWindowRectEx, CopyImage, - DestroyCaret, EndMenu, - HideCaret, ImmProcessKey, ImmTranslateMessage, SetSystemMenu, - ShowCaret, free_menu_items, free_win_ptr, MENU_IsMenuActive, @@ -177,7 +174,6 @@ static const struct user_callbacks user_funcs = rawinput_device_get_usages, register_builtin_classes, SCROLL_SetStandardScrollPainted, - toggle_caret, unpack_dde_message, register_imm, unregister_imm, diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index 96c47a71753..52e57a5e6f1 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -99,7 +99,6 @@ extern HBRUSH SYSCOLOR_Get55AABrush(void) DECLSPEC_HIDDEN; extern void SYSPARAMS_Init(void) DECLSPEC_HIDDEN; extern void USER_CheckNotLock(void) DECLSPEC_HIDDEN; extern BOOL USER_IsExitingThread( DWORD tid ) DECLSPEC_HIDDEN; -extern void CDECL toggle_caret( HWND hwnd ) DECLSPEC_HIDDEN;
typedef LRESULT (*winproc_callback_t)( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp, LRESULT *result, void *arg ); diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index aa16c099d97..80f630b5614 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -1340,7 +1340,7 @@ HDC WINAPI NtUserBeginPaint( HWND hwnd, PAINTSTRUCT *ps ) RECT rect; UINT flags = UPDATE_NONCLIENT | UPDATE_ERASE | UPDATE_PAINT | UPDATE_INTERNALPAINT | UPDATE_NOCHILDREN;
- if (user_callbacks) user_callbacks->pHideCaret( hwnd ); + NtUserHideCaret( hwnd );
if (!(hrgn = send_ncpaint( hwnd, NULL, &flags ))) return 0;
@@ -1364,7 +1364,7 @@ HDC WINAPI NtUserBeginPaint( HWND hwnd, PAINTSTRUCT *ps ) */ BOOL WINAPI NtUserEndPaint( HWND hwnd, const PAINTSTRUCT *ps ) { - if (user_callbacks) user_callbacks->pShowCaret( hwnd ); + NtUserShowCaret( hwnd ); flush_window_surfaces( FALSE ); if (!ps) return FALSE; release_dc( hwnd, ps->hdc, TRUE ); diff --git a/dlls/win32u/gdiobj.c b/dlls/win32u/gdiobj.c index ed483d8f205..9edb4e9e6c0 100644 --- a/dlls/win32u/gdiobj.c +++ b/dlls/win32u/gdiobj.c @@ -1144,6 +1144,7 @@ static struct unix_funcs unix_funcs = NtUserClipCursor, NtUserCloseClipboard, NtUserCountClipboardFormats, + NtUserCreateCaret, NtUserCreateWindowEx, NtUserDeferWindowPosAndBand, NtUserDestroyCursor, @@ -1173,6 +1174,7 @@ static struct unix_funcs unix_funcs = NtUserGetUpdateRect, NtUserGetUpdateRgn, NtUserGetUpdatedClipboardFormats, + NtUserHideCaret, NtUserIsClipboardFormatAvailable, NtUserMapVirtualKeyEx, NtUserMessageCall, @@ -1207,6 +1209,7 @@ static struct unix_funcs unix_funcs = NtUserSetWindowPos, NtUserSetWindowRgn, NtUserSetWindowWord, + NtUserShowCaret, NtUserShowCursor, NtUserShowWindow, NtUserShowWindowAsync, diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index 61de034d7c8..c2563fd2132 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -2,10 +2,14 @@ * USER Input processing * * Copyright 1993 Bob Amstadt + * Copyright 1993 David Metcalfe * Copyright 1996 Albrecht Kleine + * Copyright 1996 Frans van Dorsselaer * Copyright 1997 David Faure * Copyright 1998 Morten Welinder * Copyright 1998 Ulrich Weigand + * Copyright 2001 Eric Pouech + * Copyright 2002 Alexandre Julliard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -1767,3 +1771,383 @@ BOOL set_foreground_window( HWND hwnd, BOOL mouse ) } return ret; } + +struct +{ + HBITMAP bitmap; + unsigned int timeout; +} caret = {0, 500}; + +static void display_caret( HWND hwnd, const RECT *r ) +{ + HDC dc, mem_dc; + + /* do not use DCX_CACHE here, since coördinates are in logical units */ + if (!(dc = NtUserGetDCEx( hwnd, 0, DCX_USESTYLE ))) + return; + mem_dc = NtGdiCreateCompatibleDC(dc); + if (mem_dc) + { + HBITMAP prev_bitmap; + + prev_bitmap = NtGdiSelectBitmap( mem_dc, caret.bitmap ); + NtGdiBitBlt( dc, r->left, r->top, r->right-r->left, r->bottom-r->top, mem_dc, 0, 0, SRCINVERT, 0, 0 ); + NtGdiSelectBitmap( mem_dc, prev_bitmap ); + NtGdiDeleteObjectApp( mem_dc ); + } + NtUserReleaseDC( hwnd, dc ); +} + +static void fill_rect( HDC dc, const RECT *rect, HBRUSH hbrush ) +{ + HBRUSH prev_brush; + + prev_brush = NtGdiSelectBrush( dc, hbrush ); + NtGdiPatBlt( dc, rect->left, rect->top, rect->right - rect->left, rect->bottom - rect->top, PATCOPY ); + if (prev_brush) NtGdiSelectBrush( dc, prev_brush ); +} + +static unsigned int get_caret_registry_timeout(void) +{ + char value_buffer[FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[11 * sizeof(WCHAR)])]; + KEY_VALUE_PARTIAL_INFORMATION *value = (void *)value_buffer; + unsigned int ret = 500; + HKEY key; + + if (!(key = reg_open_hkcu_key( "Control Panel\Desktop" ))) + return ret; + + if (query_reg_ascii_value( key, "CursorBlinkRate", value, sizeof(value_buffer) )) + ret = wcstoul( (WCHAR *)value->Data, NULL, 10 ); + NtClose( key ); + return ret; +} + +/***************************************************************** + * NtUserCreateCaret (win32u.@) + */ +BOOL WINAPI NtUserCreateCaret( HWND hwnd, HBITMAP bitmap, int width, int height ) +{ + HBITMAP caret_bitmap = 0; + int old_state = 0; + int hidden = 0; + HWND prev = 0; + BOOL ret; + RECT r; + + TRACE( "hwnd %p, bitmap %p, width %d, height %d\n", hwnd, bitmap, width, height ); + + if (!hwnd) return FALSE; + + if (bitmap && bitmap != (HBITMAP)1) + { + BITMAP bitmap_data; + + if (!NtGdiExtGetObjectW( bitmap, sizeof(bitmap_data), &bitmap_data )) return FALSE; + caret_bitmap = NtGdiCreateBitmap( bitmap_data.bmWidth, bitmap_data.bmHeight, + bitmap_data.bmPlanes, bitmap_data.bmBitsPixel, NULL ); + if (caret_bitmap) + { + size_t size = bitmap_data.bmWidthBytes * bitmap_data.bmHeight; + BYTE *bits = malloc( size ); + + NtGdiGetBitmapBits( bitmap, size, bits ); + NtGdiSetBitmapBits( caret_bitmap, size, bits ); + free( bits ); + } + } + else + { + HDC dc; + + if (!width) width = get_system_metrics( SM_CXBORDER ); + if (!height) height = get_system_metrics( SM_CYBORDER ); + + /* create the uniform bitmap on the fly */ + dc = NtUserGetDCEx( hwnd, 0, DCX_USESTYLE ); + if (dc) + { + HDC mem_dc = NtGdiCreateCompatibleDC( dc ); + if (mem_dc) + { + if ((caret_bitmap = NtGdiCreateCompatibleBitmap( mem_dc, width, height ))) + { + HBITMAP prev_bitmap = NtGdiSelectBitmap( mem_dc, caret_bitmap ); + SetRect( &r, 0, 0, width, height ); + fill_rect( mem_dc, &r, bitmap ? get_stock_object( GRAY_BRUSH ) : get_stock_object( WHITE_BRUSH )); + NtGdiSelectBitmap( mem_dc, prev_bitmap ); + } + NtGdiDeleteObjectApp( mem_dc ); + } + NtUserReleaseDC( hwnd, dc ); + } + } + if (!caret_bitmap) return FALSE; + + SERVER_START_REQ( set_caret_window ) + { + req->handle = wine_server_user_handle( hwnd ); + req->width = width; + req->height = height; + if ((ret = !wine_server_call_err( req ))) + { + prev = wine_server_ptr_handle( reply->previous ); + r.left = reply->old_rect.left; + r.top = reply->old_rect.top; + r.right = reply->old_rect.right; + r.bottom = reply->old_rect.bottom; + old_state = reply->old_state; + hidden = reply->old_hide; + } + } + SERVER_END_REQ; + if (!ret) return FALSE; + + if (prev && !hidden) /* hide the previous one */ + { + /* FIXME: won't work if prev belongs to a different process */ + kill_system_timer( prev, SYSTEM_TIMER_CARET ); + if (old_state) display_caret( prev, &r ); + } + + if (caret.bitmap) NtGdiDeleteObjectApp( caret.bitmap ); + caret.bitmap = caret_bitmap; + caret.timeout = get_caret_registry_timeout(); + return TRUE; +} + +/******************************************************************* + * destroy_caret + */ +BOOL destroy_caret(void) +{ + int old_state = 0; + int hidden = 0; + HWND prev = 0; + BOOL ret; + RECT r; + + SERVER_START_REQ( set_caret_window ) + { + req->handle = 0; + req->width = 0; + req->height = 0; + if ((ret = !wine_server_call_err( req ))) + { + prev = wine_server_ptr_handle( reply->previous ); + r.left = reply->old_rect.left; + r.top = reply->old_rect.top; + r.right = reply->old_rect.right; + r.bottom = reply->old_rect.bottom; + old_state = reply->old_state; + hidden = reply->old_hide; + } + } + SERVER_END_REQ; + + if (ret && prev && !hidden) + { + /* FIXME: won't work if prev belongs to a different process */ + kill_system_timer( prev, SYSTEM_TIMER_CARET ); + if (old_state) display_caret( prev, &r ); + } + if (caret.bitmap) NtGdiDeleteObjectApp( caret.bitmap ); + caret.bitmap = 0; + return ret; +} + +/***************************************************************** + * NtUserGetCaretBlinkTime (win32u.@) + */ +UINT WINAPI NtUserGetCaretBlinkTime(void) +{ + return caret.timeout; +} + +/******************************************************************* + * set_caret_blink_time + */ +BOOL set_caret_blink_time( unsigned int time ) +{ + TRACE( "time %u\n", time ); + + caret.timeout = time; + /* FIXME: update the timer */ + return TRUE; +} + +/***************************************************************** + * NtUserGetCaretPos (win32u.@) + */ +BOOL WINAPI NtUserGetCaretPos( POINT *pt ) +{ + BOOL ret; + + SERVER_START_REQ( set_caret_info ) + { + req->flags = 0; /* don't set anything */ + req->handle = 0; + req->x = 0; + req->y = 0; + req->hide = 0; + req->state = 0; + if ((ret = !wine_server_call_err( req ))) + { + pt->x = reply->old_rect.left; + pt->y = reply->old_rect.top; + } + } + SERVER_END_REQ; + return ret; +} + +/******************************************************************* + * set_caret_pos + */ +BOOL set_caret_pos( int x, int y ) +{ + int old_state = 0; + int hidden = 0; + HWND hwnd = 0; + BOOL ret; + RECT r; + + TRACE( "(%d, %d)\n", x, y ); + + SERVER_START_REQ( set_caret_info ) + { + req->flags = SET_CARET_POS|SET_CARET_STATE; + req->handle = 0; + req->x = x; + req->y = y; + req->hide = 0; + req->state = CARET_STATE_ON_IF_MOVED; + if ((ret = !wine_server_call_err( req ))) + { + hwnd = wine_server_ptr_handle( reply->full_handle ); + r.left = reply->old_rect.left; + r.top = reply->old_rect.top; + r.right = reply->old_rect.right; + r.bottom = reply->old_rect.bottom; + old_state = reply->old_state; + hidden = reply->old_hide; + } + } + SERVER_END_REQ; + if (ret && !hidden && (x != r.left || y != r.top)) + { + if (old_state) display_caret( hwnd, &r ); + r.right += x - r.left; + r.bottom += y - r.top; + r.left = x; + r.top = y; + display_caret( hwnd, &r ); + NtUserSetSystemTimer( hwnd, SYSTEM_TIMER_CARET, caret.timeout ); + } + return ret; +} + +/***************************************************************** + * NtUserShowCaret (win32u.@) + */ +BOOL WINAPI NtUserShowCaret( HWND hwnd ) +{ + int hidden = 0; + BOOL ret; + RECT r; + + SERVER_START_REQ( set_caret_info ) + { + req->flags = SET_CARET_HIDE | SET_CARET_STATE; + req->handle = wine_server_user_handle( hwnd ); + req->x = 0; + req->y = 0; + req->hide = -1; + req->state = CARET_STATE_ON; + if ((ret = !wine_server_call_err( req ))) + { + hwnd = wine_server_ptr_handle( reply->full_handle ); + r.left = reply->old_rect.left; + r.top = reply->old_rect.top; + r.right = reply->old_rect.right; + r.bottom = reply->old_rect.bottom; + hidden = reply->old_hide; + } + } + SERVER_END_REQ; + + if (ret && hidden == 1) /* hidden was 1 so it's now 0 */ + { + display_caret( hwnd, &r ); + NtUserSetSystemTimer( hwnd, SYSTEM_TIMER_CARET, caret.timeout ); + } + return ret; +} + +/***************************************************************** + * NtUserHideCaret (win32u.@) + */ +BOOL WINAPI NtUserHideCaret( HWND hwnd ) +{ + int old_state = 0; + int hidden = 0; + BOOL ret; + RECT r; + + SERVER_START_REQ( set_caret_info ) + { + req->flags = SET_CARET_HIDE | SET_CARET_STATE; + req->handle = wine_server_user_handle( hwnd ); + req->x = 0; + req->y = 0; + req->hide = 1; + req->state = CARET_STATE_OFF; + if ((ret = !wine_server_call_err( req ))) + { + hwnd = wine_server_ptr_handle( reply->full_handle ); + r.left = reply->old_rect.left; + r.top = reply->old_rect.top; + r.right = reply->old_rect.right; + r.bottom = reply->old_rect.bottom; + old_state = reply->old_state; + hidden = reply->old_hide; + } + } + SERVER_END_REQ; + + if (ret && !hidden) + { + if (old_state) display_caret( hwnd, &r ); + kill_system_timer( hwnd, SYSTEM_TIMER_CARET ); + } + return ret; +} + +void toggle_caret( HWND hwnd ) +{ + BOOL ret; + RECT r; + int hidden = 0; + + SERVER_START_REQ( set_caret_info ) + { + req->flags = SET_CARET_STATE; + req->handle = wine_server_user_handle( hwnd ); + req->x = 0; + req->y = 0; + req->hide = 0; + req->state = CARET_STATE_TOGGLE; + if ((ret = !wine_server_call( req ))) + { + hwnd = wine_server_ptr_handle( reply->full_handle ); + r.left = reply->old_rect.left; + r.top = reply->old_rect.top; + r.right = reply->old_rect.right; + r.bottom = reply->old_rect.bottom; + hidden = reply->old_hide; + } + } + SERVER_END_REQ; + + if (ret && !hidden) display_caret( hwnd, &r ); +} diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 8ad4a0271b3..d43dca723d2 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -2474,8 +2474,7 @@ LRESULT dispatch_message( const MSG *msg, BOOL ansi ) switch (msg->wParam) { case SYSTEM_TIMER_CARET: - if (!user_callbacks) break; - user_callbacks->toggle_caret( msg->hwnd ); + toggle_caret( msg->hwnd ); return 0;
case SYSTEM_TIMER_TRACK_MOUSE: diff --git a/dlls/win32u/ntgdi_private.h b/dlls/win32u/ntgdi_private.h index 6e7e24b154a..b04f7a87e34 100644 --- a/dlls/win32u/ntgdi_private.h +++ b/dlls/win32u/ntgdi_private.h @@ -381,7 +381,6 @@ extern void GDI_ReleaseObj( HGDIOBJ ) DECLSPEC_HIDDEN; extern UINT GDI_get_ref_count( HGDIOBJ handle ) DECLSPEC_HIDDEN; extern HGDIOBJ GDI_inc_ref_count( HGDIOBJ handle ) DECLSPEC_HIDDEN; extern BOOL GDI_dec_ref_count( HGDIOBJ handle ) DECLSPEC_HIDDEN; -extern HGDIOBJ get_stock_object( INT obj ) DECLSPEC_HIDDEN; extern DWORD get_gdi_object_type( HGDIOBJ obj ) DECLSPEC_HIDDEN; extern void make_gdi_object_system( HGDIOBJ handle, BOOL set ) DECLSPEC_HIDDEN;
diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index cad038dbff6..632cb16d23a 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -34,13 +34,10 @@ struct user_callbacks { BOOL (WINAPI *pAdjustWindowRectEx)( RECT *, DWORD, BOOL, DWORD ); HANDLE (WINAPI *pCopyImage)( HANDLE, UINT, INT, INT, UINT ); - BOOL (WINAPI *pDestroyCaret)(void); BOOL (WINAPI *pEndMenu)(void); - BOOL (WINAPI *pHideCaret)( HWND hwnd ); BOOL (WINAPI *pImmProcessKey)(HWND, HKL, UINT, LPARAM, DWORD); BOOL (WINAPI *pImmTranslateMessage)(HWND, UINT, WPARAM, LPARAM); BOOL (WINAPI *pSetSystemMenu)( HWND hwnd, HMENU menu ); - BOOL (WINAPI *pShowCaret)( HWND hwnd ); void (CDECL *free_menu_items)( void *ptr ); void (CDECL *free_win_ptr)( struct tagWND *win ); HWND (CDECL *is_menu_active)(void); @@ -51,7 +48,6 @@ struct user_callbacks BOOL (CDECL *rawinput_device_get_usages)(HANDLE handle, USHORT *usage_page, USHORT *usage); void (CDECL *register_builtin_classes)(void); void (WINAPI *set_standard_scroll_painted)( HWND hwnd, INT bar, BOOL visible ); - void (CDECL *toggle_caret)( HWND hwnd ); BOOL (CDECL *unpack_dde_message)( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lparam, void **buffer, size_t size ); BOOL (WINAPI *register_imm)( HWND hwnd ); diff --git a/dlls/win32u/syscall.c b/dlls/win32u/syscall.c index 0be0863b992..dc58cbe1944 100644 --- a/dlls/win32u/syscall.c +++ b/dlls/win32u/syscall.c @@ -119,6 +119,8 @@ static void * const syscalls[] = NtUserFindWindowEx, NtUserGetAncestor, NtUserGetAtomName, + NtUserGetCaretBlinkTime, + NtUserGetCaretPos, NtUserGetClassName, NtUserGetClipboardFormatName, NtUserGetClipboardOwner, diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 3b380c017e5..66a2461232c 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -4653,6 +4653,9 @@ ULONG_PTR WINAPI NtUserCallNoParam( ULONG code ) { switch(code) { + case NtUserCallNoParam_DestroyCaret: + return destroy_caret(); + case NtUserCallNoParam_GetDesktopWindow: return HandleToUlong( get_desktop_window() );
@@ -4748,6 +4751,9 @@ ULONG_PTR WINAPI NtUserCallOneParam( ULONG_PTR arg, ULONG code ) case NtUserCallOneParam_MessageBeep: return message_beep( arg );
+ case NtUserCallOneParam_SetCaretBlinkTime: + return set_caret_blink_time( arg ); + /* temporary exports */ case NtUserCallHooks: { @@ -4804,6 +4810,9 @@ ULONG_PTR WINAPI NtUserCallTwoParam( ULONG_PTR arg1, ULONG_PTR arg2, ULONG code case NtUserCallTwoParam_ReplyMessage: return reply_message_result( arg1, (MSG *)arg2 );
+ case NtUserCallTwoParam_SetCaretPos: + return set_caret_pos( arg1, arg2 ); + case NtUserCallTwoParam_SetIconParam: return set_icon_param( UlongToHandle(arg1), arg2 );
diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index 265e2ca808b..867b2a01b5f 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -807,7 +807,7 @@ @ stdcall -syscall NtUserCreateAcceleratorTable(ptr long) @ stub NtUserCreateActivationGroup @ stub NtUserCreateActivationObject -@ stub NtUserCreateCaret +@ stdcall NtUserCreateCaret(long long long long) @ stub NtUserCreateDCompositionHwndTarget @ stdcall -syscall NtUserCreateDesktopEx(ptr ptr ptr long long long) @ stub NtUserCreateEmptyCursorObject @@ -896,8 +896,8 @@ @ stub NtUserGetAutoRotationState @ stub NtUserGetCIMSSM @ stub NtUserGetCPD -@ stub NtUserGetCaretBlinkTime -@ stub NtUserGetCaretPos +@ stdcall -syscall NtUserGetCaretBlinkTime() +@ stdcall -syscall NtUserGetCaretPos(ptr) @ stdcall NtUserGetClassInfoEx(ptr ptr ptr ptr long) @ stdcall -syscall NtUserGetClassName(long long ptr) @ stub NtUserGetClipCursor @@ -1020,7 +1020,7 @@ @ stub NtUserGhostWindowFromHungWindow @ stub NtUserHandleDelegatedInput @ stub NtUserHardErrorControl -@ stub NtUserHideCaret +@ stdcall NtUserHideCaret(long) @ stub NtUserHidePointerContactVisualization @ stub NtUserHiliteMenuItem @ stub NtUserHungWindowFromGhostWindow @@ -1257,7 +1257,7 @@ @ stdcall NtUserSetWindowWord(long long long) @ stub NtUserSetWindowsHookAW @ stdcall -syscall NtUserSetWindowsHookEx(ptr ptr long long ptr long) -@ stub NtUserShowCaret +@ stdcall NtUserShowCaret(long) @ stdcall NtUserShowCursor(long) @ stub NtUserShowScrollBar @ stub NtUserShowSystemCursor diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index d13958e8449..d1d14879ea4 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -197,6 +197,7 @@ struct unix_funcs BOOL (WINAPI *pNtUserClipCursor)( const RECT *rect ); BOOL (WINAPI *pNtUserCloseClipboard)(void); INT (WINAPI *pNtUserCountClipboardFormats)(void); + BOOL (WINAPI *pNtUserCreateCaret)( HWND hwnd, HBITMAP bitmap, int width, int height ); HWND (WINAPI *pNtUserCreateWindowEx)( DWORD ex_style, UNICODE_STRING *class_name, UNICODE_STRING *version, UNICODE_STRING *window_name, DWORD style, INT x, INT y, INT width, INT height, @@ -238,6 +239,7 @@ struct unix_funcs BOOL (WINAPI *pNtUserGetUpdateRect)( HWND hwnd, RECT *rect, BOOL erase ); INT (WINAPI *pNtUserGetUpdateRgn)( HWND hwnd, HRGN hrgn, BOOL erase ); BOOL (WINAPI *pNtUserGetUpdatedClipboardFormats)( UINT *formats, UINT size, UINT *out_size ); + BOOL (WINAPI *pNtUserHideCaret)( HWND hwnd ); BOOL (WINAPI *pNtUserIsClipboardFormatAvailable)( UINT format ); UINT (WINAPI *pNtUserMapVirtualKeyEx)( UINT code, UINT type, HKL layout ); LRESULT (WINAPI *pNtUserMessageCall)( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, @@ -279,6 +281,7 @@ struct unix_funcs BOOL (WINAPI *pNtUserSetWindowPos)( HWND hwnd, HWND after, INT x, INT y, INT cx, INT cy, UINT flags ); int (WINAPI *pNtUserSetWindowRgn)( HWND hwnd, HRGN hrgn, BOOL redraw ); WORD (WINAPI *pNtUserSetWindowWord)( HWND hwnd, INT offset, WORD newval ); + BOOL (WINAPI *pNtUserShowCaret)( HWND hwnd ); INT (WINAPI *pNtUserShowCursor)( BOOL show ); BOOL (WINAPI *pNtUserShowWindow)( HWND hwnd, INT cmd ); BOOL (WINAPI *pNtUserShowWindowAsync)( HWND hwnd, INT cmd ); @@ -343,12 +346,16 @@ extern void register_window_surface( struct window_surface *old, extern LRESULT default_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, BOOL ansi ) DECLSPEC_HIDDEN;
+/* gdiobj.c */ +extern HGDIOBJ get_stock_object( INT obj ) DECLSPEC_HIDDEN; + /* hook.c */ extern LRESULT call_current_hook( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam ) DECLSPEC_HIDDEN; extern LRESULT call_hooks( INT id, INT code, WPARAM wparam, LPARAM lparam, BOOL unicode ) DECLSPEC_HIDDEN; extern BOOL unhook_windows_hook( INT id, HOOKPROC proc ) DECLSPEC_HIDDEN;
/* input.c */ +extern BOOL destroy_caret(void) DECLSPEC_HIDDEN; extern LONG global_key_state_counter DECLSPEC_HIDDEN; extern HWND get_active_window(void) DECLSPEC_HIDDEN; extern HWND get_capture(void) DECLSPEC_HIDDEN; @@ -357,7 +364,10 @@ extern HWND get_focus(void) DECLSPEC_HIDDEN; extern DWORD get_input_state(void) DECLSPEC_HIDDEN; extern BOOL WINAPI release_capture(void) DECLSPEC_HIDDEN; extern BOOL set_capture_window( HWND hwnd, UINT gui_flags, HWND *prev_ret ) DECLSPEC_HIDDEN; +extern BOOL set_caret_blink_time( unsigned int time ) DECLSPEC_HIDDEN; +extern BOOL set_caret_pos( int x, int y ) DECLSPEC_HIDDEN; extern BOOL set_foreground_window( HWND hwnd, BOOL mouse ) DECLSPEC_HIDDEN; +extern void toggle_caret( HWND hwnd ) DECLSPEC_HIDDEN; extern void update_mouse_tracking_info( HWND hwnd ) DECLSPEC_HIDDEN;
/* menu.c */ diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index a20c2886bc1..e206881e596 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -3307,13 +3307,10 @@ BOOL set_window_pos( WINDOWPOS *winpos, int parent_x, int parent_y ) &new_window_rect, &new_client_rect, valid_rects )) goto done;
- if (user_callbacks) - { - if (winpos->flags & SWP_HIDEWINDOW) - user_callbacks->pHideCaret( winpos->hwnd ); - else if (winpos->flags & SWP_SHOWWINDOW) - user_callbacks->pShowCaret( winpos->hwnd ); - } + if (winpos->flags & SWP_HIDEWINDOW) + NtUserHideCaret( winpos->hwnd ); + else if (winpos->flags & SWP_SHOWWINDOW) + NtUserShowCaret( winpos->hwnd );
if (!(winpos->flags & (SWP_NOACTIVATE|SWP_HIDEWINDOW))) { @@ -4407,7 +4404,7 @@ static void send_destroy_message( HWND hwnd ) info.cbSize = sizeof(info); if (NtUserGetGUIThreadInfo( GetCurrentThreadId(), &info )) { - if (hwnd == info.hwndCaret && user_callbacks) user_callbacks->pDestroyCaret(); + if (hwnd == info.hwndCaret) destroy_caret(); if (hwnd == info.hwndActive) activate_other_window( hwnd ); }
diff --git a/dlls/win32u/wrappers.c b/dlls/win32u/wrappers.c index 8ac82139dd0..1c1bc34a91f 100644 --- a/dlls/win32u/wrappers.c +++ b/dlls/win32u/wrappers.c @@ -780,6 +780,12 @@ INT WINAPI NtUserCountClipboardFormats(void) return unix_funcs->pNtUserCountClipboardFormats(); }
+BOOL WINAPI NtUserCreateCaret( HWND hwnd, HBITMAP bitmap, int width, int height ) +{ + if (!unix_funcs) return 0; + return unix_funcs->pNtUserCreateCaret( hwnd, bitmap, width, height ); +} + HWND WINAPI NtUserCreateWindowEx( DWORD ex_style, UNICODE_STRING *class_name, UNICODE_STRING *version, UNICODE_STRING *window_name, DWORD style, INT x, INT y, INT width, INT height, @@ -945,6 +951,12 @@ INT WINAPI NtUserGetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase ) return unix_funcs->pNtUserGetUpdateRgn( hwnd, hrgn, erase ); }
+BOOL WINAPI NtUserHideCaret( HWND hwnd ) +{ + if (!unix_funcs) return FALSE; + return unix_funcs->pNtUserHideCaret( hwnd ); +} + BOOL WINAPI NtUserMoveWindow( HWND hwnd, INT x, INT y, INT cx, INT cy, BOOL repaint ) { if (!unix_funcs) return 0; @@ -1173,6 +1185,12 @@ WORD WINAPI NtUserSetWindowWord( HWND hwnd, INT offset, WORD newval ) return unix_funcs->pNtUserSetWindowWord( hwnd, offset, newval ); }
+BOOL WINAPI NtUserShowCaret( HWND hwnd ) +{ + if (!unix_funcs) return FALSE; + return unix_funcs->pNtUserShowCaret( hwnd ); +} + INT WINAPI NtUserShowCursor( BOOL show ) { if (!unix_funcs) return 0; diff --git a/dlls/wow64win/syscall.h b/dlls/wow64win/syscall.h index 124506bdb05..1bfc210eab0 100644 --- a/dlls/wow64win/syscall.h +++ b/dlls/wow64win/syscall.h @@ -106,6 +106,8 @@ SYSCALL_ENTRY( NtUserFindWindowEx ) \ SYSCALL_ENTRY( NtUserGetAncestor ) \ SYSCALL_ENTRY( NtUserGetAtomName ) \ + SYSCALL_ENTRY( NtUserGetCaretBlinkTime ) \ + SYSCALL_ENTRY( NtUserGetCaretPos ) \ SYSCALL_ENTRY( NtUserGetClassName ) \ SYSCALL_ENTRY( NtUserGetClipboardFormatName ) \ SYSCALL_ENTRY( NtUserGetClipboardOwner ) \ diff --git a/dlls/wow64win/user.c b/dlls/wow64win/user.c index 3e8004b005c..554a6634f0e 100644 --- a/dlls/wow64win/user.c +++ b/dlls/wow64win/user.c @@ -608,6 +608,18 @@ NTSTATUS WINAPI wow64_NtUserKillTimer( UINT *args ) return NtUserKillTimer( hwnd, id ); }
+NTSTATUS WINAPI wow64_NtUserGetCaretBlinkTime( UINT *args ) +{ + return NtUserGetCaretBlinkTime(); +} + +NTSTATUS WINAPI wow64_NtUserGetCaretPos( UINT *args ) +{ + POINT *pt = get_ptr( &args ); + + return NtUserGetCaretPos( pt ); +} + NTSTATUS WINAPI wow64_NtUserCopyAcceleratorTable( UINT *args ) { HACCEL src = get_handle( &args ); diff --git a/include/ntuser.h b/include/ntuser.h index aa2683fc451..a0216df6a85 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -429,6 +429,7 @@ BOOL WINAPI NtUserCloseWindowStation( HWINSTA handle ); INT WINAPI NtUserCopyAcceleratorTable( HACCEL src, ACCEL *dst, INT count ); INT WINAPI NtUserCountClipboardFormats(void); HACCEL WINAPI NtUserCreateAcceleratorTable( ACCEL *table, INT count ); +BOOL WINAPI NtUserCreateCaret( HWND hwnd, HBITMAP bitmap, int width, int height ); HDESK WINAPI NtUserCreateDesktopEx( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *device, DEVMODEW *devmode, DWORD flags, ACCESS_MASK access, ULONG heap_size ); @@ -465,6 +466,8 @@ BOOL WINAPI NtUserFlashWindowEx( FLASHWINFO *info ); HWND WINAPI NtUserGetAncestor( HWND hwnd, UINT type ); SHORT WINAPI NtUserGetAsyncKeyState( INT key ); ULONG WINAPI NtUserGetAtomName( ATOM atom, UNICODE_STRING *name ); +UINT WINAPI NtUserGetCaretBlinkTime(void); +BOOL WINAPI NtUserGetCaretPos( POINT *point ); ATOM WINAPI NtUserGetClassInfoEx( HINSTANCE instance, UNICODE_STRING *name, WNDCLASSEXW *wc, struct client_menu_name *menu_name, BOOL ansi ); INT WINAPI NtUserGetClassName( HWND hwnd, BOOL real, UNICODE_STRING *name ); @@ -511,6 +514,7 @@ INT WINAPI NtUserGetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase ); BOOL WINAPI NtUserGetUpdatedClipboardFormats( UINT *formats, UINT size, UINT *out_size ); BOOL WINAPI NtUserGetUpdateRect( HWND hwnd, RECT *rect, BOOL erase ); int WINAPI NtUserGetWindowRgnEx( HWND hwnd, HRGN hrgn, UINT unk ); +BOOL WINAPI NtUserHideCaret( HWND hwnd ); NTSTATUS WINAPI NtUserInitializeClientPfnArrays( const struct user_client_procs *client_procsA, const struct user_client_procs *client_procsW, const void *client_workers, HINSTANCE user_module ); @@ -578,6 +582,7 @@ HHOOK WINAPI NtUserSetWindowsHookEx( HINSTANCE inst, UNICODE_STRING *module, D HWINEVENTHOOK WINAPI NtUserSetWinEventHook( DWORD event_min, DWORD event_max, HMODULE inst, UNICODE_STRING *module, WINEVENTPROC proc, DWORD pid, DWORD tid, DWORD flags ); +BOOL WINAPI NtUserShowCaret( HWND hwnd ); INT WINAPI NtUserShowCursor( BOOL show ); BOOL WINAPI NtUserShowWindow( HWND hwnd, INT cmd ); BOOL WINAPI NtUserShowWindowAsync( HWND hwnd, INT cmd ); @@ -605,6 +610,7 @@ HWND WINAPI NtUserWindowFromPoint( LONG x, LONG y ); /* NtUserCallNoParam codes, not compatible with Windows */ enum { + NtUserCallNoParam_DestroyCaret, NtUserCallNoParam_GetDesktopWindow, NtUserCallNoParam_GetInputState, NtUserCallNoParam_ReleaseCapture, @@ -614,6 +620,11 @@ enum NtUserUpdateClipboard, };
+static inline BOOL NtUserDestroyCaret(void) +{ + return NtUserCallNoParam( NtUserCallNoParam_DestroyCaret ); +} + static inline HWND NtUserGetDesktopWindow(void) { return UlongToHandle( NtUserCallNoParam( NtUserCallNoParam_GetDesktopWindow )); @@ -651,6 +662,7 @@ enum NtUserCallOneParam_IsWindowRectFullScreen, NtUserCallOneParam_MessageBeep, NtUserCallOneParam_RealizePalette, + NtUserCallOneParam_SetCaretBlinkTime, /* temporary exports */ NtUserCallHooks, NtUserGetDeskPattern, @@ -717,6 +729,11 @@ static inline RECT NtUserGetPrimaryMonitorRect(void) return primary; }
+static inline BOOL NtUserSetCaretBlinkTime( unsigned int time ) +{ + return NtUserCallOneParam( time, NtUserCallOneParam_SetCaretBlinkTime ); +} + static inline COLORREF NtUserGetSysColor( INT index ) { return NtUserCallOneParam( index, NtUserCallOneParam_GetSysColor ); @@ -767,6 +784,7 @@ enum NtUserCallTwoParam_GetSystemMetricsForDpi, NtUserCallTwoParam_MonitorFromRect, NtUserCallTwoParam_ReplyMessage, + NtUserCallTwoParam_SetCaretPos, NtUserCallTwoParam_SetIconParam, NtUserCallTwoParam_UnhookWindowsHook, /* temporary exports */ @@ -802,6 +820,11 @@ static inline BOOL NtUserReplyMessage( LRESULT result, MSG *msg ) return NtUserCallTwoParam( result, (UINT_PTR)msg, NtUserCallTwoParam_ReplyMessage ); }
+static inline BOOL NtUserSetCaretPos( int x, int y ) +{ + return NtUserCallTwoParam( x, y, NtUserCallTwoParam_SetCaretPos ); +} + static inline UINT_PTR NtUserSetIconParam( HICON icon, ULONG_PTR param ) { return NtUserCallTwoParam( HandleToUlong(icon), param, NtUserCallTwoParam_SetIconParam );
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=113367
Your paranoid android.
=== debian11 (32 bit report) ===
user32: win.c:10982: Test failed: Expected foreground window 001A0124, got 011400CE
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/user32/Makefile.in | 1 - dlls/user32/caret.c | 58 ----------------------------------------- dlls/user32/input.c | 27 +++++++++++++++++++ 3 files changed, 27 insertions(+), 59 deletions(-) delete mode 100644 dlls/user32/caret.c
diff --git a/dlls/user32/Makefile.in b/dlls/user32/Makefile.in index dd83ecec5cf..92d5c1ec1d9 100644 --- a/dlls/user32/Makefile.in +++ b/dlls/user32/Makefile.in @@ -7,7 +7,6 @@ DELAYIMPORTS = hid setupapi imm32
C_SRCS = \ button.c \ - caret.c \ class.c \ clipboard.c \ combo.c \ diff --git a/dlls/user32/caret.c b/dlls/user32/caret.c deleted file mode 100644 index 9e0ff5ca48c..00000000000 --- a/dlls/user32/caret.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Caret functions - * - * Copyright 1993 David Metcalfe - * Copyright 1996 Frans van Dorsselaer - * Copyright 2001 Eric Pouech - * Copyright 2002 Alexandre Julliard - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include <stdarg.h> - -#include "windef.h" -#include "winbase.h" -#include "wingdi.h" -#include "ntuser.h" -#include "user_private.h" -#include "wine/server.h" -#include "wine/debug.h" - -/***************************************************************** - * DestroyCaret (USER32.@) - */ -BOOL WINAPI DestroyCaret(void) -{ - return NtUserDestroyCaret(); -} - - -/***************************************************************** - * SetCaretPos (USER32.@) - */ -BOOL WINAPI SetCaretPos( INT x, INT y ) -{ - return NtUserSetCaretPos( x, y ); -} - - -/***************************************************************** - * SetCaretBlinkTime (USER32.@) - */ -BOOL WINAPI SetCaretBlinkTime( unsigned int time ) -{ - return NtUserSetCaretBlinkTime( time ); -} diff --git a/dlls/user32/input.c b/dlls/user32/input.c index dcb46df22b5..06756b5551e 100644 --- a/dlls/user32/input.c +++ b/dlls/user32/input.c @@ -162,6 +162,33 @@ HWND WINAPI GetCapture(void) }
+/***************************************************************** + * DestroyCaret (USER32.@) + */ +BOOL WINAPI DestroyCaret(void) +{ + return NtUserDestroyCaret(); +} + + +/***************************************************************** + * SetCaretPos (USER32.@) + */ +BOOL WINAPI SetCaretPos( int x, int y ) +{ + return NtUserSetCaretPos( x, y ); +} + + +/***************************************************************** + * SetCaretBlinkTime (USER32.@) + */ +BOOL WINAPI SetCaretBlinkTime( unsigned int time ) +{ + return NtUserSetCaretBlinkTime( time ); +} + + /*********************************************************************** * GetInputState (USER32.@) */