3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * PURPOSE: Caret functions
6 * FILE: subsys/win32k/ntuser/caret.c
7 * PROGRAMER: Thomas Weidenmueller (w3seek@users.sourceforge.net)
12 /* INCLUDES ******************************************************************/
19 /* DEFINES *****************************************************************/
21 #define MIN_CARETBLINKRATE 100
22 #define MAX_CARETBLINKRATE 10000
23 #define DEFAULT_CARETBLINKRATE 530
24 #define CARET_REGKEY L"\\Registry\\User\\.Default\\Control Panel\\Desktop"
25 #define CARET_VALUENAME L"CursorBlinkRate"
27 /* FUNCTIONS *****************************************************************/
31 co_IntHideCaret(PTHRDCARETINFO CaretInfo
)
33 if(CaretInfo
->hWnd
&& CaretInfo
->Visible
&& CaretInfo
->Showing
)
35 co_IntSendMessage(CaretInfo
->hWnd
, WM_SYSTIMER
, IDCARETTIMER
, 0);
36 CaretInfo
->Showing
= 0;
43 co_IntDestroyCaret(PTHREADINFO Win32Thread
)
45 PUSER_MESSAGE_QUEUE ThreadQueue
;
46 ThreadQueue
= (PUSER_MESSAGE_QUEUE
)Win32Thread
->MessageQueue
;
48 if(!ThreadQueue
|| !ThreadQueue
->CaretInfo
)
51 co_IntHideCaret(ThreadQueue
->CaretInfo
);
52 ThreadQueue
->CaretInfo
->Bitmap
= (HBITMAP
)0;
53 ThreadQueue
->CaretInfo
->hWnd
= (HWND
)0;
54 ThreadQueue
->CaretInfo
->Size
.cx
= ThreadQueue
->CaretInfo
->Size
.cy
= 0;
55 ThreadQueue
->CaretInfo
->Showing
= 0;
56 ThreadQueue
->CaretInfo
->Visible
= 0;
61 IntSetCaretBlinkTime(UINT uMSeconds
)
63 /* Don't save the new value to the registry! */
64 PTHREADINFO pti
= PsGetCurrentThreadWin32Thread();
65 PWINSTATION_OBJECT WinStaObject
= pti
->Desktop
->WindowStation
;
67 /* windows doesn't do this check */
68 if((uMSeconds
< MIN_CARETBLINKRATE
) || (uMSeconds
> MAX_CARETBLINKRATE
))
70 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
71 ObDereferenceObject(WinStaObject
);
75 WinStaObject
->CaretBlinkRate
= uMSeconds
;
82 IntQueryCaretBlinkRate(VOID
)
84 UNICODE_STRING KeyName
= RTL_CONSTANT_STRING(CARET_REGKEY
);
85 UNICODE_STRING ValueName
= RTL_CONSTANT_STRING(CARET_VALUENAME
);
87 HANDLE KeyHandle
= NULL
;
88 OBJECT_ATTRIBUTES KeyAttributes
;
89 PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo
;
94 InitializeObjectAttributes(&KeyAttributes
, &KeyName
, OBJ_CASE_INSENSITIVE
,
97 Status
= ZwOpenKey(&KeyHandle
, KEY_READ
, &KeyAttributes
);
98 if(!NT_SUCCESS(Status
))
103 Status
= ZwQueryValueKey(KeyHandle
, &ValueName
, KeyValuePartialInformation
,
105 if((Status
!= STATUS_BUFFER_TOO_SMALL
))
111 ResLength
+= sizeof(KEY_VALUE_PARTIAL_INFORMATION
);
112 KeyValuePartialInfo
= ExAllocatePoolWithTag(PagedPool
, ResLength
, TAG_STRING
);
115 if(!KeyValuePartialInfo
)
121 Status
= ZwQueryValueKey(KeyHandle
, &ValueName
, KeyValuePartialInformation
,
122 (PVOID
)KeyValuePartialInfo
, Length
, &ResLength
);
123 if(!NT_SUCCESS(Status
) || (KeyValuePartialInfo
->Type
!= REG_SZ
))
126 ExFreePoolWithTag(KeyValuePartialInfo
, TAG_STRING
);
130 ValueName
.Length
= KeyValuePartialInfo
->DataLength
;
131 ValueName
.MaximumLength
= KeyValuePartialInfo
->DataLength
;
132 ValueName
.Buffer
= (PWSTR
)KeyValuePartialInfo
->Data
;
134 Status
= RtlUnicodeStringToInteger(&ValueName
, 0, &Val
);
135 if(!NT_SUCCESS(Status
))
140 ExFreePoolWithTag(KeyValuePartialInfo
, TAG_STRING
);
148 IntGetCaretBlinkTime(VOID
)
151 PWINSTATION_OBJECT WinStaObject
;
154 pti
= PsGetCurrentThreadWin32Thread();
155 WinStaObject
= pti
->Desktop
->WindowStation
;
157 Ret
= WinStaObject
->CaretBlinkRate
;
160 /* load it from the registry the first call only! */
161 Ret
= WinStaObject
->CaretBlinkRate
= IntQueryCaretBlinkRate();
164 /* windows doesn't do this check */
165 if((Ret
< MIN_CARETBLINKRATE
) || (Ret
> MAX_CARETBLINKRATE
))
167 Ret
= DEFAULT_CARETBLINKRATE
;
175 co_IntSetCaretPos(int X
, int Y
)
178 PUSER_MESSAGE_QUEUE ThreadQueue
;
180 pti
= PsGetCurrentThreadWin32Thread();
181 ThreadQueue
= pti
->MessageQueue
;
183 if(ThreadQueue
->CaretInfo
->hWnd
)
185 if(ThreadQueue
->CaretInfo
->Pos
.x
!= X
|| ThreadQueue
->CaretInfo
->Pos
.y
!= Y
)
187 co_IntHideCaret(ThreadQueue
->CaretInfo
);
188 ThreadQueue
->CaretInfo
->Showing
= 0;
189 ThreadQueue
->CaretInfo
->Pos
.x
= X
;
190 ThreadQueue
->CaretInfo
->Pos
.y
= Y
;
191 co_IntSendMessage(ThreadQueue
->CaretInfo
->hWnd
, WM_SYSTIMER
, IDCARETTIMER
, 0);
192 IntSetTimer(ThreadQueue
->CaretInfo
->hWnd
, IDCARETTIMER
, IntGetCaretBlinkTime(), NULL
, TRUE
);
201 IntSwitchCaretShowing(PVOID Info
)
204 PUSER_MESSAGE_QUEUE ThreadQueue
;
206 pti
= PsGetCurrentThreadWin32Thread();
207 ThreadQueue
= pti
->MessageQueue
;
209 if(ThreadQueue
->CaretInfo
->hWnd
)
211 ThreadQueue
->CaretInfo
->Showing
= (ThreadQueue
->CaretInfo
->Showing
? 0 : 1);
212 MmCopyToCaller(Info
, ThreadQueue
->CaretInfo
, sizeof(THRDCARETINFO
));
222 co_IntDrawCaret(HWND hWnd
)
225 PUSER_MESSAGE_QUEUE ThreadQueue
;
227 pti
= PsGetCurrentThreadWin32Thread();
228 ThreadQueue
= pti
->MessageQueue
;
230 if(ThreadQueue
->CaretInfo
->hWnd
&& ThreadQueue
->CaretInfo
->Visible
&&
231 ThreadQueue
->CaretInfo
->Showing
)
233 co_IntSendMessage(ThreadQueue
->CaretInfo
->hWnd
, WM_SYSTIMER
, IDCARETTIMER
, 0);
234 ThreadQueue
->CaretInfo
->Showing
= 1;
241 BOOL FASTCALL
co_UserHideCaret(PWINDOW_OBJECT Window OPTIONAL
)
244 PUSER_MESSAGE_QUEUE ThreadQueue
;
246 if (Window
) ASSERT_REFS_CO(Window
);
248 if(Window
&& Window
->pti
->pEThread
!= PsGetCurrentThread())
250 SetLastWin32Error(ERROR_ACCESS_DENIED
);
254 pti
= PsGetCurrentThreadWin32Thread();
255 ThreadQueue
= pti
->MessageQueue
;
257 if(Window
&& ThreadQueue
->CaretInfo
->hWnd
!= Window
->hSelf
)
259 SetLastWin32Error(ERROR_ACCESS_DENIED
);
263 if(ThreadQueue
->CaretInfo
->Visible
)
265 IntKillTimer(ThreadQueue
->CaretInfo
->hWnd
, IDCARETTIMER
, TRUE
);
267 co_IntHideCaret(ThreadQueue
->CaretInfo
);
268 ThreadQueue
->CaretInfo
->Visible
= 0;
269 ThreadQueue
->CaretInfo
->Showing
= 0;
276 BOOL FASTCALL
co_UserShowCaret(PWINDOW_OBJECT Window OPTIONAL
)
279 PUSER_MESSAGE_QUEUE ThreadQueue
;
281 if (Window
) ASSERT_REFS_CO(Window
);
283 if(Window
&& Window
->pti
->pEThread
!= PsGetCurrentThread())
285 SetLastWin32Error(ERROR_ACCESS_DENIED
);
289 pti
= PsGetCurrentThreadWin32Thread();
290 ThreadQueue
= pti
->MessageQueue
;
292 if(Window
&& ThreadQueue
->CaretInfo
->hWnd
!= Window
->hSelf
)
294 SetLastWin32Error(ERROR_ACCESS_DENIED
);
298 if(!ThreadQueue
->CaretInfo
->Visible
)
300 ThreadQueue
->CaretInfo
->Visible
= 1;
301 if(!ThreadQueue
->CaretInfo
->Showing
)
303 co_IntSendMessage(ThreadQueue
->CaretInfo
->hWnd
, WM_SYSTIMER
, IDCARETTIMER
, 0);
305 IntSetTimer(ThreadQueue
->CaretInfo
->hWnd
, IDCARETTIMER
, IntGetCaretBlinkTime(), NULL
, TRUE
);
312 /* SYSCALLS *****************************************************************/
322 PWINDOW_OBJECT Window
;
324 PUSER_MESSAGE_QUEUE ThreadQueue
;
325 DECLARE_RETURN(BOOL
);
327 DPRINT("Enter NtUserCreateCaret\n");
328 UserEnterExclusive();
330 if(!(Window
= UserGetWindowObject(hWnd
)))
335 if(Window
->pti
->pEThread
!= PsGetCurrentThread())
337 SetLastWin32Error(ERROR_ACCESS_DENIED
);
341 pti
= PsGetCurrentThreadWin32Thread();
342 ThreadQueue
= pti
->MessageQueue
;
344 if (ThreadQueue
->CaretInfo
->Visible
)
346 IntKillTimer(hWnd
, IDCARETTIMER
, TRUE
);
347 co_IntHideCaret(ThreadQueue
->CaretInfo
);
350 ThreadQueue
->CaretInfo
->hWnd
= hWnd
;
353 ThreadQueue
->CaretInfo
->Bitmap
= hBitmap
;
354 ThreadQueue
->CaretInfo
->Size
.cx
= ThreadQueue
->CaretInfo
->Size
.cy
= 0;
360 nWidth
= UserGetSystemMetrics(SM_CXBORDER
);
364 nHeight
= UserGetSystemMetrics(SM_CYBORDER
);
366 ThreadQueue
->CaretInfo
->Bitmap
= (HBITMAP
)0;
367 ThreadQueue
->CaretInfo
->Size
.cx
= nWidth
;
368 ThreadQueue
->CaretInfo
->Size
.cy
= nHeight
;
370 ThreadQueue
->CaretInfo
->Visible
= 0;
371 ThreadQueue
->CaretInfo
->Showing
= 0;
376 DPRINT("Leave NtUserCreateCaret, ret=%i\n",_ret_
);
383 NtUserGetCaretBlinkTime(VOID
)
385 DECLARE_RETURN(UINT
);
387 DPRINT("Enter NtUserGetCaretBlinkTime\n");
390 RETURN(IntGetCaretBlinkTime());
393 DPRINT("Leave NtUserGetCaretBlinkTime, ret=%i\n",_ret_
);
404 PUSER_MESSAGE_QUEUE ThreadQueue
;
406 DECLARE_RETURN(BOOL
);
408 DPRINT("Enter NtUserGetCaretPos\n");
411 pti
= PsGetCurrentThreadWin32Thread();
412 ThreadQueue
= pti
->MessageQueue
;
414 Status
= MmCopyToCaller(lpPoint
, &(ThreadQueue
->CaretInfo
->Pos
), sizeof(POINT
));
415 if(!NT_SUCCESS(Status
))
417 SetLastNtError(Status
);
424 DPRINT("Leave NtUserGetCaretPos, ret=%i\n",_ret_
);
431 NtUserShowCaret(HWND hWnd OPTIONAL
)
433 PWINDOW_OBJECT Window
= NULL
;
434 USER_REFERENCE_ENTRY Ref
;
435 DECLARE_RETURN(BOOL
);
438 DPRINT("Enter NtUserShowCaret\n");
439 UserEnterExclusive();
441 if(hWnd
&& !(Window
= UserGetWindowObject(hWnd
)))
446 if (Window
) UserRefObjectCo(Window
, &Ref
);
448 ret
= co_UserShowCaret(Window
);
450 if (Window
) UserDerefObjectCo(Window
);
455 DPRINT("Leave NtUserShowCaret, ret=%i\n",_ret_
);
462 NtUserHideCaret(HWND hWnd OPTIONAL
)
464 PWINDOW_OBJECT Window
= NULL
;
465 USER_REFERENCE_ENTRY Ref
;
466 DECLARE_RETURN(BOOL
);
469 DPRINT("Enter NtUserHideCaret\n");
470 UserEnterExclusive();
472 if(hWnd
&& !(Window
= UserGetWindowObject(hWnd
)))
477 if (Window
) UserRefObjectCo(Window
, &Ref
);
479 ret
= co_UserHideCaret(Window
);
481 if (Window
) UserDerefObjectCo(Window
);
486 DPRINT("Leave NtUserHideCaret, ret=%i\n",_ret_
);