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