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