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
->OwnerThread
!= 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
->OwnerThread
!= 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
->OwnerThread
!= 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;
358 ThreadQueue
->CaretInfo
->Bitmap
= (HBITMAP
)0;
359 ThreadQueue
->CaretInfo
->Size
.cx
= nWidth
;
360 ThreadQueue
->CaretInfo
->Size
.cy
= nHeight
;
362 ThreadQueue
->CaretInfo
->Visible
= 0;
363 ThreadQueue
->CaretInfo
->Showing
= 0;
368 DPRINT("Leave NtUserCreateCaret, ret=%i\n",_ret_
);
375 NtUserGetCaretBlinkTime(VOID
)
377 DECLARE_RETURN(UINT
);
379 DPRINT("Enter NtUserGetCaretBlinkTime\n");
382 RETURN(IntGetCaretBlinkTime());
385 DPRINT("Leave NtUserGetCaretBlinkTime, ret=%i\n",_ret_
);
396 PUSER_MESSAGE_QUEUE ThreadQueue
;
398 DECLARE_RETURN(BOOL
);
400 DPRINT("Enter NtUserGetCaretPos\n");
403 pti
= PsGetCurrentThreadWin32Thread();
404 ThreadQueue
= pti
->MessageQueue
;
406 Status
= MmCopyToCaller(lpPoint
, &(ThreadQueue
->CaretInfo
->Pos
), sizeof(POINT
));
407 if(!NT_SUCCESS(Status
))
409 SetLastNtError(Status
);
416 DPRINT("Leave NtUserGetCaretPos, ret=%i\n",_ret_
);
423 NtUserShowCaret(HWND hWnd OPTIONAL
)
425 PWINDOW_OBJECT Window
= NULL
;
426 USER_REFERENCE_ENTRY Ref
;
427 DECLARE_RETURN(BOOL
);
430 DPRINT("Enter NtUserShowCaret\n");
431 UserEnterExclusive();
433 if(hWnd
&& !(Window
= UserGetWindowObject(hWnd
)))
438 if (Window
) UserRefObjectCo(Window
, &Ref
);
440 ret
= co_UserShowCaret(Window
);
442 if (Window
) UserDerefObjectCo(Window
);
447 DPRINT("Leave NtUserShowCaret, ret=%i\n",_ret_
);
454 NtUserHideCaret(HWND hWnd OPTIONAL
)
456 PWINDOW_OBJECT Window
= NULL
;
457 USER_REFERENCE_ENTRY Ref
;
458 DECLARE_RETURN(BOOL
);
461 DPRINT("Enter NtUserHideCaret\n");
462 UserEnterExclusive();
464 if(hWnd
&& !(Window
= UserGetWindowObject(hWnd
)))
469 if (Window
) UserRefObjectCo(Window
, &Ref
);
471 ret
= co_UserHideCaret(Window
);
473 if (Window
) UserDerefObjectCo(Window
);
478 DPRINT("Leave NtUserHideCaret, ret=%i\n",_ret_
);