ReactOS  0.4.13-dev-563-g0561610
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 /* DEFINES *****************************************************************/
14 
15 #define MIN_CARETBLINKRATE 100
16 #define MAX_CARETBLINKRATE 10000
17 
18 /* FUNCTIONS *****************************************************************/
19 
22 {
23  HDC hdc, hdcMem;
24  HBITMAP hbmOld;
25  RECT rcClient;
26  BOOL bDone = FALSE;
27 
28  if (pWnd == NULL)
29  {
30  TRACE("Null Window!\n");
31  return;
32  }
33 
34  hdc = UserGetDCEx(pWnd, NULL, DCX_USESTYLE);
35  if (!hdc)
36  {
37  ERR("GetDC failed\n");
38  return;
39  }
40 
41  if (pWnd->hrgnUpdate)
42  {
44  }
45 
46  IntGetClientRect(pWnd, &rcClient);
48  rcClient.left,
49  rcClient.top,
50  rcClient.right,
51  rcClient.bottom);
52 
53  if (CaretInfo->Bitmap)
54  {
55  if (!GreGetBitmapDimension(CaretInfo->Bitmap, &CaretInfo->Size))
56  {
57  ERR("Failed to get bitmap dimensions\n");
58  goto cleanup;
59  }
60 
62  if (hdcMem)
63  {
64  hbmOld = NtGdiSelectBitmap(hdcMem, CaretInfo->Bitmap);
65  bDone = NtGdiBitBlt(hdc,
66  CaretInfo->Pos.x,
67  CaretInfo->Pos.y,
68  CaretInfo->Size.cx,
69  CaretInfo->Size.cy,
70  hdcMem,
71  0,
72  0,
73  SRCINVERT,
74  0,
75  0);
76  NtGdiSelectBitmap(hdcMem, hbmOld);
78  }
79  }
80 
81  if (!bDone)
82  {
84  CaretInfo->Pos.x,
85  CaretInfo->Pos.y,
86  CaretInfo->Size.cx,
87  CaretInfo->Size.cy,
88  DSTINVERT);
89  }
90 
91 cleanup:
92  if (pWnd->hrgnUpdate)
93  {
94  NtGdiRestoreDC(hdc, -1);
95  }
96 
97  UserReleaseDC(pWnd, hdc, FALSE);
98 }
99 
100 VOID
101 CALLBACK
103  UINT uMsg,
104  UINT_PTR idEvent,
105  DWORD dwTime)
106 {
107  PTHREADINFO pti;
108  PUSER_MESSAGE_QUEUE ThreadQueue;
109  PWND pWnd;
110 
112  ThreadQueue = pti->MessageQueue;
113 
114  if (ThreadQueue->CaretInfo.hWnd != hwnd)
115  {
116  TRACE("Not the same caret window!\n");
117  return;
118  }
119 
120  if (hwnd)
121  {
122  pWnd = UserGetWindowObject(hwnd);
123  if (!pWnd)
124  {
125  ERR("Caret System Timer Proc has invalid window handle! %p Id: %u\n", hwnd, idEvent);
126  return;
127  }
128  }
129  else
130  {
131  TRACE( "Windowless Caret Timer Running!\n" );
132  return;
133  }
134 
135  switch (idEvent)
136  {
137  case IDCARETTIMER:
138  {
139  ThreadQueue->CaretInfo.Showing = (ThreadQueue->CaretInfo.Showing ? 0 : 1);
140  co_IntDrawCaret(pWnd, &ThreadQueue->CaretInfo);
141  }
142  }
143  return;
144 }
145 
146 static
149 {
150  PWND pWnd;
151  if(CaretInfo->hWnd && CaretInfo->Visible && CaretInfo->Showing)
152  {
153  pWnd = UserGetWindowObject(CaretInfo->hWnd);
154  CaretInfo->Showing = 0;
155 
156  co_IntDrawCaret(pWnd, CaretInfo);
157  IntNotifyWinEvent(EVENT_OBJECT_HIDE, pWnd, OBJID_CARET, CHILDID_SELF, 0);
158  return TRUE;
159  }
160  return FALSE;
161 }
162 
165 {
166  PUSER_MESSAGE_QUEUE ThreadQueue;
167  PWND pWnd;
168  ThreadQueue = Win32Thread->MessageQueue;
169 
170  if (!ThreadQueue)
171  return FALSE;
172 
173  pWnd = ValidateHwndNoErr(ThreadQueue->CaretInfo.hWnd);
174  co_IntHideCaret(&ThreadQueue->CaretInfo);
175  ThreadQueue->CaretInfo.Bitmap = (HBITMAP)0;
176  ThreadQueue->CaretInfo.hWnd = (HWND)0;
177  ThreadQueue->CaretInfo.Size.cx = ThreadQueue->CaretInfo.Size.cy = 0;
178  ThreadQueue->CaretInfo.Showing = 0;
179  ThreadQueue->CaretInfo.Visible = 0;
180  if (pWnd)
181  {
182  IntNotifyWinEvent(EVENT_OBJECT_DESTROY, pWnd, OBJID_CARET, CHILDID_SELF, 0);
183  }
184  return TRUE;
185 }
186 
189 {
190  /* Don't save the new value to the registry! */
191 
192  /* Windows doesn't do this check */
193  if((uMSeconds < MIN_CARETBLINKRATE) || (uMSeconds > MAX_CARETBLINKRATE))
194  {
196  return FALSE;
197  }
198 
199  gpsi->dtCaretBlink = uMSeconds;
200 
201  return TRUE;
202 }
203 
206 {
207  PTHREADINFO pti;
208  PWND pWnd;
209  PUSER_MESSAGE_QUEUE ThreadQueue;
210 
212  ThreadQueue = pti->MessageQueue;
213 
214  if(ThreadQueue->CaretInfo.hWnd)
215  {
216  pWnd = UserGetWindowObject(ThreadQueue->CaretInfo.hWnd);
217  if(ThreadQueue->CaretInfo.Pos.x != X || ThreadQueue->CaretInfo.Pos.y != Y)
218  {
219  co_IntHideCaret(&ThreadQueue->CaretInfo);
220  ThreadQueue->CaretInfo.Showing = 1;
221  ThreadQueue->CaretInfo.Pos.x = X;
222  ThreadQueue->CaretInfo.Pos.y = Y;
223  co_IntDrawCaret(pWnd, &ThreadQueue->CaretInfo);
224 
226  IntNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE, pWnd, OBJID_CARET, CHILDID_SELF, 0);
227  }
228  return TRUE;
229  }
230 
231  return FALSE;
232 }
233 
235 {
236  PTHREADINFO pti;
237  PUSER_MESSAGE_QUEUE ThreadQueue;
238 
240 
241  if(Window && Window->head.pti->pEThread != PsGetCurrentThread())
242  {
244  return FALSE;
245  }
246 
248  ThreadQueue = pti->MessageQueue;
249 
250  if(Window && ThreadQueue->CaretInfo.hWnd != Window->head.h)
251  {
253  return FALSE;
254  }
255 
256  if(ThreadQueue->CaretInfo.Visible)
257  {
258  PWND pwnd = UserGetWindowObject(ThreadQueue->CaretInfo.hWnd);
260 
261  co_IntHideCaret(&ThreadQueue->CaretInfo);
262  ThreadQueue->CaretInfo.Visible = 0;
263  ThreadQueue->CaretInfo.Showing = 0;
264  }
265 
266  return TRUE;
267 }
268 
270 {
271  PTHREADINFO pti;
272  PUSER_MESSAGE_QUEUE ThreadQueue;
273  PWND pWnd = NULL;
274 
276 
277  if(Window && Window->head.pti->pEThread != PsGetCurrentThread())
278  {
280  return FALSE;
281  }
282 
284  ThreadQueue = pti->MessageQueue;
285 
286  if(Window && ThreadQueue->CaretInfo.hWnd != Window->head.h)
287  {
289  return FALSE;
290  }
291 
292  if (!ThreadQueue->CaretInfo.Visible)
293  {
294  ThreadQueue->CaretInfo.Visible = 1;
295  pWnd = ValidateHwndNoErr(ThreadQueue->CaretInfo.hWnd);
296  if (!ThreadQueue->CaretInfo.Showing && pWnd)
297  {
298  IntNotifyWinEvent(EVENT_OBJECT_SHOW, pWnd, OBJID_CARET, OBJID_CARET, 0);
299  }
301  }
302  return TRUE;
303 }
304 
305 /* SYSCALLS *****************************************************************/
306 
307 BOOL
308 APIENTRY
310  HWND hWnd,
312  int nWidth,
313  int nHeight)
314 {
315  PWND Window;
316  PTHREADINFO pti;
317  PUSER_MESSAGE_QUEUE ThreadQueue;
319 
320  TRACE("Enter NtUserCreateCaret\n");
322 
324  {
325  RETURN(FALSE);
326  }
327 
328  if(Window->head.pti->pEThread != PsGetCurrentThread())
329  {
331  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  RETURN(TRUE);
371 
372 CLEANUP:
373  TRACE("Leave NtUserCreateCaret, ret=%i\n",_ret_);
374  UserLeave();
375  END_CLEANUP;
376 }
377 
378 UINT
379 APIENTRY
381 {
382  UINT ret;
383 
384  UserEnterShared();
385 
386  ret = gpsi->dtCaretBlink;
387 
388  UserLeave();
389 
390  return ret;
391 }
392 
393 BOOL
394 APIENTRY
396  LPPOINT lpPoint)
397 {
398  PTHREADINFO pti;
399  PUSER_MESSAGE_QUEUE ThreadQueue;
402 
403  TRACE("Enter NtUserGetCaretPos\n");
404  UserEnterShared();
405 
407  ThreadQueue = pti->MessageQueue;
408 
409  Status = MmCopyToCaller(lpPoint, &ThreadQueue->CaretInfo.Pos, sizeof(POINT));
410  if(!NT_SUCCESS(Status))
411  {
413  RETURN(FALSE);
414  }
415 
416  RETURN(TRUE);
417 
418 CLEANUP:
419  TRACE("Leave NtUserGetCaretPos, ret=%i\n",_ret_);
420  UserLeave();
421  END_CLEANUP;
422 }
423 
424 BOOL
425 APIENTRY
427 {
428  PWND Window = NULL;
431  BOOL ret;
432 
433  TRACE("Enter NtUserShowCaret\n");
435 
436  if(hWnd && !(Window = UserGetWindowObject(hWnd)))
437  {
438  RETURN(FALSE);
439  }
440 
441  if (Window) UserRefObjectCo(Window, &Ref);
442 
444 
446 
447  RETURN(ret);
448 
449 CLEANUP:
450  TRACE("Leave NtUserShowCaret, ret=%i\n",_ret_);
451  UserLeave();
452  END_CLEANUP;
453 }
454 
455 BOOL
456 APIENTRY
458 {
459  PWND Window = NULL;
462  BOOL ret;
463 
464  TRACE("Enter NtUserHideCaret\n");
466 
467  if(hWnd && !(Window = UserGetWindowObject(hWnd)))
468  {
469  RETURN(FALSE);
470  }
471 
472  if (Window) UserRefObjectCo(Window, &Ref);
473 
475 
477 
478  RETURN(ret);
479 
480 CLEANUP:
481  TRACE("Leave NtUserHideCaret, ret=%i\n",_ret_);
482  UserLeave();
483  END_CLEANUP;
484 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
UINT_PTR FASTCALL IntSetTimer(PWND Window, UINT_PTR IDEvent, UINT Elapse, TIMERPROC TimerFunc, INT Type)
Definition: timer.c:177
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
VOID FASTCALL UserEnterShared(VOID)
Definition: ntuser.c:241
BOOL NTAPI GreDeleteObject(HGDIOBJ hobj)
Definition: gdiobj.c:1155
#define TRUE
Definition: types.h:120
PWND FASTCALL ValidateHwndNoErr(HWND hWnd)
Definition: window.c:96
#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:503
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:924
#define Y(I)
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
long x
Definition: polytest.cpp:48
#define ASSERT_REFS_CO(_obj_)
Definition: userfuncs.h:13
#define IDCARETTIMER
Definition: undocuser.h:78
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:27
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:292
static __inline VOID UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry)
Definition: object.h:25
BOOL APIENTRY NtUserHideCaret(HWND hWnd OPTIONAL)
Definition: caret.c:457
HANDLE HWND
Definition: compat.h:13
#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:291
VOID FASTCALL IntGetClientRect(PWND WindowObject, RECTL *Rect)
Definition: winpos.c:91
LONG right
Definition: windef.h:293
#define FASTCALL
Definition: nt_native.h:50
PSERVERINFO gpsi
Definition: main.c:27
BOOL NTAPI GreGetBitmapDimension(_In_ HBITMAP hBitmap, _Out_ LPSIZE psizDim)
Definition: bitmaps.c:448
Definition: window.c:29
__kernel_entry W32KAPI INT APIENTRY NtGdiSaveDC(_In_ HDC hdc)
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
BOOL FASTCALL co_IntDestroyCaret(PTHREADINFO Win32Thread)
Definition: caret.c:164
unsigned int BOOL
Definition: ntddk_ex.h:94
static __inline VOID UserDerefObjectCo(PVOID obj)
Definition: object.h:38
#define MIN_CARETBLINKRATE
Definition: caret.c:15
HBITMAP Bitmap
Definition: ntusrtyp.h:130
#define CHILDID_SELF
Definition: winable.h:14
Definition: object.h:3
smooth NULL
Definition: ftsmooth.c:416
__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:319
BOOL APIENTRY NtUserGetCaretPos(LPPOINT lpPoint)
Definition: caret.c:395
PWND FASTCALL UserGetWindowObject(HWND hWnd)
Definition: window.c:103
#define DSTINVERT
Definition: wingdi.h:326
LONG NTAPI UserGetSystemMetrics(ULONG Index)
Definition: metric.c:180
DWORD dwTime
Definition: solitaire.cpp:25
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:247
UINT APIENTRY NtUserGetCaretBlinkTime(VOID)
Definition: caret.c:380
#define TRACE(s)
Definition: solgame.cpp:4
#define TMRF_SYSTEM
Definition: timer.h:20
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define MAX_CARETBLINKRATE
Definition: caret.c:16
HRGN hrgnUpdate
Definition: ntuser.h:685
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:148
VOID CALLBACK CaretSystemTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
Definition: caret.c:102
#define SM_CYBORDER
Definition: winuser.h:955
BOOL FASTCALL co_IntSetCaretPos(int X, int Y)
Definition: caret.c:205
int ret
HDC hdc
Definition: main.c:9
#define SM_CXBORDER
Definition: winuser.h:954
BOOL APIENTRY NtUserShowCaret(HWND hWnd OPTIONAL)
Definition: caret.c:426
THRDCARETINFO CaretInfo
Definition: msgqueue.h:92
BOOL FASTCALL co_UserShowCaret(PWND Window OPTIONAL)
Definition: caret.c:269
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
DBG_DEFAULT_CHANNEL(UserCaret)
__kernel_entry W32KAPI HDC APIENTRY NtGdiCreateCompatibleDC(_In_opt_ HDC hdc)
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:109
Definition: ntuser.h:657
struct _USER_MESSAGE_QUEUE * MessageQueue
Definition: win32.h:88
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:255
unsigned int UINT
Definition: ndis.h:50
INT FASTCALL UserReleaseDC(PWND Window, HDC hDc, BOOL EndPaint)
Definition: windc.c:917
BOOL APIENTRY NtUserCreateCaret(HWND hWnd, HBITMAP hBitmap, int nWidth, int nHeight)
Definition: caret.c:309
LONG bottom
Definition: windef.h:294
char * cleanup(char *str)
Definition: wpickclick.c:99
BOOL FASTCALL co_UserHideCaret(PWND Window OPTIONAL)
Definition: caret.c:234
static HBITMAP
Definition: button.c:44
#define OBJID_CARET
Definition: winable.h:23
LONG cy
Definition: windef.h:320
static HBITMAP hBitmap
Definition: timezone.c:35
VOID FASTCALL co_IntDrawCaret(PWND pWnd, PTHRDCARETINFO CaretInfo)
Definition: caret.c:21
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27
HDC hdcMem
Definition: welcome.c:104
#define RETURN(rrr)
Definition: decompress.c:40
#define SRCINVERT
Definition: wingdi.h:328
#define APIENTRY
Definition: api.h:79
BOOL FASTCALL IntSetCaretBlinkTime(UINT uMSeconds)
Definition: caret.c:188
#define END_CLEANUP
Definition: ntuser.h:6
#define X(b, s)
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68