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
->rpdesk
->rpwinstaParent
;
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
;
76 gpsi
->dtCaretBlink
= uMSeconds
;
83 IntQueryCaretBlinkRate(VOID
)
85 UNICODE_STRING KeyName
= RTL_CONSTANT_STRING(CARET_REGKEY
);
86 UNICODE_STRING ValueName
= RTL_CONSTANT_STRING(CARET_VALUENAME
);
88 HANDLE KeyHandle
= NULL
;
89 OBJECT_ATTRIBUTES KeyAttributes
;
90 PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo
;
95 InitializeObjectAttributes(&KeyAttributes
, &KeyName
, OBJ_CASE_INSENSITIVE
,
98 Status
= ZwOpenKey(&KeyHandle
, KEY_READ
, &KeyAttributes
);
99 if(!NT_SUCCESS(Status
))
104 Status
= ZwQueryValueKey(KeyHandle
, &ValueName
, KeyValuePartialInformation
,
106 if((Status
!= STATUS_BUFFER_TOO_SMALL
))
112 ResLength
+= sizeof(KEY_VALUE_PARTIAL_INFORMATION
);
113 KeyValuePartialInfo
= ExAllocatePoolWithTag(PagedPool
, ResLength
, TAG_STRING
);
116 if(!KeyValuePartialInfo
)
122 Status
= ZwQueryValueKey(KeyHandle
, &ValueName
, KeyValuePartialInformation
,
123 (PVOID
)KeyValuePartialInfo
, Length
, &ResLength
);
124 if(!NT_SUCCESS(Status
) || (KeyValuePartialInfo
->Type
!= REG_SZ
))
127 ExFreePoolWithTag(KeyValuePartialInfo
, TAG_STRING
);
131 ValueName
.Length
= KeyValuePartialInfo
->DataLength
;
132 ValueName
.MaximumLength
= KeyValuePartialInfo
->DataLength
;
133 ValueName
.Buffer
= (PWSTR
)KeyValuePartialInfo
->Data
;
135 Status
= RtlUnicodeStringToInteger(&ValueName
, 0, &Val
);
136 if(!NT_SUCCESS(Status
))
141 ExFreePoolWithTag(KeyValuePartialInfo
, TAG_STRING
);
149 IntGetCaretBlinkTime(VOID
)
152 PWINSTATION_OBJECT WinStaObject
;
155 pti
= PsGetCurrentThreadWin32Thread();
156 WinStaObject
= pti
->rpdesk
->rpwinstaParent
;
158 Ret
= WinStaObject
->CaretBlinkRate
;
161 /* load it from the registry the first call only! */
162 Ret
= WinStaObject
->CaretBlinkRate
= IntQueryCaretBlinkRate();
165 /* windows doesn't do this check */
166 if((Ret
< MIN_CARETBLINKRATE
) || (Ret
> MAX_CARETBLINKRATE
))
168 Ret
= DEFAULT_CARETBLINKRATE
;
176 co_IntSetCaretPos(int X
, int Y
)
179 PUSER_MESSAGE_QUEUE ThreadQueue
;
181 pti
= PsGetCurrentThreadWin32Thread();
182 ThreadQueue
= pti
->MessageQueue
;
184 if(ThreadQueue
->CaretInfo
->hWnd
)
186 if(ThreadQueue
->CaretInfo
->Pos
.x
!= X
|| ThreadQueue
->CaretInfo
->Pos
.y
!= Y
)
188 co_IntHideCaret(ThreadQueue
->CaretInfo
);
189 ThreadQueue
->CaretInfo
->Showing
= 0;
190 ThreadQueue
->CaretInfo
->Pos
.x
= X
;
191 ThreadQueue
->CaretInfo
->Pos
.y
= Y
;
192 co_IntSendMessage(ThreadQueue
->CaretInfo
->hWnd
, WM_SYSTIMER
, IDCARETTIMER
, 0);
193 IntSetTimer(UserGetWindowObject(ThreadQueue
->CaretInfo
->hWnd
), IDCARETTIMER
, IntGetCaretBlinkTime(), NULL
, TMRF_SYSTEM
);
202 IntSwitchCaretShowing(PVOID Info
)
205 PUSER_MESSAGE_QUEUE ThreadQueue
;
207 pti
= PsGetCurrentThreadWin32Thread();
208 ThreadQueue
= pti
->MessageQueue
;
210 if(ThreadQueue
->CaretInfo
->hWnd
)
212 ThreadQueue
->CaretInfo
->Showing
= (ThreadQueue
->CaretInfo
->Showing
? 0 : 1);
213 MmCopyToCaller(Info
, ThreadQueue
->CaretInfo
, sizeof(THRDCARETINFO
));
223 co_IntDrawCaret(HWND hWnd
)
226 PUSER_MESSAGE_QUEUE ThreadQueue
;
228 pti
= PsGetCurrentThreadWin32Thread();
229 ThreadQueue
= pti
->MessageQueue
;
231 if(ThreadQueue
->CaretInfo
->hWnd
&& ThreadQueue
->CaretInfo
->Visible
&&
232 ThreadQueue
->CaretInfo
->Showing
)
234 co_IntSendMessage(ThreadQueue
->CaretInfo
->hWnd
, WM_SYSTIMER
, IDCARETTIMER
, 0);
235 ThreadQueue
->CaretInfo
->Showing
= 1;
242 BOOL FASTCALL
co_UserHideCaret(PWND Window OPTIONAL
)
245 PUSER_MESSAGE_QUEUE ThreadQueue
;
247 if (Window
) ASSERT_REFS_CO(Window
);
249 if(Window
&& Window
->head
.pti
->pEThread
!= PsGetCurrentThread())
251 SetLastWin32Error(ERROR_ACCESS_DENIED
);
255 pti
= PsGetCurrentThreadWin32Thread();
256 ThreadQueue
= pti
->MessageQueue
;
258 if(Window
&& ThreadQueue
->CaretInfo
->hWnd
!= Window
->head
.h
)
260 SetLastWin32Error(ERROR_ACCESS_DENIED
);
264 if(ThreadQueue
->CaretInfo
->Visible
)
266 IntKillTimer(ThreadQueue
->CaretInfo
->hWnd
, IDCARETTIMER
, TRUE
);
268 co_IntHideCaret(ThreadQueue
->CaretInfo
);
269 ThreadQueue
->CaretInfo
->Visible
= 0;
270 ThreadQueue
->CaretInfo
->Showing
= 0;
277 BOOL FASTCALL
co_UserShowCaret(PWND Window OPTIONAL
)
280 PUSER_MESSAGE_QUEUE ThreadQueue
;
282 if (Window
) ASSERT_REFS_CO(Window
);
284 if(Window
&& Window
->head
.pti
->pEThread
!= PsGetCurrentThread())
286 SetLastWin32Error(ERROR_ACCESS_DENIED
);
290 pti
= PsGetCurrentThreadWin32Thread();
291 ThreadQueue
= pti
->MessageQueue
;
293 if(Window
&& ThreadQueue
->CaretInfo
->hWnd
!= Window
->head
.h
)
295 SetLastWin32Error(ERROR_ACCESS_DENIED
);
299 if(!ThreadQueue
->CaretInfo
->Visible
)
301 ThreadQueue
->CaretInfo
->Visible
= 1;
302 if(!ThreadQueue
->CaretInfo
->Showing
)
304 co_IntSendMessage(ThreadQueue
->CaretInfo
->hWnd
, WM_SYSTIMER
, IDCARETTIMER
, 0);
306 IntSetTimer(UserGetWindowObject(ThreadQueue
->CaretInfo
->hWnd
), IDCARETTIMER
, IntGetCaretBlinkTime(), NULL
, TMRF_SYSTEM
);
313 /* SYSCALLS *****************************************************************/
325 PUSER_MESSAGE_QUEUE ThreadQueue
;
326 DECLARE_RETURN(BOOL
);
328 DPRINT("Enter NtUserCreateCaret\n");
329 UserEnterExclusive();
331 if(!(Window
= UserGetWindowObject(hWnd
)))
336 if(Window
->head
.pti
->pEThread
!= PsGetCurrentThread())
338 SetLastWin32Error(ERROR_ACCESS_DENIED
);
342 pti
= PsGetCurrentThreadWin32Thread();
343 ThreadQueue
= pti
->MessageQueue
;
345 if (ThreadQueue
->CaretInfo
->Visible
)
347 IntKillTimer(hWnd
, IDCARETTIMER
, TRUE
);
348 co_IntHideCaret(ThreadQueue
->CaretInfo
);
351 ThreadQueue
->CaretInfo
->hWnd
= hWnd
;
354 ThreadQueue
->CaretInfo
->Bitmap
= hBitmap
;
355 ThreadQueue
->CaretInfo
->Size
.cx
= ThreadQueue
->CaretInfo
->Size
.cy
= 0;
361 nWidth
= UserGetSystemMetrics(SM_CXBORDER
);
365 nHeight
= UserGetSystemMetrics(SM_CYBORDER
);
367 ThreadQueue
->CaretInfo
->Bitmap
= (HBITMAP
)0;
368 ThreadQueue
->CaretInfo
->Size
.cx
= nWidth
;
369 ThreadQueue
->CaretInfo
->Size
.cy
= nHeight
;
371 ThreadQueue
->CaretInfo
->Visible
= 0;
372 ThreadQueue
->CaretInfo
->Showing
= 0;
377 DPRINT("Leave NtUserCreateCaret, ret=%i\n",_ret_
);
384 NtUserGetCaretBlinkTime(VOID
)
386 DECLARE_RETURN(UINT
);
388 DPRINT("Enter NtUserGetCaretBlinkTime\n");
391 RETURN(IntGetCaretBlinkTime());
394 DPRINT("Leave NtUserGetCaretBlinkTime, ret=%i\n",_ret_
);
405 PUSER_MESSAGE_QUEUE ThreadQueue
;
407 DECLARE_RETURN(BOOL
);
409 DPRINT("Enter NtUserGetCaretPos\n");
412 pti
= PsGetCurrentThreadWin32Thread();
413 ThreadQueue
= pti
->MessageQueue
;
415 Status
= MmCopyToCaller(lpPoint
, &(ThreadQueue
->CaretInfo
->Pos
), sizeof(POINT
));
416 if(!NT_SUCCESS(Status
))
418 SetLastNtError(Status
);
425 DPRINT("Leave NtUserGetCaretPos, ret=%i\n",_ret_
);
432 NtUserShowCaret(HWND hWnd OPTIONAL
)
435 USER_REFERENCE_ENTRY Ref
;
436 DECLARE_RETURN(BOOL
);
439 DPRINT("Enter NtUserShowCaret\n");
440 UserEnterExclusive();
442 if(hWnd
&& !(Window
= UserGetWindowObject(hWnd
)))
447 if (Window
) UserRefObjectCo(Window
, &Ref
);
449 ret
= co_UserShowCaret(Window
);
451 if (Window
) UserDerefObjectCo(Window
);
456 DPRINT("Leave NtUserShowCaret, ret=%i\n",_ret_
);
463 NtUserHideCaret(HWND hWnd OPTIONAL
)
466 USER_REFERENCE_ENTRY Ref
;
467 DECLARE_RETURN(BOOL
);
470 DPRINT("Enter NtUserHideCaret\n");
471 UserEnterExclusive();
473 if(hWnd
&& !(Window
= UserGetWindowObject(hWnd
)))
478 if (Window
) UserRefObjectCo(Window
, &Ref
);
480 ret
= co_UserHideCaret(Window
);
482 if (Window
) UserDerefObjectCo(Window
);
487 DPRINT("Leave NtUserHideCaret, ret=%i\n",_ret_
);