ReactOS 0.4.16-dev-109-gf4cb10f
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,
69 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
187 gpsi->dtCaretBlink = uMSeconds;
188
189 return TRUE;
190}
191
194{
195 PTHREADINFO pti;
196 PWND pWnd;
197 PUSER_MESSAGE_QUEUE ThreadQueue;
198
200 ThreadQueue = pti->MessageQueue;
201
202 if(ThreadQueue->CaretInfo.hWnd)
203 {
204 pWnd = UserGetWindowObject(ThreadQueue->CaretInfo.hWnd);
205 if(ThreadQueue->CaretInfo.Pos.x != X || ThreadQueue->CaretInfo.Pos.y != Y)
206 {
207 co_IntHideCaret(&ThreadQueue->CaretInfo);
208 ThreadQueue->CaretInfo.Pos.x = X;
209 ThreadQueue->CaretInfo.Pos.y = Y;
210 if (ThreadQueue->CaretInfo.Visible)
211 {
212 ThreadQueue->CaretInfo.Showing = 1;
213 co_IntDrawCaret(pWnd, &ThreadQueue->CaretInfo);
214 }
215
217 IntNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE, pWnd, OBJID_CARET, CHILDID_SELF, 0);
218 }
219 return TRUE;
220 }
221
222 return FALSE;
223}
224
225/* Win: zzzHideCaret */
227{
228 PTHREADINFO pti;
229 PUSER_MESSAGE_QUEUE ThreadQueue;
230
232
233 if(Window && Window->head.pti->pEThread != PsGetCurrentThread())
234 {
236 return FALSE;
237 }
238
240 ThreadQueue = pti->MessageQueue;
241
242 if(Window && ThreadQueue->CaretInfo.hWnd != UserHMGetHandle(Window))
243 {
245 return FALSE;
246 }
247
248 if(ThreadQueue->CaretInfo.Visible)
249 {
250 PWND pwnd = UserGetWindowObject(ThreadQueue->CaretInfo.hWnd);
252
253 co_IntHideCaret(&ThreadQueue->CaretInfo);
254 ThreadQueue->CaretInfo.Visible = 0;
255 ThreadQueue->CaretInfo.Showing = 0;
256 }
257
258 return TRUE;
259}
260
261/* Win: zzzShowCaret */
263{
264 PTHREADINFO pti;
265 PUSER_MESSAGE_QUEUE ThreadQueue;
266 PWND pWnd = NULL;
267
269
270 if(Window && Window->head.pti->pEThread != PsGetCurrentThread())
271 {
273 return FALSE;
274 }
275
277 ThreadQueue = pti->MessageQueue;
278
279 if(Window && ThreadQueue->CaretInfo.hWnd != UserHMGetHandle(Window))
280 {
282 return FALSE;
283 }
284
285 if (!ThreadQueue->CaretInfo.Visible)
286 {
287 ThreadQueue->CaretInfo.Visible = 1;
288 pWnd = ValidateHwndNoErr(ThreadQueue->CaretInfo.hWnd);
289 if (!ThreadQueue->CaretInfo.Showing && pWnd)
290 {
291 IntNotifyWinEvent(EVENT_OBJECT_SHOW, pWnd, OBJID_CARET, OBJID_CARET, 0);
292 }
293 if ((INT)gpsi->dtCaretBlink > 0)
294 {
296 }
297 else if (ThreadQueue->CaretInfo.Visible)
298 {
299 ThreadQueue->CaretInfo.Showing = 1;
300 co_IntDrawCaret(pWnd, &ThreadQueue->CaretInfo);
301 }
302 }
303 return TRUE;
304}
305
306/* SYSCALLS *****************************************************************/
307
308BOOL
311 HWND hWnd,
313 int nWidth,
314 int nHeight)
315{
316 PWND Window;
317 PTHREADINFO pti;
318 PUSER_MESSAGE_QUEUE ThreadQueue;
319 BOOL Ret = FALSE;
320
321 TRACE("Enter NtUserCreateCaret\n");
323
325 {
326 goto Exit; // Return FALSE
327 }
328
329 if(Window->head.pti->pEThread != PsGetCurrentThread())
330 {
332 goto Exit; // Return FALSE
333 }
334
336 ThreadQueue = pti->MessageQueue;
337
338 if (ThreadQueue->CaretInfo.Visible)
339 {
341 co_IntHideCaret(&ThreadQueue->CaretInfo);
342 }
343
344 ThreadQueue->CaretInfo.hWnd = hWnd;
345 if(hBitmap)
346 {
347 ThreadQueue->CaretInfo.Bitmap = hBitmap;
348 ThreadQueue->CaretInfo.Size.cx = ThreadQueue->CaretInfo.Size.cy = 0;
349 }
350 else
351 {
352 if (nWidth == 0)
353 {
355 }
356 if (nHeight == 0)
357 {
359 }
360 ThreadQueue->CaretInfo.Bitmap = (HBITMAP)0;
361 ThreadQueue->CaretInfo.Size.cx = nWidth;
362 ThreadQueue->CaretInfo.Size.cy = nHeight;
363 }
364 ThreadQueue->CaretInfo.Visible = 0;
365 ThreadQueue->CaretInfo.Showing = 0;
366
368
369 IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window, OBJID_CARET, CHILDID_SELF, 0);
370
371 Ret = TRUE;
372
373Exit:
374 TRACE("Leave NtUserCreateCaret, ret=%i\n", Ret);
375 UserLeave();
376 return Ret;
377}
378
379UINT
382{
383 UINT ret;
384
386
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
PSERVERINFO gpsi
Definition: imm.c:18
#define ValidateHwndNoErr(hwnd)
Definition: precomp.h:84
static void cleanup(void)
Definition: main.c:1335
#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)
#define UserHMGetHandle(obj)
Definition: ntuser.h:230
#define MmCopyToCaller(x, y, z)
Definition: mmcopy.h:19
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:992
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:40
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:308
LONG bottom
Definition: windef.h:309
LONG top
Definition: windef.h:307
LONG left
Definition: windef.h:306
int32_t INT
Definition: typedefs.h:58
#define IDCARETTIMER
Definition: undocuser.h:80
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)
int ret
HDC hdcMem
Definition: welcome.c:104
VOID FASTCALL SetLastNtError(_In_ NTSTATUS Status)
Definition: error.c:31
BOOL NTAPI GreDeleteObject(HGDIOBJ hobj)
Definition: gdiobj.c:1158
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:226
BOOL FASTCALL co_IntSetCaretPos(int X, int Y)
Definition: caret.c:193
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:310
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:381
BOOL FASTCALL co_UserShowCaret(PWND Window OPTIONAL)
Definition: caret.c:262
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:214
BOOL FASTCALL IntKillTimer(PWND Window, UINT_PTR IDEvent, BOOL SystemTimer)
Definition: timer.c:580
UINT_PTR FASTCALL IntSetTimer(PWND Window, UINT_PTR IDEvent, UINT Elapse, TIMERPROC TimerFunc, INT Type)
Definition: timer.c:179
#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 SRCINVERT
Definition: wingdi.h:329
#define DSTINVERT
Definition: wingdi.h:327
#define SM_CYBORDER
Definition: winuser.h:968
#define SM_CXBORDER
Definition: winuser.h:967