2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Win32k subsystem
4 * PURPOSE: Caret functions
5 * FILE: subsystems/win32/win32k/ntuser/caret.c
6 * PROGRAMER: Thomas Weidenmueller (w3seek@users.sourceforge.net)
10 DBG_DEFAULT_CHANNEL(UserCaret
);
12 /* DEFINES *****************************************************************/
14 #define MIN_CARETBLINKRATE 100
15 #define MAX_CARETBLINKRATE 10000
17 /* FUNCTIONS *****************************************************************/
21 co_IntHideCaret(PTHRDCARETINFO CaretInfo
)
24 if(CaretInfo
->hWnd
&& CaretInfo
->Visible
&& CaretInfo
->Showing
)
26 pWnd
= UserGetWindowObject(CaretInfo
->hWnd
);
27 co_IntSendMessage(CaretInfo
->hWnd
, WM_SYSTIMER
, IDCARETTIMER
, 0);
28 CaretInfo
->Showing
= 0;
29 IntNotifyWinEvent(EVENT_OBJECT_HIDE
, pWnd
, OBJID_CARET
, CHILDID_SELF
, 0);
36 co_IntDestroyCaret(PTHREADINFO Win32Thread
)
38 PUSER_MESSAGE_QUEUE ThreadQueue
;
40 ThreadQueue
= (PUSER_MESSAGE_QUEUE
)Win32Thread
->MessageQueue
;
42 if(!ThreadQueue
|| !ThreadQueue
->CaretInfo
)
45 pWnd
= UserGetWindowObject(ThreadQueue
->CaretInfo
->hWnd
);
46 co_IntHideCaret(ThreadQueue
->CaretInfo
);
47 ThreadQueue
->CaretInfo
->Bitmap
= (HBITMAP
)0;
48 ThreadQueue
->CaretInfo
->hWnd
= (HWND
)0;
49 ThreadQueue
->CaretInfo
->Size
.cx
= ThreadQueue
->CaretInfo
->Size
.cy
= 0;
50 ThreadQueue
->CaretInfo
->Showing
= 0;
51 ThreadQueue
->CaretInfo
->Visible
= 0;
52 IntNotifyWinEvent(EVENT_OBJECT_DESTROY
, pWnd
, OBJID_CARET
, CHILDID_SELF
, 0);
57 IntSetCaretBlinkTime(UINT uMSeconds
)
59 /* Don't save the new value to the registry! */
61 /* Windows doesn't do this check */
62 if((uMSeconds
< MIN_CARETBLINKRATE
) || (uMSeconds
> MAX_CARETBLINKRATE
))
64 EngSetLastError(ERROR_INVALID_PARAMETER
);
68 gpsi
->dtCaretBlink
= uMSeconds
;
74 co_IntSetCaretPos(int X
, int Y
)
78 PUSER_MESSAGE_QUEUE ThreadQueue
;
80 pti
= PsGetCurrentThreadWin32Thread();
81 ThreadQueue
= pti
->MessageQueue
;
83 if(ThreadQueue
->CaretInfo
->hWnd
)
85 pWnd
= UserGetWindowObject(ThreadQueue
->CaretInfo
->hWnd
);
86 if(ThreadQueue
->CaretInfo
->Pos
.x
!= X
|| ThreadQueue
->CaretInfo
->Pos
.y
!= Y
)
88 co_IntHideCaret(ThreadQueue
->CaretInfo
);
89 ThreadQueue
->CaretInfo
->Showing
= 0;
90 ThreadQueue
->CaretInfo
->Pos
.x
= X
;
91 ThreadQueue
->CaretInfo
->Pos
.y
= Y
;
92 co_IntSendMessage(ThreadQueue
->CaretInfo
->hWnd
, WM_SYSTIMER
, IDCARETTIMER
, 0);
93 IntSetTimer(UserGetWindowObject(ThreadQueue
->CaretInfo
->hWnd
), IDCARETTIMER
, gpsi
->dtCaretBlink
, NULL
, TMRF_SYSTEM
);
94 IntNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE
, pWnd
, OBJID_CARET
, CHILDID_SELF
, 0);
103 IntSwitchCaretShowing(PVOID Info
)
106 PUSER_MESSAGE_QUEUE ThreadQueue
;
108 pti
= PsGetCurrentThreadWin32Thread();
109 ThreadQueue
= pti
->MessageQueue
;
111 if(ThreadQueue
->CaretInfo
->hWnd
)
113 ThreadQueue
->CaretInfo
->Showing
= (ThreadQueue
->CaretInfo
->Showing
? 0 : 1);
114 MmCopyToCaller(Info
, ThreadQueue
->CaretInfo
, sizeof(THRDCARETINFO
));
124 co_IntDrawCaret(HWND hWnd
)
127 PUSER_MESSAGE_QUEUE ThreadQueue
;
129 pti
= PsGetCurrentThreadWin32Thread();
130 ThreadQueue
= pti
->MessageQueue
;
132 if(ThreadQueue
->CaretInfo
->hWnd
&& ThreadQueue
->CaretInfo
->Visible
&&
133 ThreadQueue
->CaretInfo
->Showing
)
135 co_IntSendMessage(ThreadQueue
->CaretInfo
->hWnd
, WM_SYSTIMER
, IDCARETTIMER
, 0);
136 ThreadQueue
->CaretInfo
->Showing
= 1;
143 BOOL FASTCALL
co_UserHideCaret(PWND Window OPTIONAL
)
146 PUSER_MESSAGE_QUEUE ThreadQueue
;
148 if (Window
) ASSERT_REFS_CO(Window
);
150 if(Window
&& Window
->head
.pti
->pEThread
!= PsGetCurrentThread())
152 EngSetLastError(ERROR_ACCESS_DENIED
);
156 pti
= PsGetCurrentThreadWin32Thread();
157 ThreadQueue
= pti
->MessageQueue
;
159 if(Window
&& ThreadQueue
->CaretInfo
->hWnd
!= Window
->head
.h
)
161 EngSetLastError(ERROR_ACCESS_DENIED
);
165 if(ThreadQueue
->CaretInfo
->Visible
)
167 PWND pwnd
= UserGetWindowObject(ThreadQueue
->CaretInfo
->hWnd
);
168 IntKillTimer(pwnd
, IDCARETTIMER
, TRUE
);
170 co_IntHideCaret(ThreadQueue
->CaretInfo
);
171 ThreadQueue
->CaretInfo
->Visible
= 0;
172 ThreadQueue
->CaretInfo
->Showing
= 0;
179 BOOL FASTCALL
co_UserShowCaret(PWND Window OPTIONAL
)
183 PUSER_MESSAGE_QUEUE ThreadQueue
;
185 if (Window
) ASSERT_REFS_CO(Window
);
187 if(Window
&& Window
->head
.pti
->pEThread
!= PsGetCurrentThread())
189 EngSetLastError(ERROR_ACCESS_DENIED
);
193 pti
= PsGetCurrentThreadWin32Thread();
194 ThreadQueue
= pti
->MessageQueue
;
196 if(Window
&& ThreadQueue
->CaretInfo
->hWnd
!= Window
->head
.h
)
198 EngSetLastError(ERROR_ACCESS_DENIED
);
202 if(!ThreadQueue
->CaretInfo
->Visible
)
204 ThreadQueue
->CaretInfo
->Visible
= 1;
205 if(!ThreadQueue
->CaretInfo
->Showing
)
207 pWnd
= UserGetWindowObject(ThreadQueue
->CaretInfo
->hWnd
);
208 co_IntSendMessage(ThreadQueue
->CaretInfo
->hWnd
, WM_SYSTIMER
, IDCARETTIMER
, 0);
209 IntNotifyWinEvent(EVENT_OBJECT_SHOW
, pWnd
, OBJID_CARET
, OBJID_CARET
, 0);
211 IntSetTimer(UserGetWindowObject(ThreadQueue
->CaretInfo
->hWnd
), IDCARETTIMER
, gpsi
->dtCaretBlink
, NULL
, TMRF_SYSTEM
);
217 /* SYSCALLS *****************************************************************/
229 PUSER_MESSAGE_QUEUE ThreadQueue
;
230 DECLARE_RETURN(BOOL
);
232 TRACE("Enter NtUserCreateCaret\n");
233 UserEnterExclusive();
235 if(!(Window
= UserGetWindowObject(hWnd
)))
240 if(Window
->head
.pti
->pEThread
!= PsGetCurrentThread())
242 EngSetLastError(ERROR_ACCESS_DENIED
);
246 pti
= PsGetCurrentThreadWin32Thread();
247 ThreadQueue
= pti
->MessageQueue
;
249 if (ThreadQueue
->CaretInfo
->Visible
)
251 PWND pwnd
= UserGetWindowObject(hWnd
);
252 IntKillTimer(pwnd
, IDCARETTIMER
, TRUE
);
253 co_IntHideCaret(ThreadQueue
->CaretInfo
);
256 ThreadQueue
->CaretInfo
->hWnd
= hWnd
;
259 ThreadQueue
->CaretInfo
->Bitmap
= hBitmap
;
260 ThreadQueue
->CaretInfo
->Size
.cx
= ThreadQueue
->CaretInfo
->Size
.cy
= 0;
266 nWidth
= UserGetSystemMetrics(SM_CXBORDER
);
270 nHeight
= UserGetSystemMetrics(SM_CYBORDER
);
272 ThreadQueue
->CaretInfo
->Bitmap
= (HBITMAP
)0;
273 ThreadQueue
->CaretInfo
->Size
.cx
= nWidth
;
274 ThreadQueue
->CaretInfo
->Size
.cy
= nHeight
;
276 ThreadQueue
->CaretInfo
->Visible
= 0;
277 ThreadQueue
->CaretInfo
->Showing
= 0;
278 IntNotifyWinEvent(EVENT_OBJECT_CREATE
, Window
, OBJID_CARET
, CHILDID_SELF
, 0);
282 TRACE("Leave NtUserCreateCaret, ret=%i\n",_ret_
);
289 NtUserGetCaretBlinkTime(VOID
)
295 ret
= gpsi
->dtCaretBlink
;
308 PUSER_MESSAGE_QUEUE ThreadQueue
;
310 DECLARE_RETURN(BOOL
);
312 TRACE("Enter NtUserGetCaretPos\n");
315 pti
= PsGetCurrentThreadWin32Thread();
316 ThreadQueue
= pti
->MessageQueue
;
318 Status
= MmCopyToCaller(lpPoint
, &(ThreadQueue
->CaretInfo
->Pos
), sizeof(POINT
));
319 if(!NT_SUCCESS(Status
))
321 SetLastNtError(Status
);
328 TRACE("Leave NtUserGetCaretPos, ret=%i\n",_ret_
);
335 NtUserShowCaret(HWND hWnd OPTIONAL
)
338 USER_REFERENCE_ENTRY Ref
;
339 DECLARE_RETURN(BOOL
);
342 TRACE("Enter NtUserShowCaret\n");
343 UserEnterExclusive();
345 if(hWnd
&& !(Window
= UserGetWindowObject(hWnd
)))
350 if (Window
) UserRefObjectCo(Window
, &Ref
);
352 ret
= co_UserShowCaret(Window
);
354 if (Window
) UserDerefObjectCo(Window
);
359 TRACE("Leave NtUserShowCaret, ret=%i\n",_ret_
);
366 NtUserHideCaret(HWND hWnd OPTIONAL
)
369 USER_REFERENCE_ENTRY Ref
;
370 DECLARE_RETURN(BOOL
);
373 TRACE("Enter NtUserHideCaret\n");
374 UserEnterExclusive();
376 if(hWnd
&& !(Window
= UserGetWindowObject(hWnd
)))
381 if (Window
) UserRefObjectCo(Window
, &Ref
);
383 ret
= co_UserHideCaret(Window
);
385 if (Window
) UserDerefObjectCo(Window
);
390 TRACE("Leave NtUserHideCaret, ret=%i\n",_ret_
);