ReactOS  0.4.15-dev-5488-ge316d61
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>
11 DBG_DEFAULT_CHANNEL(UserCaret);
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 
29  hdc = UserGetDCEx(pWnd, NULL, DCX_USESTYLE);
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,
68  SRCINVERT,
69  0,
70  0);
71  NtGdiSelectBitmap(hdcMem, hbmOld);
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 
86 cleanup:
87  if (pWnd->hrgnUpdate)
88  {
89  NtGdiRestoreDC(hdc, -1);
90  }
91 
92  UserReleaseDC(pWnd, hdc, FALSE);
93 }
94 
95 VOID
98  UINT uMsg,
99  UINT_PTR idEvent,
100  DWORD dwTime)
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  {
117  pWnd = UserGetWindowObject(hwnd);
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 
141 static
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 
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 != Window->head.h)
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 
261 {
262  PTHREADINFO pti;
263  PUSER_MESSAGE_QUEUE ThreadQueue;
264  PWND pWnd = NULL;
265 
267 
268  if(Window && Window->head.pti->pEThread != PsGetCurrentThread())
269  {
271  return FALSE;
272  }
273 
275  ThreadQueue = pti->MessageQueue;
276 
277  if(Window && ThreadQueue->CaretInfo.hWnd != Window->head.h)
278  {
280  return FALSE;
281  }
282 
283  if (!ThreadQueue->CaretInfo.Visible)
284  {
285  ThreadQueue->CaretInfo.Visible = 1;
286  pWnd = ValidateHwndNoErr(ThreadQueue->CaretInfo.hWnd);
287  if (!ThreadQueue->CaretInfo.Showing && pWnd)
288  {
289  IntNotifyWinEvent(EVENT_OBJECT_SHOW, pWnd, OBJID_CARET, OBJID_CARET, 0);
290  }
291  if ((INT)gpsi->dtCaretBlink > 0)
292  {
294  }
295  else if (ThreadQueue->CaretInfo.Visible)
296  {
297  ThreadQueue->CaretInfo.Showing = 1;
298  co_IntDrawCaret(pWnd, &ThreadQueue->CaretInfo);
299  }
300  }
301  return TRUE;
302 }
303 
304 /* SYSCALLS *****************************************************************/
305 
306 BOOL
307 APIENTRY
309  HWND hWnd,
311  int nWidth,
312  int nHeight)
313 {
314  PWND Window;
315  PTHREADINFO pti;
316  PUSER_MESSAGE_QUEUE ThreadQueue;
318 
319  TRACE("Enter NtUserCreateCaret\n");
321 
323  {
324  RETURN(FALSE);
325  }
326 
327  if(Window->head.pti->pEThread != PsGetCurrentThread())
328  {
330  RETURN(FALSE);
331  }
332 
334  ThreadQueue = pti->MessageQueue;
335 
336  if (ThreadQueue->CaretInfo.Visible)
337  {
339  co_IntHideCaret(&ThreadQueue->CaretInfo);
340  }
341 
342  ThreadQueue->CaretInfo.hWnd = hWnd;
343  if(hBitmap)
344  {
345  ThreadQueue->CaretInfo.Bitmap = hBitmap;
346  ThreadQueue->CaretInfo.Size.cx = ThreadQueue->CaretInfo.Size.cy = 0;
347  }
348  else
349  {
350  if (nWidth == 0)
351  {
353  }
354  if (nHeight == 0)
355  {
357  }
358  ThreadQueue->CaretInfo.Bitmap = (HBITMAP)0;
359  ThreadQueue->CaretInfo.Size.cx = nWidth;
360  ThreadQueue->CaretInfo.Size.cy = nHeight;
361  }
362  ThreadQueue->CaretInfo.Visible = 0;
363  ThreadQueue->CaretInfo.Showing = 0;
364 
366 
367  IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window, OBJID_CARET, CHILDID_SELF, 0);
368 
369  RETURN(TRUE);
370 
371 CLEANUP:
372  TRACE("Leave NtUserCreateCaret, ret=%i\n",_ret_);
373  UserLeave();
374  END_CLEANUP;
375 }
376 
377 UINT
378 APIENTRY
380 {
381  UINT ret;
382 
383  UserEnterShared();
384 
385  ret = gpsi->dtCaretBlink;
386 
387  UserLeave();
388 
389  return ret;
390 }
391 
392 BOOL
393 APIENTRY
395  LPPOINT lpPoint)
396 {
397  PTHREADINFO pti;
398  PUSER_MESSAGE_QUEUE ThreadQueue;
401 
402  TRACE("Enter NtUserGetCaretPos\n");
403  UserEnterShared();
404 
406  ThreadQueue = pti->MessageQueue;
407 
408  Status = MmCopyToCaller(lpPoint, &ThreadQueue->CaretInfo.Pos, sizeof(POINT));
409  if(!NT_SUCCESS(Status))
410  {
412  RETURN(FALSE);
413  }
414 
415  RETURN(TRUE);
416 
417 CLEANUP:
418  TRACE("Leave NtUserGetCaretPos, ret=%i\n",_ret_);
419  UserLeave();
420  END_CLEANUP;
421 }
422 
423 BOOL
424 APIENTRY
426 {
427  PWND Window = NULL;
430  BOOL ret;
431 
432  TRACE("Enter NtUserShowCaret\n");
434 
435  if(hWnd && !(Window = UserGetWindowObject(hWnd)))
436  {
437  RETURN(FALSE);
438  }
439 
440  if (Window) UserRefObjectCo(Window, &Ref);
441 
443 
445 
446  RETURN(ret);
447 
448 CLEANUP:
449  TRACE("Leave NtUserShowCaret, ret=%i\n",_ret_);
450  UserLeave();
451  END_CLEANUP;
452 }
453 
454 BOOL
455 APIENTRY
457 {
458  PWND Window = NULL;
461  BOOL ret;
462 
463  TRACE("Enter NtUserHideCaret\n");
465 
466  if(hWnd && !(Window = UserGetWindowObject(hWnd)))
467  {
468  RETURN(FALSE);
469  }
470 
471  if (Window) UserRefObjectCo(Window, &Ref);
472 
474 
476 
477  RETURN(ret);
478 
479 CLEANUP:
480  TRACE("Leave NtUserHideCaret, ret=%i\n",_ret_);
481  UserLeave();
482  END_CLEANUP;
483 }
UINT_PTR FASTCALL IntSetTimer(PWND Window, UINT_PTR IDEvent, UINT Elapse, TIMERPROC TimerFunc, INT Type)
Definition: timer.c:177
VOID FASTCALL UserEnterShared(VOID)
Definition: ntuser.c:238
BOOL NTAPI GreDeleteObject(HGDIOBJ hobj)
Definition: gdiobj.c:1158
#define CLEANUP
Definition: ntuser.h:5
__kernel_entry W32KAPI INT APIENTRY NtGdiIntersectClipRect(_In_ HDC hdc, _In_ INT xLeft, _In_ INT yTop, _In_ INT xRight, _In_ INT yBottom)
Definition: cliprgn.c:486
long y
Definition: polytest.cpp:48
__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:984
#define Y(I)
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
long x
Definition: polytest.cpp:48
#define TRUE
Definition: types.h:120
#define ASSERT_REFS_CO(_obj_)
Definition: userfuncs.h:14
#define IDCARETTIMER
Definition: undocuser.h:80
VOID FASTCALL IntNotifyWinEvent(DWORD Event, PWND pWnd, LONG idObject, LONG idChild, DWORD flags)
Definition: event.c:179
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
BOOL FASTCALL IntKillTimer(PWND Window, UINT_PTR IDEvent, BOOL SystemTimer)
Definition: timer.c:573
LONG NTSTATUS
Definition: precomp.h:26
static HDC
Definition: imagelist.c:92
#define CALLBACK
Definition: compat.h:35
PSERVERINFO gpsi
Definition: imm.c:18
HWND hWnd
Definition: settings.c:17
__kernel_entry W32KAPI BOOL APIENTRY NtGdiRestoreDC(_In_ HDC hdc, _In_ INT iLevel)
__kernel_entry W32KAPI HBITMAP APIENTRY NtGdiSelectBitmap(_In_ HDC hdc, _In_ HBITMAP hbm)
LONG top
Definition: windef.h:307
static __inline VOID UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry)
Definition: object.h:27
BOOL APIENTRY NtUserHideCaret(HWND hWnd OPTIONAL)
Definition: caret.c:456
HANDLE HWND
Definition: compat.h:19
#define DCX_USESTYLE
Definition: GetDCEx.c:10
HDC FASTCALL UserGetDCEx(PWND Window OPTIONAL, HANDLE ClipRegion, ULONG Flags)
#define MmCopyToCaller(x, y, z)
Definition: mmcopy.h:19
LONG left
Definition: windef.h:306
VOID FASTCALL IntGetClientRect(PWND WindowObject, RECTL *Rect)
Definition: winpos.c:91
LONG right
Definition: windef.h:308
#define FASTCALL
Definition: nt_native.h:50
int32_t INT
Definition: typedefs.h:58
#define RETURN(x)
BOOL NTAPI GreGetBitmapDimension(_In_ HBITMAP hBitmap, _Out_ LPSIZE psizDim)
Definition: bitmaps.c:453
Definition: window.c:28
__kernel_entry W32KAPI INT APIENTRY NtGdiSaveDC(_In_ HDC hdc)
#define FALSE
Definition: types.h:117
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
BOOL FASTCALL co_IntDestroyCaret(PTHREADINFO Win32Thread)
Definition: caret.c:159
unsigned int BOOL
Definition: ntddk_ex.h:94
static __inline VOID UserDerefObjectCo(PVOID obj)
Definition: object.h:40
HBITMAP Bitmap
Definition: ntusrtyp.h:130
#define CHILDID_SELF
Definition: winable.h:14
Definition: object.h:3
__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)
LONG cx
Definition: windef.h:334
BOOL APIENTRY NtUserGetCaretPos(LPPOINT lpPoint)
Definition: caret.c:394
PWND FASTCALL UserGetWindowObject(HWND hWnd)
Definition: window.c:126
#define DSTINVERT
Definition: wingdi.h:327
LONG NTAPI UserGetSystemMetrics(ULONG Index)
Definition: metric.c:208
DWORD dwTime
Definition: solitaire.cpp:26
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:245
Status
Definition: gdiplustypes.h:24
UINT APIENTRY NtUserGetCaretBlinkTime(VOID)
Definition: caret.c:379
#define TRACE(s)
Definition: solgame.cpp:4
#define TMRF_SYSTEM
Definition: timer.h:20
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ValidateHwndNoErr(hwnd)
Definition: precomp.h:84
HRGN hrgnUpdate
Definition: ntuser.h:716
unsigned long DWORD
Definition: ntddk_ex.h:95
#define DECLARE_RETURN(type)
Definition: ntuser.h:3
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
int Window
Definition: x11stubs.h:26
static BOOL FASTCALL co_IntHideCaret(PTHRDCARETINFO CaretInfo)
Definition: caret.c:143
VOID CALLBACK CaretSystemTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
Definition: caret.c:97
#define SM_CYBORDER
Definition: winuser.h:959
BOOL FASTCALL co_IntSetCaretPos(int X, int Y)
Definition: caret.c:193
int ret
HDC hdc
Definition: main.c:9
#define SM_CXBORDER
Definition: winuser.h:958
BOOL APIENTRY NtUserShowCaret(HWND hWnd OPTIONAL)
Definition: caret.c:425
THRDCARETINFO CaretInfo
Definition: msgqueue.h:92
BOOL FASTCALL co_UserShowCaret(PWND Window OPTIONAL)
Definition: caret.c:260
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:37
DBG_DEFAULT_CHANNEL(UserCaret)
__kernel_entry W32KAPI HDC APIENTRY NtGdiCreateCompatibleDC(_In_opt_ HDC hdc)
#define ERR(fmt,...)
Definition: debug.h:110
Definition: ntuser.h:688
struct _USER_MESSAGE_QUEUE * MessageQueue
Definition: win32.h:89
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:254
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
INT FASTCALL UserReleaseDC(PWND Window, HDC hDc, BOOL EndPaint)
Definition: windc.c:918
BOOL APIENTRY NtUserCreateCaret(HWND hWnd, HBITMAP hBitmap, int nWidth, int nHeight)
Definition: caret.c:308
LONG bottom
Definition: windef.h:309
char * cleanup(char *str)
Definition: wpickclick.c:99
BOOL FASTCALL co_UserHideCaret(PWND Window OPTIONAL)
Definition: caret.c:225
static HBITMAP
Definition: button.c:44
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4022
#define OBJID_CARET
Definition: winable.h:23
LONG cy
Definition: windef.h:335
static HBITMAP hBitmap
Definition: timezone.c:26
VOID FASTCALL co_IntDrawCaret(PWND pWnd, PTHRDCARETINFO CaretInfo)
Definition: caret.c:16
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:28
HDC hdcMem
Definition: welcome.c:104
#define SRCINVERT
Definition: wingdi.h:329
#define APIENTRY
Definition: api.h:79
BOOL FASTCALL IntSetCaretBlinkTime(UINT uMSeconds)
Definition: caret.c:183
#define END_CLEANUP
Definition: ntuser.h:6
#define X(b, s)
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68