1a317beb3f30f58cacffc5002c071230e373e2d4
[reactos.git] / dll / win32 / user32 / misc / desktop.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS user32.dll
5 * FILE: lib/user32/misc/desktop.c
6 * PURPOSE: Desktops
7 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * UPDATE HISTORY:
9 * 06-06-2001 CSH Created
10 */
11
12 #include <user32.h>
13
14 #include <wine/debug.h>
15 WINE_DEFAULT_DEBUG_CHANNEL(user32);
16
17 /*********************************************************************
18 * desktop class descriptor
19 */
20 #if 0 // Kept for referencing.
21 const struct builtin_class_descr DESKTOP_builtin_class =
22 {
23 WC_DESKTOP, /* name */
24 CS_DBLCLKS, /* style */
25 NULL, /* procA (winproc is Unicode only) */
26 (WNDPROC) DesktopWndProc, /* procW */
27 0, /* extra */
28 IDC_ARROW, /* cursor */
29 (HBRUSH)(COLOR_BACKGROUND+1) /* brush */
30 };
31 #endif
32 LRESULT
33 WINAPI
34 DesktopWndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
35 {
36 TRACE("Desktop Class Atom! hWnd 0x%x, Msg %d\n", hwnd, message);
37 if (message == WM_NCCREATE) return TRUE;
38 return 0; /* all other messages are ignored */
39 }
40
41 VOID
42 WINAPI
43 LogFontA2W(LPLOGFONTW pW, CONST LOGFONTA *pA)
44 {
45 #define COPYS(f,len) MultiByteToWideChar ( CP_THREAD_ACP, 0, pA->f, len, pW->f, len )
46 #define COPYN(f) pW->f = pA->f
47
48 COPYN(lfHeight);
49 COPYN(lfWidth);
50 COPYN(lfEscapement);
51 COPYN(lfOrientation);
52 COPYN(lfWeight);
53 COPYN(lfItalic);
54 COPYN(lfUnderline);
55 COPYN(lfStrikeOut);
56 COPYN(lfCharSet);
57 COPYN(lfOutPrecision);
58 COPYN(lfClipPrecision);
59 COPYN(lfQuality);
60 COPYN(lfPitchAndFamily);
61 COPYS(lfFaceName,LF_FACESIZE);
62
63 #undef COPYN
64 #undef COPYS
65 }
66
67 VOID
68 WINAPI
69 LogFontW2A(LPLOGFONTA pA, CONST LOGFONTW *pW)
70 {
71 #define COPYS(f,len) WideCharToMultiByte ( CP_THREAD_ACP, 0, pW->f, len, pA->f, len, NULL, NULL )
72 #define COPYN(f) pA->f = pW->f
73
74 COPYN(lfHeight);
75 COPYN(lfWidth);
76 COPYN(lfEscapement);
77 COPYN(lfOrientation);
78 COPYN(lfWeight);
79 COPYN(lfItalic);
80 COPYN(lfUnderline);
81 COPYN(lfStrikeOut);
82 COPYN(lfCharSet);
83 COPYN(lfOutPrecision);
84 COPYN(lfClipPrecision);
85 COPYN(lfQuality);
86 COPYN(lfPitchAndFamily);
87 COPYS(lfFaceName,LF_FACESIZE);
88
89 #undef COPYN
90 #undef COPYS
91 }
92
93 int WINAPI
94 RealGetSystemMetrics(int nIndex)
95 {
96 GetConnected();
97 // FIXME("Global Server Data -> %x\n",gpsi);
98 if (nIndex < 0 || nIndex >= SM_CMETRICS) return 0;
99 return gpsi->aiSysMet[nIndex];
100 }
101
102 /*
103 * @implemented
104 */
105 int WINAPI
106 GetSystemMetrics(int nIndex)
107 {
108 BOOL Hook;
109 int Ret = 0;
110
111 if (!gpsi) // Fixme! Hax! Need Timos delay load support?
112 {
113 return RealGetSystemMetrics(nIndex);
114 }
115
116 LOADUSERAPIHOOK
117
118 Hook = BeginIfHookedUserApiHook();
119
120 /* Bypass SEH and go direct. */
121 if (!Hook) return RealGetSystemMetrics(nIndex);
122
123 _SEH2_TRY
124 {
125 Ret = guah.GetSystemMetrics(nIndex);
126 }
127 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
128 {
129 }
130 _SEH2_END;
131
132 EndUserApiHook();
133
134 return Ret;
135 }
136
137 /*
138 * @unimplemented
139 */
140 BOOL WINAPI SetDeskWallpaper(LPCSTR filename)
141 {
142 return SystemParametersInfoA(SPI_SETDESKWALLPAPER,0,(PVOID)filename,TRUE);
143 }
144
145 BOOL WINAPI
146 RealSystemParametersInfoA(UINT uiAction,
147 UINT uiParam,
148 PVOID pvParam,
149 UINT fWinIni)
150 {
151 switch (uiAction)
152 {
153
154 case SPI_GETNONCLIENTMETRICS:
155 {
156 LPNONCLIENTMETRICSA pnclma = (LPNONCLIENTMETRICSA)pvParam;
157 NONCLIENTMETRICSW nclmw;
158 if(pnclma->cbSize != sizeof(NONCLIENTMETRICSA))
159 {
160 SetLastError(ERROR_INVALID_PARAMETER);
161 return FALSE;
162 }
163 nclmw.cbSize = sizeof(NONCLIENTMETRICSW);
164
165 if (!SystemParametersInfoW(uiAction, sizeof(NONCLIENTMETRICSW),
166 &nclmw, fWinIni))
167 return FALSE;
168
169 pnclma->iBorderWidth = nclmw.iBorderWidth;
170 pnclma->iScrollWidth = nclmw.iScrollWidth;
171 pnclma->iScrollHeight = nclmw.iScrollHeight;
172 pnclma->iCaptionWidth = nclmw.iCaptionWidth;
173 pnclma->iCaptionHeight = nclmw.iCaptionHeight;
174 pnclma->iSmCaptionWidth = nclmw.iSmCaptionWidth;
175 pnclma->iSmCaptionHeight = nclmw.iSmCaptionHeight;
176 pnclma->iMenuWidth = nclmw.iMenuWidth;
177 pnclma->iMenuHeight = nclmw.iMenuHeight;
178 LogFontW2A(&(pnclma->lfCaptionFont), &(nclmw.lfCaptionFont));
179 LogFontW2A(&(pnclma->lfSmCaptionFont), &(nclmw.lfSmCaptionFont));
180 LogFontW2A(&(pnclma->lfMenuFont), &(nclmw.lfMenuFont));
181 LogFontW2A(&(pnclma->lfStatusFont), &(nclmw.lfStatusFont));
182 LogFontW2A(&(pnclma->lfMessageFont), &(nclmw.lfMessageFont));
183 return TRUE;
184 }
185 case SPI_SETNONCLIENTMETRICS:
186 {
187 LPNONCLIENTMETRICSA pnclma = (LPNONCLIENTMETRICSA)pvParam;
188 NONCLIENTMETRICSW nclmw;
189 if(pnclma->cbSize != sizeof(NONCLIENTMETRICSA))
190 {
191 SetLastError(ERROR_INVALID_PARAMETER);
192 return FALSE;
193 }
194 nclmw.cbSize = sizeof(NONCLIENTMETRICSW);
195 nclmw.iBorderWidth = pnclma->iBorderWidth;
196 nclmw.iScrollWidth = pnclma->iScrollWidth;
197 nclmw.iScrollHeight = pnclma->iScrollHeight;
198 nclmw.iCaptionWidth = pnclma->iCaptionWidth;
199 nclmw.iCaptionHeight = pnclma->iCaptionHeight;
200 nclmw.iSmCaptionWidth = pnclma->iSmCaptionWidth;
201 nclmw.iSmCaptionHeight = pnclma->iSmCaptionHeight;
202 nclmw.iMenuWidth = pnclma->iMenuWidth;
203 nclmw.iMenuHeight = pnclma->iMenuHeight;
204 LogFontA2W(&(nclmw.lfCaptionFont), &(pnclma->lfCaptionFont));
205 LogFontA2W(&(nclmw.lfSmCaptionFont), &(pnclma->lfSmCaptionFont));
206 LogFontA2W(&(nclmw.lfMenuFont), &(pnclma->lfMenuFont));
207 LogFontA2W(&(nclmw.lfStatusFont), &(pnclma->lfStatusFont));
208 LogFontA2W(&(nclmw.lfMessageFont), &(pnclma->lfMessageFont));
209
210 return SystemParametersInfoW(uiAction, sizeof(NONCLIENTMETRICSW),
211 &nclmw, fWinIni);
212 }
213 case SPI_GETICONMETRICS:
214 {
215 LPICONMETRICSA picma = (LPICONMETRICSA)pvParam;
216 ICONMETRICSW icmw;
217 if(picma->cbSize != sizeof(ICONMETRICSA))
218 {
219 SetLastError(ERROR_INVALID_PARAMETER);
220 return FALSE;
221 }
222 icmw.cbSize = sizeof(ICONMETRICSW);
223 if (!SystemParametersInfoW(uiAction, sizeof(ICONMETRICSW),
224 &icmw, fWinIni))
225 return FALSE;
226
227 picma->iHorzSpacing = icmw.iHorzSpacing;
228 picma->iVertSpacing = icmw.iVertSpacing;
229 picma->iTitleWrap = icmw.iTitleWrap;
230 LogFontW2A(&(picma->lfFont), &(icmw.lfFont));
231 return TRUE;
232 }
233 case SPI_SETICONMETRICS:
234 {
235 LPICONMETRICSA picma = (LPICONMETRICSA)pvParam;
236 ICONMETRICSW icmw;
237 if(picma->cbSize != sizeof(ICONMETRICSA))
238 {
239 SetLastError(ERROR_INVALID_PARAMETER);
240 return FALSE;
241 }
242 icmw.cbSize = sizeof(ICONMETRICSW);
243 icmw.iHorzSpacing = picma->iHorzSpacing;
244 icmw.iVertSpacing = picma->iVertSpacing;
245 icmw.iTitleWrap = picma->iTitleWrap;
246 LogFontA2W(&(icmw.lfFont), &(picma->lfFont));
247
248 return SystemParametersInfoW(uiAction, sizeof(ICONMETRICSW),
249 &icmw, fWinIni);
250 }
251 case SPI_GETICONTITLELOGFONT:
252 {
253 LOGFONTW lfw;
254 if (!SystemParametersInfoW(uiAction, 0, &lfw, fWinIni))
255 return FALSE;
256 LogFontW2A(pvParam, &lfw);
257 return TRUE;
258 }
259 case SPI_SETICONTITLELOGFONT:
260 {
261 LPLOGFONTA plfa = (LPLOGFONTA)pvParam;
262 LOGFONTW lfw;
263 LogFontA2W(&lfw,plfa);
264 return SystemParametersInfoW(uiAction, 0, &lfw, fWinIni);
265 }
266 case SPI_GETDESKWALLPAPER:
267 {
268 BOOL Ret;
269 WCHAR awc[MAX_PATH];
270 UNICODE_STRING ustrWallpaper;
271 ANSI_STRING astrWallpaper;
272
273 Ret = NtUserSystemParametersInfo(SPI_GETDESKWALLPAPER, MAX_PATH, awc, fWinIni);
274 RtlInitUnicodeString(&ustrWallpaper, awc);
275 RtlUnicodeStringToAnsiString(&astrWallpaper, &ustrWallpaper, TRUE);
276
277 RtlCopyMemory(pvParam, astrWallpaper.Buffer, uiParam);
278 RtlFreeAnsiString(&astrWallpaper);
279 return Ret;
280 }
281
282 case SPI_SETDESKWALLPAPER:
283 {
284 NTSTATUS Status;
285 UNICODE_STRING ustrWallpaper;
286 BOOL Ret;
287
288 if (pvParam)
289 {
290 Status = RtlCreateUnicodeStringFromAsciiz(&ustrWallpaper, pvParam);
291 if (!NT_SUCCESS(Status))
292 {
293 ERR("Status = 0x%x\n", Status);
294 return FALSE;
295 }
296 pvParam = &ustrWallpaper;
297 }
298
299 Ret = NtUserSystemParametersInfo(SPI_SETDESKWALLPAPER, uiParam, pvParam, fWinIni);
300 RtlFreeUnicodeString(&ustrWallpaper);
301 return Ret;
302 }
303 }
304 return NtUserSystemParametersInfo(uiAction, uiParam, pvParam, fWinIni);
305 }
306
307 BOOL WINAPI
308 RealSystemParametersInfoW(UINT uiAction,
309 UINT uiParam,
310 PVOID pvParam,
311 UINT fWinIni)
312 {
313 switch(uiAction)
314 {
315
316 case SPI_SETDESKWALLPAPER:
317 {
318 UNICODE_STRING ustrWallpaper;
319
320 RtlInitUnicodeString(&ustrWallpaper, pvParam);
321 return NtUserSystemParametersInfo(SPI_SETDESKWALLPAPER, uiParam, &ustrWallpaper, fWinIni);
322 }
323 }
324 return NtUserSystemParametersInfo(uiAction, uiParam, pvParam, fWinIni);
325 }
326
327
328 /*
329 * @implemented
330 */
331 BOOL WINAPI
332 SystemParametersInfoA(UINT uiAction,
333 UINT uiParam,
334 PVOID pvParam,
335 UINT fWinIni)
336 {
337 BOOL Hook, Ret = FALSE;
338
339 LOADUSERAPIHOOK
340
341 Hook = BeginIfHookedUserApiHook();
342
343 /* Bypass SEH and go direct. */
344 if (!Hook) return RealSystemParametersInfoA(uiAction, uiParam, pvParam, fWinIni);
345
346 _SEH2_TRY
347 {
348 Ret = guah.SystemParametersInfoA(uiAction, uiParam, pvParam, fWinIni);
349 }
350 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
351 {
352 }
353 _SEH2_END;
354
355 EndUserApiHook();
356
357 return Ret;
358 }
359
360 /*
361 * @implemented
362 */
363 BOOL WINAPI
364 SystemParametersInfoW(UINT uiAction,
365 UINT uiParam,
366 PVOID pvParam,
367 UINT fWinIni)
368 {
369 BOOL Hook, Ret = FALSE;
370
371 LOADUSERAPIHOOK
372
373 Hook = BeginIfHookedUserApiHook();
374
375 /* Bypass SEH and go direct. */
376 if (!Hook) return RealSystemParametersInfoW(uiAction, uiParam, pvParam, fWinIni);
377
378 _SEH2_TRY
379 {
380 Ret = guah.SystemParametersInfoW(uiAction, uiParam, pvParam, fWinIni);
381 }
382 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
383 {
384 }
385 _SEH2_END;
386
387 EndUserApiHook();
388
389 return Ret;
390 }
391
392 /*
393 * @implemented
394 */
395 HDESK WINAPI
396 CreateDesktopA(LPCSTR lpszDesktop,
397 LPCSTR lpszDevice,
398 LPDEVMODEA pDevmode,
399 DWORD dwFlags,
400 ACCESS_MASK dwDesiredAccess,
401 LPSECURITY_ATTRIBUTES lpsa)
402 {
403 UNICODE_STRING DesktopNameU;
404 HDESK hDesktop;
405 LPDEVMODEW DevmodeW = NULL;
406
407 if (lpszDesktop)
408 {
409 /* After conversion, the buffer is zero-terminated */
410 RtlCreateUnicodeStringFromAsciiz(&DesktopNameU, lpszDesktop);
411 }
412 else
413 {
414 RtlInitUnicodeString(&DesktopNameU, NULL);
415 }
416
417 if (pDevmode)
418 DevmodeW = GdiConvertToDevmodeW(pDevmode);
419
420 hDesktop = CreateDesktopW(DesktopNameU.Buffer,
421 NULL,
422 DevmodeW,
423 dwFlags,
424 dwDesiredAccess,
425 lpsa);
426
427 /* Free the string, if it was allocated */
428 if (lpszDesktop) RtlFreeUnicodeString(&DesktopNameU);
429
430 return hDesktop;
431 }
432
433
434 /*
435 * @implemented
436 */
437 HDESK WINAPI
438 CreateDesktopW(LPCWSTR lpszDesktop,
439 LPCWSTR lpszDevice,
440 LPDEVMODEW pDevmode,
441 DWORD dwFlags,
442 ACCESS_MASK dwDesiredAccess,
443 LPSECURITY_ATTRIBUTES lpsa)
444 {
445 OBJECT_ATTRIBUTES oas;
446 UNICODE_STRING DesktopName, DesktopDevice;
447 HWINSTA hWinSta;
448 HDESK hDesktop;
449 ULONG Attributes = (OBJ_OPENIF|OBJ_CASE_INSENSITIVE);
450
451 /* Retrive WinStation handle. */
452 hWinSta = NtUserGetProcessWindowStation();
453
454 /* Initialize the strings. */
455 RtlInitUnicodeString(&DesktopName, lpszDesktop);
456 RtlInitUnicodeString(&DesktopDevice, lpszDevice);
457
458 /* Check for process is inherited, set flag if set. */
459 if (lpsa && lpsa->bInheritHandle) Attributes |= OBJ_INHERIT;
460
461 /* Initialize the attributes for the desktop. */
462 InitializeObjectAttributes( &oas,
463 &DesktopName,
464 Attributes,
465 hWinSta,
466 lpsa ? lpsa->lpSecurityDescriptor : NULL);
467
468 /* Send the request and call to win32k. */
469 hDesktop = NtUserCreateDesktop( &oas,
470 &DesktopDevice,
471 pDevmode,
472 dwFlags,
473 dwDesiredAccess);
474
475 return(hDesktop);
476 }
477
478
479 /*
480 * @implemented
481 */
482 BOOL
483 WINAPI
484 EnumDesktopsA(
485 HWINSTA WindowStation,
486 DESKTOPENUMPROCA EnumFunc,
487 LPARAM Context)
488 {
489 return EnumNamesA(WindowStation, EnumFunc, Context, TRUE);
490 }
491
492
493 /*
494 * @implemented
495 */
496 BOOL
497 WINAPI
498 EnumDesktopsW(
499 HWINSTA WindowStation,
500 DESKTOPENUMPROCW EnumFunc,
501 LPARAM Context)
502 {
503 return EnumNamesW(WindowStation, EnumFunc, Context, TRUE);
504 }
505
506
507 /*
508 * @implemented
509 */
510 HDESK
511 WINAPI
512 GetThreadDesktop(
513 DWORD dwThreadId)
514 {
515 return NtUserGetThreadDesktop(dwThreadId, 0);
516 }
517
518
519 /*
520 * @implemented
521 */
522 HDESK
523 WINAPI
524 OpenDesktopA(
525 LPCSTR lpszDesktop,
526 DWORD dwFlags,
527 BOOL fInherit,
528 ACCESS_MASK dwDesiredAccess)
529 {
530 UNICODE_STRING DesktopNameU;
531 HDESK hDesktop;
532
533 if (lpszDesktop)
534 {
535 /* After conversion, the buffer is zero-terminated */
536 RtlCreateUnicodeStringFromAsciiz(&DesktopNameU, lpszDesktop);
537 }
538 else
539 {
540 RtlInitUnicodeString(&DesktopNameU, NULL);
541 }
542
543 hDesktop = OpenDesktopW(DesktopNameU.Buffer,
544 dwFlags,
545 fInherit,
546 dwDesiredAccess);
547
548 /* Free the string, if it was allocated */
549 if (lpszDesktop) RtlFreeUnicodeString(&DesktopNameU);
550
551 return hDesktop;
552 }
553
554
555 /*
556 * @implemented
557 */
558 HDESK
559 WINAPI
560 OpenDesktopW(
561 LPCWSTR lpszDesktop,
562 DWORD dwFlags,
563 BOOL fInherit,
564 ACCESS_MASK dwDesiredAccess)
565 {
566 UNICODE_STRING DesktopName;
567 OBJECT_ATTRIBUTES ObjectAttributes;
568
569 RtlInitUnicodeString(&DesktopName, lpszDesktop);
570
571 InitializeObjectAttributes(&ObjectAttributes,
572 &DesktopName,
573 OBJ_CASE_INSENSITIVE,
574 GetProcessWindowStation(),
575 0);
576
577 if( fInherit == TRUE )
578 {
579 ObjectAttributes.Attributes |= OBJ_INHERIT;
580 }
581
582 return NtUserOpenDesktop(&ObjectAttributes, dwFlags, dwDesiredAccess);
583 }
584
585
586 /*
587 * @implemented
588 */
589 BOOL WINAPI
590 SetShellWindow(HWND hwndShell)
591 {
592 return SetShellWindowEx(hwndShell, hwndShell);
593 }
594
595
596 /*
597 * @implemented
598 */
599 HWND WINAPI
600 GetShellWindow(VOID)
601 {
602 PDESKTOPINFO pdi;
603 pdi = GetThreadDesktopInfo();
604 if (pdi) return pdi->hShellWindow;
605 return NULL;
606 }
607
608
609 /* EOF */