ReactOS  0.4.15-dev-1377-ga59cecd
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.Pos.x = X;
221  ThreadQueue->CaretInfo.Pos.y = Y;
222  if (ThreadQueue->CaretInfo.Visible)
223  {
224  ThreadQueue->CaretInfo.Showing = 1;
225  co_IntDrawCaret(pWnd, &ThreadQueue->CaretInfo);
226  }
227 
229  IntNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE, pWnd, OBJID_CARET, CHILDID_SELF, 0);
230  }
231  return TRUE;
232  }
233 
234  return FALSE;
235 }
236 
238 {
239  PTHREADINFO pti;
240  PUSER_MESSAGE_QUEUE ThreadQueue;
241 
243 
244  if(Window && Window->head.pti->pEThread != PsGetCurrentThread())
245  {
247  return FALSE;
248  }
249 
251  ThreadQueue = pti->MessageQueue;
252 
253  if(Window && ThreadQueue->CaretInfo.hWnd != Window->head.h)
254  {
256  return FALSE;
257  }
258 
259  if(ThreadQueue->CaretInfo.Visible)
260  {
261  PWND pwnd = UserGetWindowObject(ThreadQueue->CaretInfo.hWnd);
263 
264  co_IntHideCaret(&ThreadQueue->CaretInfo);
265  ThreadQueue->CaretInfo.Visible = 0;
266  ThreadQueue->CaretInfo.Showing = 0;
267  }
268 
269  return TRUE;
270 }
271 
273 {
274  PTHREADINFO pti;
275  PUSER_MESSAGE_QUEUE ThreadQueue;
276  PWND pWnd = NULL;
277 
279 
280  if(Window && Window->head.pti->pEThread != PsGetCurrentThread())
281  {
283  return FALSE;
284  }
285 
287  ThreadQueue = pti->MessageQueue;
288 
289  if(Window && ThreadQueue->CaretInfo.hWnd != Window->head.h)
290  {
292  return FALSE;
293  }
294 
295  if (!ThreadQueue->CaretInfo.Visible)
296  {
297  ThreadQueue->CaretInfo.Visible = 1;
298  pWnd = ValidateHwndNoErr(ThreadQueue->CaretInfo.hWnd);
299  if (!ThreadQueue->CaretInfo.Showing && pWnd)
300  {
301  IntNotifyWinEvent(EVENT_OBJECT_SHOW, pWnd, OBJID_CARET, OBJID_CARET, 0);
302  }
304  }
305  return TRUE;
306 }
307 
308 /* SYSCALLS *****************************************************************/
309 
310 BOOL
311 APIENTRY
313  HWND hWnd,
315  int nWidth,
316  int nHeight)
317 {
318  PWND Window;
319  PTHREADINFO pti;
320  PUSER_MESSAGE_QUEUE ThreadQueue;
322 
323  TRACE("Enter NtUserCreateCaret\n");
325 
327  {
328  RETURN(FALSE);
329  }
330 
331  if(Window->head.pti->pEThread != PsGetCurrentThread())
332  {
334  RETURN(FALSE);
335  }
336 
338  ThreadQueue = pti->MessageQueue;
339 
340  if (ThreadQueue->CaretInfo.Visible)
341  {
343  co_IntHideCaret(&ThreadQueue->CaretInfo);
344  }
345 
346  ThreadQueue->CaretInfo.hWnd = hWnd;
347  if(hBitmap)
348  {
349  ThreadQueue->CaretInfo.Bitmap = hBitmap;
350  ThreadQueue->CaretInfo.Size.cx = ThreadQueue->CaretInfo.Size.cy = 0;
351  }
352  else
353  {
354  if (nWidth == 0)
355  {
357  }
358  if (nHeight == 0)
359  {
361  }
362  ThreadQueue->CaretInfo.Bitmap = (HBITMAP)0;
363  ThreadQueue->CaretInfo.Size.cx = nWidth;
364  ThreadQueue->CaretInfo.Size.cy = nHeight;
365  }
366  ThreadQueue->CaretInfo.Visible = 0;
367  ThreadQueue->CaretInfo.Showing = 0;
368 
370 
371  IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window, OBJID_CARET, CHILDID_SELF, 0);
372 
373  RETURN(TRUE);
374 
375 CLEANUP:
376  TRACE("Leave NtUserCreateCaret, ret=%i\n",_ret_);
377  UserLeave();
378  END_CLEANUP;
379 }
380 
381 UINT
382 APIENTRY
384 {
385  UINT ret;
386 
387  UserEnterShared();
388 
389  ret = gpsi->dtCaretBlink;
390 
391  UserLeave();
392 
393  return ret;
394 }
395 
396 BOOL
397 APIENTRY
399  LPPOINT lpPoint)
400 {
401  PTHREADINFO pti;
402  PUSER_MESSAGE_QUEUE ThreadQueue;
405 
406  TRACE("Enter NtUserGetCaretPos\n");
407  UserEnterShared();
408 
410  ThreadQueue = pti->MessageQueue;
411 
412  Status = MmCopyToCaller(lpPoint, &ThreadQueue->CaretInfo.Pos, sizeof(POINT));
413  if(!NT_SUCCESS(Status))
414  {
416  RETURN(FALSE);
417  }
418 
419  RETURN(TRUE);
420 
421 CLEANUP:
422  TRACE("Leave NtUserGetCaretPos, ret=%i\n",_ret_);
423  UserLeave();
424  END_CLEANUP;
425 }
426 
427 BOOL
428 APIENTRY
430 {
431  PWND Window = NULL;
434  BOOL ret;
435 
436  TRACE("Enter NtUserShowCaret\n");
438 
439  if(hWnd && !(Window = UserGetWindowObject(hWnd)))
440  {
441  RETURN(FALSE);
442  }
443 
444  if (Window) UserRefObjectCo(Window, &Ref);
445 
447 
449 
450  RETURN(ret);
451 
452 CLEANUP:
453  TRACE("Leave NtUserShowCaret, ret=%i\n",_ret_);
454  UserLeave();
455  END_CLEANUP;
456 }
457 
458 BOOL
459 APIENTRY
461 {
462  PWND Window = NULL;
465  BOOL ret;
466 
467  TRACE("Enter NtUserHideCaret\n");
469 
470  if(hWnd && !(Window = UserGetWindowObject(hWnd)))
471  {
472  RETURN(FALSE);
473  }
474 
475  if (Window) UserRefObjectCo(Window, &Ref);
476 
478 
480 
481  RETURN(ret);
482 
483 CLEANUP:
484  TRACE("Leave NtUserHideCaret, ret=%i\n",_ret_);
485  UserLeave();
486  END_CLEANUP;
487 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
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:1158
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: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:919
#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: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:35
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:25
BOOL APIENTRY NtUserHideCaret(HWND hWnd OPTIONAL)
Definition: caret.c:460
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
PSERVERINFO gpsi
Definition: main.c:27
#define RETURN(x)
BOOL NTAPI GreGetBitmapDimension(_In_ HBITMAP hBitmap, _Out_ LPSIZE psizDim)
Definition: bitmaps.c:448
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: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
__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:398
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
Status
Definition: gdiplustypes.h:24
UINT APIENTRY NtUserGetCaretBlinkTime(VOID)
Definition: caret.c:383
#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:429
THRDCARETINFO CaretInfo
Definition: msgqueue.h:92
BOOL FASTCALL co_UserShowCaret(PWND Window OPTIONAL)
Definition: caret.c:272
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
DBG_DEFAULT_CHANNEL(UserCaret)
__kernel_entry W32KAPI HDC APIENTRY NtGdiCreateCompatibleDC(_In_opt_ HDC hdc)
#define ERR(fmt,...)
Definition: debug.h:110
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
#define NULL
Definition: types.h:112
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:312
LONG bottom
Definition: windef.h:309
char * cleanup(char *str)
Definition: wpickclick.c:99
BOOL FASTCALL co_UserHideCaret(PWND Window OPTIONAL)
Definition: caret.c:237
static HBITMAP
Definition: button.c:44
#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:21
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27
HDC hdcMem
Definition: welcome.c:104
#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