ReactOS 0.4.16-dev-2332-g4cba65d
caret.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Win32k subsystem
4 * PURPOSE: Caret functions
5 * FILE: win32ss/user/ntuser/caret.c
6 * PROGRAMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net)
7 * Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
8 */
9
10#include <win32k.h>
12
13/* FUNCTIONS *****************************************************************/
14
17{
18 HDC hdc, hdcMem;
19 HBITMAP hbmOld;
20 RECT rcClient;
21 BOOL bDone = FALSE;
22
23 if (pWnd == NULL)
24 {
25 TRACE("Null Window!\n");
26 return;
27 }
28
30 if (!hdc)
31 {
32 ERR("GetDC failed\n");
33 return;
34 }
35
36 if (pWnd->hrgnUpdate)
37 {
39 }
40
41 IntGetClientRect(pWnd, &rcClient);
43 rcClient.left,
44 rcClient.top,
45 rcClient.right,
46 rcClient.bottom);
47
48 if (CaretInfo->Bitmap)
49 {
50 if (!GreGetBitmapDimension(CaretInfo->Bitmap, &CaretInfo->Size))
51 {
52 ERR("Failed to get bitmap dimensions\n");
53 goto cleanup;
54 }
55
57 if (hdcMem)
58 {
59 hbmOld = NtGdiSelectBitmap(hdcMem, CaretInfo->Bitmap);
60 bDone = NtGdiBitBlt(hdc,
61 CaretInfo->Pos.x,
62 CaretInfo->Pos.y,
63 CaretInfo->Size.cx,
64 CaretInfo->Size.cy,
65 hdcMem,
66 0,
67 0,
70 0);
73 }
74 }
75
76 if (!bDone)
77 {
79 CaretInfo->Pos.x,
80 CaretInfo->Pos.y,
81 CaretInfo->Size.cx,
82 CaretInfo->Size.cy,
83 DSTINVERT);
84 }
85
87 if (pWnd->hrgnUpdate)
88 {
90 }
91
92 UserReleaseDC(pWnd, hdc, FALSE);
93}
94
95VOID
98 UINT uMsg,
99 UINT_PTR idEvent,
101{
102 PTHREADINFO pti;
103 PUSER_MESSAGE_QUEUE ThreadQueue;
104 PWND pWnd;
105
107 ThreadQueue = pti->MessageQueue;
108
109 if (ThreadQueue->CaretInfo.hWnd != hwnd)
110 {
111 TRACE("Not the same caret window!\n");
112 return;
113 }
114
115 if (hwnd)
116 {
118 if (!pWnd)
119 {
120 ERR("Caret System Timer Proc has invalid window handle! %p Id: %u\n", hwnd, idEvent);
121 return;
122 }
123 }
124 else
125 {
126 TRACE( "Windowless Caret Timer Running!\n" );
127 return;
128 }
129
130 switch (idEvent)
131 {
132 case IDCARETTIMER:
133 {
134 ThreadQueue->CaretInfo.Showing = (ThreadQueue->CaretInfo.Showing ? 0 : 1);
135 co_IntDrawCaret(pWnd, &ThreadQueue->CaretInfo);
136 }
137 }
138 return;
139}
140
141static
144{
145 PWND pWnd;
146 if(CaretInfo->hWnd && CaretInfo->Visible && CaretInfo->Showing)
147 {
148 pWnd = UserGetWindowObject(CaretInfo->hWnd);
149 CaretInfo->Showing = 0;
150
151 co_IntDrawCaret(pWnd, CaretInfo);
152 IntNotifyWinEvent(EVENT_OBJECT_HIDE, pWnd, OBJID_CARET, CHILDID_SELF, 0);
153 return TRUE;
154 }
155 return FALSE;
156}
157
160{
161 PUSER_MESSAGE_QUEUE ThreadQueue;
162 PWND pWnd;
163 ThreadQueue = Win32Thread->MessageQueue;
164
165 if (!ThreadQueue)
166 return FALSE;
167
168 pWnd = ValidateHwndNoErr(ThreadQueue->CaretInfo.hWnd);
169 co_IntHideCaret(&ThreadQueue->CaretInfo);
170 ThreadQueue->CaretInfo.Bitmap = (HBITMAP)0;
171 ThreadQueue->CaretInfo.hWnd = (HWND)0;
172 ThreadQueue->CaretInfo.Size.cx = ThreadQueue->CaretInfo.Size.cy = 0;
173 ThreadQueue->CaretInfo.Showing = 0;
174 ThreadQueue->CaretInfo.Visible = 0;
175 if (pWnd)
176 {
177 IntNotifyWinEvent(EVENT_OBJECT_DESTROY, pWnd, OBJID_CARET, CHILDID_SELF, 0);
178 }
179 return TRUE;
180}
181
184{
185 /* Don't save the new value to the registry! */
186 ASSERT(gpsi);
187 gpsi->dtCaretBlink = uMSeconds;
188 return TRUE;
189}
190
193{
194 PTHREADINFO pti;
195 PWND pWnd;
196 PUSER_MESSAGE_QUEUE ThreadQueue;
197
199 ThreadQueue = pti->MessageQueue;
200
201 if(ThreadQueue->CaretInfo.hWnd)
202 {
203 pWnd = UserGetWindowObject(ThreadQueue->CaretInfo.hWnd);
204 if(ThreadQueue->CaretInfo.Pos.x != X || ThreadQueue->CaretInfo.Pos.y != Y)
205 {
206 co_IntHideCaret(&ThreadQueue->CaretInfo);
207 ThreadQueue->CaretInfo.Pos.x = X;
208 ThreadQueue->CaretInfo.Pos.y = Y;
209 if (ThreadQueue->CaretInfo.Visible)
210 {
211 ThreadQueue->CaretInfo.Showing = 1;
212 co_IntDrawCaret(pWnd, &ThreadQueue->CaretInfo);
213 }
214
216 IntNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE, pWnd, OBJID_CARET, CHILDID_SELF, 0);
217 }
218 return TRUE;
219 }
220
221 return FALSE;
222}
223
224/* Win: zzzHideCaret */
226{
227 PTHREADINFO pti;
228 PUSER_MESSAGE_QUEUE ThreadQueue;
229
231
232 if(Window && Window->head.pti->pEThread != PsGetCurrentThread())
233 {
235 return FALSE;
236 }
237
239 ThreadQueue = pti->MessageQueue;
240
241 if(Window && ThreadQueue->CaretInfo.hWnd != UserHMGetHandle(Window))
242 {
244 return FALSE;
245 }
246
247 if(ThreadQueue->CaretInfo.Visible)
248 {
249 PWND pwnd = UserGetWindowObject(ThreadQueue->CaretInfo.hWnd);
251
252 co_IntHideCaret(&ThreadQueue->CaretInfo);
253 ThreadQueue->CaretInfo.Visible = 0;
254 ThreadQueue->CaretInfo.Showing = 0;
255 }
256
257 return TRUE;
258}
259
260/* Win: zzzShowCaret */
262{
263 PTHREADINFO pti;
264 PUSER_MESSAGE_QUEUE ThreadQueue;
265 PWND pWnd = NULL;
266
268
269 if(Window && Window->head.pti->pEThread != PsGetCurrentThread())
270 {
272 return FALSE;
273 }
274
276 ThreadQueue = pti->MessageQueue;
277
278 if(Window && ThreadQueue->CaretInfo.hWnd != UserHMGetHandle(Window))
279 {
281 return FALSE;
282 }
283
284 if (!ThreadQueue->CaretInfo.Visible)
285 {
286 ThreadQueue->CaretInfo.Visible = 1;
287 pWnd = ValidateHwndNoErr(ThreadQueue->CaretInfo.hWnd);
288 if (!ThreadQueue->CaretInfo.Showing && pWnd)
289 {
290 IntNotifyWinEvent(EVENT_OBJECT_SHOW, pWnd, OBJID_CARET, OBJID_CARET, 0);
291 }
292 if ((INT)gpsi->dtCaretBlink > 0)
293 {
295 }
296 else if (ThreadQueue->CaretInfo.Visible)
297 {
298 ThreadQueue->CaretInfo.Showing = 1;
299 co_IntDrawCaret(pWnd, &ThreadQueue->CaretInfo);
300 }
301 }
302 return TRUE;
303}
304
305/* SYSCALLS *****************************************************************/
306
307BOOL
310 HWND hWnd,
312 int nWidth,
313 int nHeight)
314{
315 PWND Window;
316 PTHREADINFO pti;
317 PUSER_MESSAGE_QUEUE ThreadQueue;
318 BOOL Ret = FALSE;
319
320 TRACE("Enter NtUserCreateCaret\n");
322
324 {
325 goto Exit; // Return FALSE
326 }
327
328 if(Window->head.pti->pEThread != PsGetCurrentThread())
329 {
331 goto Exit; // Return FALSE
332 }
333
335 ThreadQueue = pti->MessageQueue;
336
337 if (ThreadQueue->CaretInfo.Visible)
338 {
340 co_IntHideCaret(&ThreadQueue->CaretInfo);
341 }
342
343 ThreadQueue->CaretInfo.hWnd = hWnd;
344 if(hBitmap)
345 {
346 ThreadQueue->CaretInfo.Bitmap = hBitmap;
347 ThreadQueue->CaretInfo.Size.cx = ThreadQueue->CaretInfo.Size.cy = 0;
348 }
349 else
350 {
351 if (nWidth == 0)
352 {
354 }
355 if (nHeight == 0)
356 {
358 }
359 ThreadQueue->CaretInfo.Bitmap = (HBITMAP)0;
360 ThreadQueue->CaretInfo.Size.cx = nWidth;
361 ThreadQueue->CaretInfo.Size.cy = nHeight;
362 }
363 ThreadQueue->CaretInfo.Visible = 0;
364 ThreadQueue->CaretInfo.Showing = 0;
365
367
368 IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window, OBJID_CARET, CHILDID_SELF, 0);
369
370 Ret = TRUE;
371
372Exit:
373 TRACE("Leave NtUserCreateCaret, ret=%i\n", Ret);
374 UserLeave();
375 return Ret;
376}
377
378UINT
381{
382 UINT ret;
383
385
386 ASSERT(gpsi);
387 ret = gpsi->dtCaretBlink;
388
389 UserLeave();
390
391 return ret;
392}
393
394BOOL
397 LPPOINT lpPoint)
398{
399 PTHREADINFO pti;
400 PUSER_MESSAGE_QUEUE ThreadQueue;
402 BOOL Ret = TRUE;
403
404 TRACE("Enter NtUserGetCaretPos\n");
406
408 ThreadQueue = pti->MessageQueue;
409
410 Status = MmCopyToCaller(lpPoint, &ThreadQueue->CaretInfo.Pos, sizeof(POINT));
411 if(!NT_SUCCESS(Status))
412 {
414 Ret = FALSE;
415 }
416
417 TRACE("Leave NtUserGetCaretPos, ret=%i\n", Ret);
418 UserLeave();
419 return Ret;
420}
421
422BOOL
425{
426 PWND Window = NULL;
428 BOOL ret = FALSE;
429
430 TRACE("Enter NtUserShowCaret\n");
432
434 {
435 goto Exit; // Return FALSE
436 }
437
438 if (Window) UserRefObjectCo(Window, &Ref);
439
441
443
444Exit:
445 TRACE("Leave NtUserShowCaret, ret=%i\n", ret);
446 UserLeave();
447 return ret;
448}
449
450BOOL
453{
454 PWND Window = NULL;
456 BOOL ret = FALSE;
457
458 TRACE("Enter NtUserHideCaret\n");
460
462 {
463 goto Exit; // Return FALSE
464 }
465
466 if (Window) UserRefObjectCo(Window, &Ref);
467
469
471
472Exit:
473 TRACE("Leave NtUserHideCaret, ret=%i\n", ret);
474 UserLeave();
475 return ret;
476}
#define DCX_USESTYLE
Definition: GetDCEx.c:10
HWND hWnd
Definition: settings.c:17
LONG NTSTATUS
Definition: precomp.h:26
#define ERR(fmt,...)
Definition: precomp.h:57
BOOL NTAPI GreGetBitmapDimension(_In_ HBITMAP hBitmap, _Out_ LPSIZE psizDim)
Definition: bitmaps.c:453
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:106
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
static HBITMAP hBitmap
Definition: timezone.c:26
#define APIENTRY
Definition: api.h:79
#define Y(I)
HANDLE HWND
Definition: compat.h:19
#define CALLBACK
Definition: compat.h:35
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
static void cleanup(void)
Definition: main.c:1335
return ret
Definition: mutex.c:146
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
Status
Definition: gdiplustypes.h:25
#define X(b, s)
PSERVERINFO gpsi
Definition: imm.c:18
#define UserHMGetHandle(obj)
Definition: ntuser.h:230
#define MmCopyToCaller(x, y, z)
Definition: mmcopy.h:19
#define ASSERT(a)
Definition: mode.c:44
HDC hdc
Definition: main.c:9
static HBITMAP
Definition: button.c:44
static HDC
Definition: imagelist.c:88
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
unsigned int UINT
Definition: ndis.h:50
#define FASTCALL
Definition: nt_native.h:50
__kernel_entry W32KAPI HDC APIENTRY NtGdiCreateCompatibleDC(_In_opt_ HDC hdc)
__kernel_entry W32KAPI BOOL APIENTRY NtGdiRestoreDC(_In_ HDC hdc, _In_ INT iLevel)
__kernel_entry W32KAPI BOOL APIENTRY NtGdiBitBlt(_In_ HDC hdcDst, _In_ INT x, _In_ INT y, _In_ INT cx, _In_ INT cy, _In_opt_ HDC hdcSrc, _In_ INT xSrc, _In_ INT ySrc, _In_ DWORD rop4, _In_ DWORD crBackColor, _In_ FLONG fl)
__kernel_entry W32KAPI INT APIENTRY NtGdiSaveDC(_In_ HDC hdc)
__kernel_entry W32KAPI INT APIENTRY NtGdiIntersectClipRect(_In_ HDC hdc, _In_ INT xLeft, _In_ INT yTop, _In_ INT xRight, _In_ INT yBottom)
Definition: cliprgn.c:488
__kernel_entry W32KAPI HBITMAP APIENTRY NtGdiSelectBitmap(_In_ HDC hdc, _In_ HBITMAP hbm)
__kernel_entry W32KAPI BOOL APIENTRY NtGdiPatBlt(_In_ HDC hdcDest, _In_ INT x, _In_ INT y, _In_ INT cx, _In_ INT cy, _In_ DWORD dwRop)
Definition: bitblt.c:988
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:258
VOID FASTCALL UserEnterShared(VOID)
Definition: ntuser.c:242
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:249
static __inline VOID UserDerefObjectCo(PVOID obj)
Definition: object.h:43
static __inline VOID UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry)
Definition: object.h:27
static void Exit(void)
Definition: sock.c:1330
#define TRACE(s)
Definition: solgame.cpp:4
DWORD dwTime
Definition: solitaire.cpp:27
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
Definition: window.c:28
LONG cx
Definition: kdterminal.h:27
LONG cy
Definition: kdterminal.h:28
HBITMAP Bitmap
Definition: ntusrtyp.h:130
struct _USER_MESSAGE_QUEUE * MessageQueue
Definition: win32.h:89
THRDCARETINFO CaretInfo
Definition: msgqueue.h:92
Definition: object.h:4
Definition: ntuser.h:694
HRGN hrgnUpdate
Definition: ntuser.h:721
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
LONG right
Definition: windef.h:108
LONG bottom
Definition: windef.h:109
LONG top
Definition: windef.h:107
LONG left
Definition: windef.h:106
int32_t INT
Definition: typedefs.h:58
#define IDCARETTIMER
Definition: undocuser.h:81
PWND FASTCALL UserGetWindowObject(HWND hWnd)
Definition: window.c:124
#define ASSERT_REFS_CO(_obj_)
Definition: userfuncs.h:14
INT FASTCALL UserReleaseDC(PWND Window, HDC hDc, BOOL EndPaint)
Definition: windc.c:918
HDC FASTCALL UserGetDCEx(PWND Window OPTIONAL, HANDLE ClipRegion, ULONG Flags)
HDC hdcMem
Definition: welcome.c:104
VOID FASTCALL SetLastNtError(_In_ NTSTATUS Status)
Definition: error.c:31
BOOL NTAPI GreDeleteObject(HGDIOBJ hobj)
Definition: gdiobj.c:1165
#define ValidateHwndNoErr(hwnd)
Definition: precomp.h:97
VOID CALLBACK CaretSystemTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
Definition: caret.c:97
VOID FASTCALL co_IntDrawCaret(PWND pWnd, PTHRDCARETINFO CaretInfo)
Definition: caret.c:16
BOOL FASTCALL IntSetCaretBlinkTime(UINT uMSeconds)
Definition: caret.c:183
BOOL FASTCALL co_UserHideCaret(PWND Window OPTIONAL)
Definition: caret.c:225
BOOL FASTCALL co_IntSetCaretPos(int X, int Y)
Definition: caret.c:192
static BOOL FASTCALL co_IntHideCaret(PTHRDCARETINFO CaretInfo)
Definition: caret.c:143
BOOL APIENTRY NtUserCreateCaret(HWND hWnd, HBITMAP hBitmap, int nWidth, int nHeight)
Definition: caret.c:309
BOOL APIENTRY NtUserHideCaret(HWND hWnd OPTIONAL)
Definition: caret.c:452
BOOL APIENTRY NtUserShowCaret(HWND hWnd OPTIONAL)
Definition: caret.c:424
UINT APIENTRY NtUserGetCaretBlinkTime(VOID)
Definition: caret.c:380
BOOL FASTCALL co_UserShowCaret(PWND Window OPTIONAL)
Definition: caret.c:261
BOOL APIENTRY NtUserGetCaretPos(LPPOINT lpPoint)
Definition: caret.c:396
BOOL FASTCALL co_IntDestroyCaret(PTHREADINFO Win32Thread)
Definition: caret.c:159
VOID FASTCALL IntNotifyWinEvent(DWORD Event, PWND pWnd, LONG idObject, LONG idChild, DWORD flags)
Definition: event.c:178
LONG NTAPI UserGetSystemMetrics(ULONG Index)
Definition: metric.c:209
BOOL FASTCALL IntKillTimer(PWND Window, UINT_PTR IDEvent, BOOL SystemTimer)
Definition: timer.c:579
UINT_PTR FASTCALL IntSetTimer(PWND Window, UINT_PTR IDEvent, UINT Elapse, TIMERPROC TimerFunc, INT Type)
Definition: timer.c:182
#define TMRF_SYSTEM
Definition: timer.h:20
VOID FASTCALL IntGetClientRect(PWND WindowObject, RECTL *Rect)
Definition: winpos.c:92
#define OBJID_CARET
Definition: winable.h:23
#define CHILDID_SELF
Definition: winable.h:14
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:22
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
#define CLR_INVALID
Definition: wingdi.h:883
#define SRCINVERT
Definition: wingdi.h:329
#define DSTINVERT
Definition: wingdi.h:327
#define SM_CYBORDER
Definition: winuser.h:976
#define SM_CXBORDER
Definition: winuser.h:975