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