From: Zebediah Figura <zfigura(a)codeweavers.com>
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
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/ntuser_private.h | 4 -
dlls/win32u/syscall.c | 2 +
dlls/win32u/sysparams.c | 9 +
dlls/win32u/win32u.spec | 10 +-
dlls/win32u/win32u_private.h | 7 +
dlls/win32u/window.c | 13 +-
dlls/win32u/wrappers.c | 18 ++
dlls/wow64win/syscall.h | 2 +
dlls/wow64win/user.c | 12 ++
include/ntuser.h | 23 +++
22 files changed, 500 insertions(+), 416 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 )
-{
- TRACE("msecs=%d\n", msecs);
-
- Caret.timeout = msecs;
-/* if (Caret.hwnd) CARET_SetTimer(); FIXME */
- return TRUE;
-}
-
-
-/*****************************************************************
- * GetCaretBlinkTime (USER32.@)
- */
-UINT WINAPI GetCaretBlinkTime(void)
+BOOL WINAPI SetCaretBlinkTime( unsigned int time )
{
- return Caret.timeout;
+ return NtUserSetCaretBlinkTime( time );
}
diff --git a/dlls/user32/edit.c b/dlls/user32/edit.c
index f15c4c8e550..4e32a59df48 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 6f86fccdfbd..da0b7c5a1ab 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 d529e49ba3a..1258181c88a 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 8fa8af00326..f28fc66bbf2 100644
--- a/dlls/user32/user_private.h
+++ b/dlls/user32/user_private.h
@@ -101,7 +101,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 0f82d446269..c5db1bfcc30 100644
--- a/dlls/win32u/gdiobj.c
+++ b/dlls/win32u/gdiobj.c
@@ -1147,6 +1147,7 @@ static struct unix_funcs unix_funcs =
NtUserClipCursor,
NtUserCloseClipboard,
NtUserCountClipboardFormats,
+ NtUserCreateCaret,
NtUserCreateWindowEx,
NtUserDeferWindowPosAndBand,
NtUserDestroyCursor,
@@ -1178,6 +1179,7 @@ static struct unix_funcs unix_funcs =
NtUserGetUpdateRect,
NtUserGetUpdateRgn,
NtUserGetUpdatedClipboardFormats,
+ NtUserHideCaret,
NtUserIsClipboardFormatAvailable,
NtUserMapVirtualKeyEx,
NtUserMessageCall,
@@ -1214,6 +1216,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 c9d14ed746f..28fc5a918c8 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, GetStockObject( bitmap ? GRAY_BRUSH : 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/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 696fc9d922d..3cf03d68399 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() );
@@ -4744,6 +4747,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:
{
@@ -4800,6 +4806,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 e94ec7f4a39..208b167229e 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 122921431fc..caf77590559 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,
@@ -240,6 +241,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,
@@ -284,6 +286,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 );
@@ -354,6 +357,7 @@ extern LRESULT call_hooks( INT id, INT code, WPARAM wparam, LPARAM lparam, BOOL
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;
@@ -362,7 +366,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 d38501f5c4c..05107352dfa 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,
@@ -957,6 +963,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;
@@ -1197,6 +1209,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 47bc7cbeb41..f49c9bc7723 100644
--- a/include/ntuser.h
+++ b/include/ntuser.h
@@ -463,6 +463,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 );
@@ -500,6 +501,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 );
@@ -547,6 +550,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 );
@@ -616,6 +620,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 );
@@ -643,6 +648,7 @@ HWND WINAPI NtUserWindowFromPoint( LONG x, LONG y );
/* NtUserCallNoParam codes, not compatible with Windows */
enum
{
+ NtUserCallNoParam_DestroyCaret,
NtUserCallNoParam_GetDesktopWindow,
NtUserCallNoParam_GetInputState,
NtUserCallNoParam_ReleaseCapture,
@@ -651,6 +657,11 @@ enum
NtUserThreadDetach,
};
+static inline BOOL NtUserDestroyCaret(void)
+{
+ return NtUserCallNoParam( NtUserCallNoParam_DestroyCaret );
+}
+
static inline HWND NtUserGetDesktopWindow(void)
{
return UlongToHandle( NtUserCallNoParam( NtUserCallNoParam_GetDesktopWindow ));
@@ -688,6 +699,7 @@ enum
NtUserCallOneParam_IsWindowRectFullScreen,
NtUserCallOneParam_MessageBeep,
NtUserCallOneParam_RealizePalette,
+ NtUserCallOneParam_SetCaretBlinkTime,
/* temporary exports */
NtUserCallHooks,
NtUserGetDeskPattern,
@@ -754,6 +766,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 );
@@ -804,6 +821,7 @@ enum
NtUserCallTwoParam_GetSystemMetricsForDpi,
NtUserCallTwoParam_MonitorFromRect,
NtUserCallTwoParam_ReplyMessage,
+ NtUserCallTwoParam_SetCaretPos,
NtUserCallTwoParam_SetIconParam,
NtUserCallTwoParam_UnhookWindowsHook,
/* temporary exports */
@@ -839,6 +857,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 );
--
2.25.1