ReactOS 0.4.17-dev-116-ga4b6fe9
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
225{
226 PTHREADINFO pti;
227 PUSER_MESSAGE_QUEUE ThreadQueue;
228
230
231 if(Window && Window->head.pti->pEThread != PsGetCurrentThread())
232 {
234 return FALSE;
235 }
236
238 ThreadQueue = pti->MessageQueue;
239
240 if(Window && ThreadQueue->CaretInfo.hWnd != UserHMGetHandle(Window))
241 {
243 return FALSE;
244 }
245
246 if(ThreadQueue->CaretInfo.Visible)
247 {
248 PWND pwnd = UserGetWindowObject(ThreadQueue->CaretInfo.hWnd);
250
251 co_IntHideCaret(&ThreadQueue->CaretInfo);
252 ThreadQueue->CaretInfo.Visible = 0;
253 ThreadQueue->CaretInfo.Showing = 0;
254 }
255
256 return TRUE;
257}
258
260{
261 PTHREADINFO pti;
262 PUSER_MESSAGE_QUEUE ThreadQueue;
263 PWND pWnd = NULL;
264
266
267 if(Window && Window->head.pti->pEThread != PsGetCurrentThread())
268 {
270 return FALSE;
271 }
272
274 ThreadQueue = pti->MessageQueue;
275
276 if(Window && ThreadQueue->CaretInfo.hWnd != UserHMGetHandle(Window))
277 {
279 return FALSE;
280 }
281
282 if (!ThreadQueue->CaretInfo.Visible)
283 {
284 ThreadQueue->CaretInfo.Visible = 1;
285 pWnd = ValidateHwndNoErr(ThreadQueue->CaretInfo.hWnd);
286 if (!ThreadQueue->CaretInfo.Showing && pWnd)
287 {
288 IntNotifyWinEvent(EVENT_OBJECT_SHOW, pWnd, OBJID_CARET, OBJID_CARET, 0);
289 }
290 if ((INT)gpsi->dtCaretBlink > 0)
291 {
293 }
294 else if (ThreadQueue->CaretInfo.Visible)
295 {
296 ThreadQueue->CaretInfo.Showing = 1;
297 co_IntDrawCaret(pWnd, &ThreadQueue->CaretInfo);
298 }
299 }
300 return TRUE;
301}
302
303/* SYSCALLS *****************************************************************/
304
305BOOL
308 HWND hWnd,
310 int nWidth,
311 int nHeight)
312{
313 PWND Window;
314 PTHREADINFO pti;
315 PUSER_MESSAGE_QUEUE ThreadQueue;
316 BOOL Ret = FALSE;
317
318 TRACE("Enter NtUserCreateCaret\n");
320
322 {
323 goto Exit; // Return FALSE
324 }
325
326 if(Window->head.pti->pEThread != PsGetCurrentThread())
327 {
329 goto Exit; // Return FALSE
330 }
331
333 ThreadQueue = pti->MessageQueue;
334
335 if (ThreadQueue->CaretInfo.Visible)
336 {
338 co_IntHideCaret(&ThreadQueue->CaretInfo);
339 }
340
341 ThreadQueue->CaretInfo.hWnd = hWnd;
342 if(hBitmap)
343 {
344 ThreadQueue->CaretInfo.Bitmap = hBitmap;
345 ThreadQueue->CaretInfo.Size.cx = ThreadQueue->CaretInfo.Size.cy = 0;
346 }
347 else
348 {
349 if (nWidth == 0)
350 {
352 }
353 if (nHeight == 0)
354 {
356 }
357 ThreadQueue->CaretInfo.Bitmap = (HBITMAP)0;
358 ThreadQueue->CaretInfo.Size.cx = nWidth;
359 ThreadQueue->CaretInfo.Size.cy = nHeight;
360 }
361 ThreadQueue->CaretInfo.Visible = 0;
362 ThreadQueue->CaretInfo.Showing = 0;
363
365
366 IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window, OBJID_CARET, CHILDID_SELF, 0);
367
368 Ret = TRUE;
369
370Exit:
371 TRACE("Leave NtUserCreateCaret, ret=%i\n", Ret);
372 UserLeave();
373 return Ret;
374}
375
376UINT
379{
380 UINT ret;
381
383
384 ASSERT(gpsi);
385 ret = gpsi->dtCaretBlink;
386
387 UserLeave();
388
389 return ret;
390}
391
392BOOL
395 LPPOINT lpPoint)
396{
397 PTHREADINFO pti;
398 PUSER_MESSAGE_QUEUE ThreadQueue;
400 BOOL Ret = TRUE;
401
402 TRACE("Enter NtUserGetCaretPos\n");
404
406 ThreadQueue = pti->MessageQueue;
407
408 Status = MmCopyToCaller(lpPoint, &ThreadQueue->CaretInfo.Pos, sizeof(POINT));
409 if(!NT_SUCCESS(Status))
410 {
412 Ret = FALSE;
413 }
414
415 TRACE("Leave NtUserGetCaretPos, ret=%i\n", Ret);
416 UserLeave();
417 return Ret;
418}
419
420BOOL
423{
424 PWND Window = NULL;
426 BOOL ret = FALSE;
427
428 TRACE("Enter NtUserShowCaret\n");
430
432 {
433 goto Exit; // Return FALSE
434 }
435
436 if (Window) UserRefObjectCo(Window, &Ref);
437
439
441
442Exit:
443 TRACE("Leave NtUserShowCaret, ret=%i\n", ret);
444 UserLeave();
445 return ret;
446}
447
448BOOL
451{
452 PWND Window = NULL;
454 BOOL ret = FALSE;
455
456 TRACE("Enter NtUserHideCaret\n");
458
460 {
461 goto Exit; // Return FALSE
462 }
463
464 if (Window) UserRefObjectCo(Window, &Ref);
465
467
469
470Exit:
471 TRACE("Leave NtUserHideCaret, ret=%i\n", ret);
472 UserLeave();
473 return ret;
474}
#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
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:255
VOID FASTCALL UserEnterShared(VOID)
Definition: ntuser.c:241
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:247
static __inline VOID UserDerefObjectCo(PVOID obj)
Definition: object.h:43
static __inline VOID UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry)
Definition: object.h:27
__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
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:123
#define ASSERT_REFS_CO(_obj_)
Definition: userfuncs.h:13
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:30
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:224
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:307
BOOL APIENTRY NtUserHideCaret(HWND hWnd OPTIONAL)
Definition: caret.c:450
BOOL APIENTRY NtUserShowCaret(HWND hWnd OPTIONAL)
Definition: caret.c:422
UINT APIENTRY NtUserGetCaretBlinkTime(VOID)
Definition: caret.c:378
BOOL FASTCALL co_UserShowCaret(PWND Window OPTIONAL)
Definition: caret.c:259
BOOL APIENTRY NtUserGetCaretPos(LPPOINT lpPoint)
Definition: caret.c:394
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
#define OBJID_CARET
Definition: winable.h:23
#define CHILDID_SELF
Definition: winable.h:14
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:21
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
VOID FASTCALL IntGetClientRect(PWND WindowObject, RECTL *Rect)
Definition: winpos.c:92
#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