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(PW32THREAD 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 PWINSTATION_OBJECT WinStaObject
= PsGetWin32Thread()->Desktop
->WindowStation
;
66 /* windows doesn't do this check */
67 if((uMSeconds
< MIN_CARETBLINKRATE
) || (uMSeconds
> MAX_CARETBLINKRATE
))
69 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
70 ObDereferenceObject(WinStaObject
);
74 WinStaObject
->CaretBlinkRate
= uMSeconds
;
81 IntQueryCaretBlinkRate(VOID
)
83 UNICODE_STRING KeyName
= RTL_CONSTANT_STRING(CARET_REGKEY
);
84 UNICODE_STRING ValueName
= RTL_CONSTANT_STRING(CARET_VALUENAME
);
86 HANDLE KeyHandle
= NULL
;
87 OBJECT_ATTRIBUTES KeyAttributes
;
88 PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo
;
93 InitializeObjectAttributes(&KeyAttributes
, &KeyName
, OBJ_CASE_INSENSITIVE
,
96 Status
= ZwOpenKey(&KeyHandle
, KEY_READ
, &KeyAttributes
);
97 if(!NT_SUCCESS(Status
))
102 Status
= ZwQueryValueKey(KeyHandle
, &ValueName
, KeyValuePartialInformation
,
104 if((Status
!= STATUS_BUFFER_TOO_SMALL
))
110 ResLength
+= sizeof(KEY_VALUE_PARTIAL_INFORMATION
);
111 KeyValuePartialInfo
= ExAllocatePoolWithTag(PagedPool
, ResLength
, TAG_STRING
);
114 if(!KeyValuePartialInfo
)
120 Status
= ZwQueryValueKey(KeyHandle
, &ValueName
, KeyValuePartialInformation
,
121 (PVOID
)KeyValuePartialInfo
, Length
, &ResLength
);
122 if(!NT_SUCCESS(Status
) || (KeyValuePartialInfo
->Type
!= REG_SZ
))
125 ExFreePool(KeyValuePartialInfo
);
129 ValueName
.Length
= KeyValuePartialInfo
->DataLength
;
130 ValueName
.MaximumLength
= KeyValuePartialInfo
->DataLength
;
131 ValueName
.Buffer
= (PWSTR
)KeyValuePartialInfo
->Data
;
133 Status
= RtlUnicodeStringToInteger(&ValueName
, 0, &Val
);
134 if(!NT_SUCCESS(Status
))
139 ExFreePool(KeyValuePartialInfo
);
147 IntGetCaretBlinkTime(VOID
)
149 PWINSTATION_OBJECT WinStaObject
;
152 WinStaObject
= PsGetWin32Thread()->Desktop
->WindowStation
;
154 Ret
= WinStaObject
->CaretBlinkRate
;
157 /* load it from the registry the first call only! */
158 Ret
= WinStaObject
->CaretBlinkRate
= IntQueryCaretBlinkRate();
161 /* windows doesn't do this check */
162 if((Ret
< MIN_CARETBLINKRATE
) || (Ret
> MAX_CARETBLINKRATE
))
164 Ret
= DEFAULT_CARETBLINKRATE
;
172 co_IntSetCaretPos(int X
, int Y
)
174 PUSER_MESSAGE_QUEUE ThreadQueue
;
175 ThreadQueue
= (PUSER_MESSAGE_QUEUE
)PsGetWin32Thread()->MessageQueue
;
177 if(ThreadQueue
->CaretInfo
->hWnd
)
179 if(ThreadQueue
->CaretInfo
->Pos
.x
!= X
|| ThreadQueue
->CaretInfo
->Pos
.y
!= Y
)
181 co_IntHideCaret(ThreadQueue
->CaretInfo
);
182 ThreadQueue
->CaretInfo
->Showing
= 0;
183 ThreadQueue
->CaretInfo
->Pos
.x
= X
;
184 ThreadQueue
->CaretInfo
->Pos
.y
= Y
;
185 co_IntSendMessage(ThreadQueue
->CaretInfo
->hWnd
, WM_SYSTIMER
, IDCARETTIMER
, 0);
186 IntSetTimer(ThreadQueue
->CaretInfo
->hWnd
, IDCARETTIMER
, IntGetCaretBlinkTime(), NULL
, TRUE
);
195 IntSwitchCaretShowing(PVOID Info
)
197 PUSER_MESSAGE_QUEUE ThreadQueue
;
198 ThreadQueue
= (PUSER_MESSAGE_QUEUE
)PsGetWin32Thread()->MessageQueue
;
200 if(ThreadQueue
->CaretInfo
->hWnd
)
202 ThreadQueue
->CaretInfo
->Showing
= (ThreadQueue
->CaretInfo
->Showing
? 0 : 1);
203 MmCopyToCaller(Info
, ThreadQueue
->CaretInfo
, sizeof(THRDCARETINFO
));
213 co_IntDrawCaret(HWND hWnd
)
215 PUSER_MESSAGE_QUEUE ThreadQueue
;
216 ThreadQueue
= (PUSER_MESSAGE_QUEUE
)PsGetWin32Thread()->MessageQueue
;
218 if(ThreadQueue
->CaretInfo
->hWnd
&& ThreadQueue
->CaretInfo
->Visible
&&
219 ThreadQueue
->CaretInfo
->Showing
)
221 co_IntSendMessage(ThreadQueue
->CaretInfo
->hWnd
, WM_SYSTIMER
, IDCARETTIMER
, 0);
222 ThreadQueue
->CaretInfo
->Showing
= 1;
229 BOOL FASTCALL
co_UserHideCaret(PWINDOW_OBJECT Window OPTIONAL
)
231 PUSER_MESSAGE_QUEUE ThreadQueue
;
233 if (Window
) ASSERT_REFS_CO(Window
);
235 if(Window
&& Window
->OwnerThread
!= PsGetCurrentThread())
237 SetLastWin32Error(ERROR_ACCESS_DENIED
);
241 ThreadQueue
= (PUSER_MESSAGE_QUEUE
)PsGetWin32Thread()->MessageQueue
;
243 if(Window
&& ThreadQueue
->CaretInfo
->hWnd
!= Window
->hSelf
)
245 SetLastWin32Error(ERROR_ACCESS_DENIED
);
249 if(ThreadQueue
->CaretInfo
->Visible
)
251 IntKillTimer(ThreadQueue
->CaretInfo
->hWnd
, IDCARETTIMER
, TRUE
);
253 co_IntHideCaret(ThreadQueue
->CaretInfo
);
254 ThreadQueue
->CaretInfo
->Visible
= 0;
255 ThreadQueue
->CaretInfo
->Showing
= 0;
262 BOOL FASTCALL
co_UserShowCaret(PWINDOW_OBJECT Window OPTIONAL
)
264 PUSER_MESSAGE_QUEUE ThreadQueue
;
266 if (Window
) ASSERT_REFS_CO(Window
);
268 if(Window
&& Window
->OwnerThread
!= PsGetCurrentThread())
270 SetLastWin32Error(ERROR_ACCESS_DENIED
);
274 ThreadQueue
= (PUSER_MESSAGE_QUEUE
)PsGetWin32Thread()->MessageQueue
;
276 if(Window
&& ThreadQueue
->CaretInfo
->hWnd
!= Window
->hSelf
)
278 SetLastWin32Error(ERROR_ACCESS_DENIED
);
282 if(!ThreadQueue
->CaretInfo
->Visible
)
284 ThreadQueue
->CaretInfo
->Visible
= 1;
285 if(!ThreadQueue
->CaretInfo
->Showing
)
287 co_IntSendMessage(ThreadQueue
->CaretInfo
->hWnd
, WM_SYSTIMER
, IDCARETTIMER
, 0);
289 IntSetTimer(ThreadQueue
->CaretInfo
->hWnd
, IDCARETTIMER
, IntGetCaretBlinkTime(), NULL
, TRUE
);
296 /* SYSCALLS *****************************************************************/
306 PWINDOW_OBJECT Window
;
307 PUSER_MESSAGE_QUEUE ThreadQueue
;
308 DECLARE_RETURN(BOOL
);
310 DPRINT("Enter NtUserCreateCaret\n");
311 UserEnterExclusive();
313 if(!(Window
= UserGetWindowObject(hWnd
)))
318 if(Window
->OwnerThread
!= PsGetCurrentThread())
320 SetLastWin32Error(ERROR_ACCESS_DENIED
);
324 ThreadQueue
= (PUSER_MESSAGE_QUEUE
)PsGetWin32Thread()->MessageQueue
;
326 if (ThreadQueue
->CaretInfo
->Visible
)
328 IntKillTimer(hWnd
, IDCARETTIMER
, TRUE
);
329 co_IntHideCaret(ThreadQueue
->CaretInfo
);
332 ThreadQueue
->CaretInfo
->hWnd
= hWnd
;
335 ThreadQueue
->CaretInfo
->Bitmap
= hBitmap
;
336 ThreadQueue
->CaretInfo
->Size
.cx
= ThreadQueue
->CaretInfo
->Size
.cy
= 0;
340 ThreadQueue
->CaretInfo
->Bitmap
= (HBITMAP
)0;
341 ThreadQueue
->CaretInfo
->Size
.cx
= nWidth
;
342 ThreadQueue
->CaretInfo
->Size
.cy
= nHeight
;
344 ThreadQueue
->CaretInfo
->Visible
= 0;
345 ThreadQueue
->CaretInfo
->Showing
= 0;
350 DPRINT("Leave NtUserCreateCaret, ret=%i\n",_ret_
);
357 NtUserGetCaretBlinkTime(VOID
)
359 DECLARE_RETURN(UINT
);
361 DPRINT("Enter NtUserGetCaretBlinkTime\n");
364 RETURN(IntGetCaretBlinkTime());
367 DPRINT("Leave NtUserGetCaretBlinkTime, ret=%i\n",_ret_
);
377 PUSER_MESSAGE_QUEUE ThreadQueue
;
379 DECLARE_RETURN(BOOL
);
381 DPRINT("Enter NtUserGetCaretPos\n");
384 ThreadQueue
= (PUSER_MESSAGE_QUEUE
)PsGetWin32Thread()->MessageQueue
;
386 Status
= MmCopyToCaller(lpPoint
, &(ThreadQueue
->CaretInfo
->Pos
), sizeof(POINT
));
387 if(!NT_SUCCESS(Status
))
389 SetLastNtError(Status
);
396 DPRINT("Leave NtUserGetCaretPos, ret=%i\n",_ret_
);
405 NtUserShowCaret(HWND hWnd OPTIONAL
, BOOL bShow
)
407 PWINDOW_OBJECT Window
= NULL
;
408 USER_REFERENCE_ENTRY Ref
;
409 DECLARE_RETURN(BOOL
);
412 DPRINT("Enter NtUserShowCaret\n");
413 UserEnterExclusive();
415 if(hWnd
&& !(Window
= UserGetWindowObject(hWnd
)))
420 if (Window
) UserRefObjectCo(Window
, &Ref
);
423 ret
= co_UserShowCaret(Window
);
425 ret
= co_UserHideCaret(Window
);
427 if (Window
) UserDerefObjectCo(Window
);
432 DPRINT("Leave NtUserShowCaret, ret=%i\n",_ret_
);