Add information letting us know creation deletion of services has worked.
[reactos.git] / reactos / subsys / win32k / ntuser / caret.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * PURPOSE: Caret functions
6 * FILE: subsys/win32k/ntuser/caret.c
7 * PROGRAMER: Thomas Weidenmueller (w3seek@users.sourceforge.net)
8 * REVISION HISTORY:
9 * 10/15/2003 Created
10 */
11
12 /* INCLUDES ******************************************************************/
13
14 #include <w32k.h>
15
16 #define NDEBUG
17 #include <debug.h>
18
19 /* DEFINES *****************************************************************/
20
21 #define MIN_CARETBLINKRATE 100
22 #define MAX_CARETBLINKRATE 10000
23 #define DEFAULT_CARETBLINKRATE 530
24 #define CARET_REGKEY L"\\Registry\\User\\.Default\\Control Panel\\Desktop"
25 #define CARET_VALUENAME L"CursorBlinkRate"
26
27 /* FUNCTIONS *****************************************************************/
28
29 static
30 BOOL FASTCALL
31 co_IntHideCaret(PTHRDCARETINFO CaretInfo)
32 {
33 if(CaretInfo->hWnd && CaretInfo->Visible && CaretInfo->Showing)
34 {
35 co_IntSendMessage(CaretInfo->hWnd, WM_SYSTIMER, IDCARETTIMER, 0);
36 CaretInfo->Showing = 0;
37 return TRUE;
38 }
39 return FALSE;
40 }
41
42 BOOL FASTCALL
43 co_IntDestroyCaret(PW32THREAD Win32Thread)
44 {
45 PUSER_MESSAGE_QUEUE ThreadQueue;
46 ThreadQueue = (PUSER_MESSAGE_QUEUE)Win32Thread->MessageQueue;
47
48 if(!ThreadQueue || !ThreadQueue->CaretInfo)
49 return FALSE;
50
51 co_IntHideCaret(ThreadQueue->CaretInfo);
52 ThreadQueue->CaretInfo->Bitmap = (HBITMAP)0;
53 ThreadQueue->CaretInfo->hWnd = (HWND)0;
54 ThreadQueue->CaretInfo->Size.cx = ThreadQueue->CaretInfo->Size.cy = 0;
55 ThreadQueue->CaretInfo->Showing = 0;
56 ThreadQueue->CaretInfo->Visible = 0;
57 return TRUE;
58 }
59
60 BOOL FASTCALL
61 IntSetCaretBlinkTime(UINT uMSeconds)
62 {
63 /* Don't save the new value to the registry! */
64 PWINSTATION_OBJECT WinStaObject = PsGetWin32Thread()->Desktop->WindowStation;
65
66 /* windows doesn't do this check */
67 if((uMSeconds < MIN_CARETBLINKRATE) || (uMSeconds > MAX_CARETBLINKRATE))
68 {
69 SetLastWin32Error(ERROR_INVALID_PARAMETER);
70 ObDereferenceObject(WinStaObject);
71 return FALSE;
72 }
73
74 WinStaObject->CaretBlinkRate = uMSeconds;
75
76 return TRUE;
77 }
78
79 static
80 UINT FASTCALL
81 IntQueryCaretBlinkRate(VOID)
82 {
83 UNICODE_STRING KeyName = RTL_CONSTANT_STRING(CARET_REGKEY);
84 UNICODE_STRING ValueName = RTL_CONSTANT_STRING(CARET_VALUENAME);
85 NTSTATUS Status;
86 HANDLE KeyHandle = NULL;
87 OBJECT_ATTRIBUTES KeyAttributes;
88 PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo;
89 ULONG Length = 0;
90 ULONG ResLength = 0;
91 ULONG Val = 0;
92
93 InitializeObjectAttributes(&KeyAttributes, &KeyName, OBJ_CASE_INSENSITIVE,
94 NULL, NULL);
95
96 Status = ZwOpenKey(&KeyHandle, KEY_READ, &KeyAttributes);
97 if(!NT_SUCCESS(Status))
98 {
99 return 0;
100 }
101
102 Status = ZwQueryValueKey(KeyHandle, &ValueName, KeyValuePartialInformation,
103 0, 0, &ResLength);
104 if((Status != STATUS_BUFFER_TOO_SMALL))
105 {
106 NtClose(KeyHandle);
107 return 0;
108 }
109
110 ResLength += sizeof(KEY_VALUE_PARTIAL_INFORMATION);
111 KeyValuePartialInfo = ExAllocatePoolWithTag(PagedPool, ResLength, TAG_STRING);
112 Length = ResLength;
113
114 if(!KeyValuePartialInfo)
115 {
116 NtClose(KeyHandle);
117 return 0;
118 }
119
120 Status = ZwQueryValueKey(KeyHandle, &ValueName, KeyValuePartialInformation,
121 (PVOID)KeyValuePartialInfo, Length, &ResLength);
122 if(!NT_SUCCESS(Status) || (KeyValuePartialInfo->Type != REG_SZ))
123 {
124 NtClose(KeyHandle);
125 ExFreePool(KeyValuePartialInfo);
126 return 0;
127 }
128
129 ValueName.Length = KeyValuePartialInfo->DataLength;
130 ValueName.MaximumLength = KeyValuePartialInfo->DataLength;
131 ValueName.Buffer = (PWSTR)KeyValuePartialInfo->Data;
132
133 Status = RtlUnicodeStringToInteger(&ValueName, 0, &Val);
134 if(!NT_SUCCESS(Status))
135 {
136 Val = 0;
137 }
138
139 ExFreePool(KeyValuePartialInfo);
140 NtClose(KeyHandle);
141
142 return (UINT)Val;
143 }
144
145 static
146 UINT FASTCALL
147 IntGetCaretBlinkTime(VOID)
148 {
149 PWINSTATION_OBJECT WinStaObject;
150 UINT Ret;
151
152 WinStaObject = PsGetWin32Thread()->Desktop->WindowStation;
153
154 Ret = WinStaObject->CaretBlinkRate;
155 if(!Ret)
156 {
157 /* load it from the registry the first call only! */
158 Ret = WinStaObject->CaretBlinkRate = IntQueryCaretBlinkRate();
159 }
160
161 /* windows doesn't do this check */
162 if((Ret < MIN_CARETBLINKRATE) || (Ret > MAX_CARETBLINKRATE))
163 {
164 Ret = DEFAULT_CARETBLINKRATE;
165 }
166
167 return Ret;
168 }
169
170
171 BOOL FASTCALL
172 co_IntSetCaretPos(int X, int Y)
173 {
174 PUSER_MESSAGE_QUEUE ThreadQueue;
175 ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
176
177 if(ThreadQueue->CaretInfo->hWnd)
178 {
179 if(ThreadQueue->CaretInfo->Pos.x != X || ThreadQueue->CaretInfo->Pos.y != Y)
180 {
181 co_IntHideCaret(ThreadQueue->CaretInfo);
182 ThreadQueue->CaretInfo->Showing = 0;
183 ThreadQueue->CaretInfo->Pos.x = X;
184 ThreadQueue->CaretInfo->Pos.y = Y;
185 co_IntSendMessage(ThreadQueue->CaretInfo->hWnd, WM_SYSTIMER, IDCARETTIMER, 0);
186 IntSetTimer(ThreadQueue->CaretInfo->hWnd, IDCARETTIMER, IntGetCaretBlinkTime(), NULL, TRUE);
187 }
188 return TRUE;
189 }
190
191 return FALSE;
192 }
193
194 BOOL FASTCALL
195 IntSwitchCaretShowing(PVOID Info)
196 {
197 PUSER_MESSAGE_QUEUE ThreadQueue;
198 ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
199
200 if(ThreadQueue->CaretInfo->hWnd)
201 {
202 ThreadQueue->CaretInfo->Showing = (ThreadQueue->CaretInfo->Showing ? 0 : 1);
203 MmCopyToCaller(Info, ThreadQueue->CaretInfo, sizeof(THRDCARETINFO));
204 return TRUE;
205 }
206
207 return FALSE;
208 }
209
210 #if 0 //unused
211 static
212 VOID FASTCALL
213 co_IntDrawCaret(HWND hWnd)
214 {
215 PUSER_MESSAGE_QUEUE ThreadQueue;
216 ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
217
218 if(ThreadQueue->CaretInfo->hWnd && ThreadQueue->CaretInfo->Visible &&
219 ThreadQueue->CaretInfo->Showing)
220 {
221 co_IntSendMessage(ThreadQueue->CaretInfo->hWnd, WM_SYSTIMER, IDCARETTIMER, 0);
222 ThreadQueue->CaretInfo->Showing = 1;
223 }
224 }
225 #endif
226
227
228
229 BOOL FASTCALL co_UserHideCaret(PWINDOW_OBJECT Window OPTIONAL)
230 {
231 PUSER_MESSAGE_QUEUE ThreadQueue;
232
233 if (Window) ASSERT_REFS_CO(Window);
234
235 if(Window && Window->OwnerThread != PsGetCurrentThread())
236 {
237 SetLastWin32Error(ERROR_ACCESS_DENIED);
238 return FALSE;
239 }
240
241 ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
242
243 if(Window && ThreadQueue->CaretInfo->hWnd != Window->hSelf)
244 {
245 SetLastWin32Error(ERROR_ACCESS_DENIED);
246 return FALSE;
247 }
248
249 if(ThreadQueue->CaretInfo->Visible)
250 {
251 IntKillTimer(ThreadQueue->CaretInfo->hWnd, IDCARETTIMER, TRUE);
252
253 co_IntHideCaret(ThreadQueue->CaretInfo);
254 ThreadQueue->CaretInfo->Visible = 0;
255 ThreadQueue->CaretInfo->Showing = 0;
256 }
257
258 return TRUE;
259 }
260
261
262 BOOL FASTCALL co_UserShowCaret(PWINDOW_OBJECT Window OPTIONAL)
263 {
264 PUSER_MESSAGE_QUEUE ThreadQueue;
265
266 if (Window) ASSERT_REFS_CO(Window);
267
268 if(Window && Window->OwnerThread != PsGetCurrentThread())
269 {
270 SetLastWin32Error(ERROR_ACCESS_DENIED);
271 return FALSE;
272 }
273
274 ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
275
276 if(Window && ThreadQueue->CaretInfo->hWnd != Window->hSelf)
277 {
278 SetLastWin32Error(ERROR_ACCESS_DENIED);
279 return FALSE;
280 }
281
282 if(!ThreadQueue->CaretInfo->Visible)
283 {
284 ThreadQueue->CaretInfo->Visible = 1;
285 if(!ThreadQueue->CaretInfo->Showing)
286 {
287 co_IntSendMessage(ThreadQueue->CaretInfo->hWnd, WM_SYSTIMER, IDCARETTIMER, 0);
288 }
289 IntSetTimer(ThreadQueue->CaretInfo->hWnd, IDCARETTIMER, IntGetCaretBlinkTime(), NULL, TRUE);
290 }
291
292 return TRUE;
293 }
294
295
296 /* SYSCALLS *****************************************************************/
297
298 BOOL
299 STDCALL
300 NtUserCreateCaret(
301 HWND hWnd,
302 HBITMAP hBitmap,
303 int nWidth,
304 int nHeight)
305 {
306 PWINDOW_OBJECT Window;
307 PUSER_MESSAGE_QUEUE ThreadQueue;
308 DECLARE_RETURN(BOOL);
309
310 DPRINT("Enter NtUserCreateCaret\n");
311 UserEnterExclusive();
312
313 if(!(Window = UserGetWindowObject(hWnd)))
314 {
315 RETURN(FALSE);
316 }
317
318 if(Window->OwnerThread != PsGetCurrentThread())
319 {
320 SetLastWin32Error(ERROR_ACCESS_DENIED);
321 RETURN(FALSE);
322 }
323
324 ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
325
326 if (ThreadQueue->CaretInfo->Visible)
327 {
328 IntKillTimer(hWnd, IDCARETTIMER, TRUE);
329 co_IntHideCaret(ThreadQueue->CaretInfo);
330 }
331
332 ThreadQueue->CaretInfo->hWnd = hWnd;
333 if(hBitmap)
334 {
335 ThreadQueue->CaretInfo->Bitmap = hBitmap;
336 ThreadQueue->CaretInfo->Size.cx = ThreadQueue->CaretInfo->Size.cy = 0;
337 }
338 else
339 {
340 ThreadQueue->CaretInfo->Bitmap = (HBITMAP)0;
341 ThreadQueue->CaretInfo->Size.cx = nWidth;
342 ThreadQueue->CaretInfo->Size.cy = nHeight;
343 }
344 ThreadQueue->CaretInfo->Visible = 0;
345 ThreadQueue->CaretInfo->Showing = 0;
346
347 RETURN(TRUE);
348
349 CLEANUP:
350 DPRINT("Leave NtUserCreateCaret, ret=%i\n",_ret_);
351 UserLeave();
352 END_CLEANUP;
353 }
354
355 UINT
356 STDCALL
357 NtUserGetCaretBlinkTime(VOID)
358 {
359 DECLARE_RETURN(UINT);
360
361 DPRINT("Enter NtUserGetCaretBlinkTime\n");
362 UserEnterShared();
363
364 RETURN(IntGetCaretBlinkTime());
365
366 CLEANUP:
367 DPRINT("Leave NtUserGetCaretBlinkTime, ret=%i\n",_ret_);
368 UserLeave();
369 END_CLEANUP;
370 }
371
372 BOOL
373 STDCALL
374 NtUserGetCaretPos(
375 LPPOINT lpPoint)
376 {
377 PUSER_MESSAGE_QUEUE ThreadQueue;
378 NTSTATUS Status;
379 DECLARE_RETURN(BOOL);
380
381 DPRINT("Enter NtUserGetCaretPos\n");
382 UserEnterShared();
383
384 ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
385
386 Status = MmCopyToCaller(lpPoint, &(ThreadQueue->CaretInfo->Pos), sizeof(POINT));
387 if(!NT_SUCCESS(Status))
388 {
389 SetLastNtError(Status);
390 RETURN(FALSE);
391 }
392
393 RETURN(TRUE);
394
395 CLEANUP:
396 DPRINT("Leave NtUserGetCaretPos, ret=%i\n",_ret_);
397 UserLeave();
398 END_CLEANUP;
399 }
400
401
402
403 BOOL
404 STDCALL
405 NtUserShowCaret(HWND hWnd OPTIONAL, BOOL bShow)
406 {
407 PWINDOW_OBJECT Window = NULL;
408 USER_REFERENCE_ENTRY Ref;
409 DECLARE_RETURN(BOOL);
410 BOOL ret;
411
412 DPRINT("Enter NtUserShowCaret\n");
413 UserEnterExclusive();
414
415 if(hWnd && !(Window = UserGetWindowObject(hWnd)))
416 {
417 RETURN(FALSE);
418 }
419
420 if (Window) UserRefObjectCo(Window, &Ref);
421
422 if (bShow)
423 ret = co_UserShowCaret(Window);
424 else
425 ret = co_UserHideCaret(Window);
426
427 if (Window) UserDerefObjectCo(Window);
428
429 RETURN(ret);
430
431 CLEANUP:
432 DPRINT("Leave NtUserShowCaret, ret=%i\n",_ret_);
433 UserLeave();
434 END_CLEANUP;
435 }