migrate substitution keywords to SVN
[reactos.git] / reactos / lib / 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 #include "winsta.h"
14 #include <string.h>
15 #include <debug.h>
16 #include <rosrtl/devmode.h>
17 #include <rosrtl/logfont.h>
18 #include <malloc.h>
19 #include <math.h>
20
21 /*
22 * @implemented
23 */
24 int STDCALL
25 GetSystemMetrics(int nIndex)
26 {
27 return(NtUserGetSystemMetrics(nIndex));
28 }
29
30
31 /*
32 * @unimplemented
33 */
34 BOOL STDCALL SetDeskWallpaper(LPCSTR filename)
35 {
36 return SystemParametersInfoA(SPI_SETDESKWALLPAPER,0,(PVOID)filename,TRUE);
37 }
38 /*
39 * @implemented
40 */
41 BOOL STDCALL
42 SystemParametersInfoA(UINT uiAction,
43 UINT uiParam,
44 PVOID pvParam,
45 UINT fWinIni)
46 {
47 switch (uiAction)
48 {
49 case SPI_SETDOUBLECLKWIDTH:
50 case SPI_SETDOUBLECLKHEIGHT:
51 case SPI_SETDOUBLECLICKTIME:
52 case SPI_SETGRADIENTCAPTIONS:
53 case SPI_SETFONTSMOOTHING:
54 case SPI_SETFOCUSBORDERHEIGHT:
55 case SPI_SETFOCUSBORDERWIDTH:
56 case SPI_SETWORKAREA:
57 case SPI_GETWORKAREA:
58 case SPI_GETFONTSMOOTHING:
59 case SPI_GETGRADIENTCAPTIONS:
60 case SPI_GETFOCUSBORDERHEIGHT:
61 case SPI_GETFOCUSBORDERWIDTH:
62 {
63 return NtUserSystemParametersInfo(uiAction, uiParam, pvParam, fWinIni);
64 }
65 case SPI_GETNONCLIENTMETRICS:
66 {
67 LPNONCLIENTMETRICSA nclma = (LPNONCLIENTMETRICSA)pvParam;
68 NONCLIENTMETRICSW nclmw;
69 nclmw.cbSize = sizeof(NONCLIENTMETRICSW);
70
71 if (!SystemParametersInfoW(uiAction, sizeof(NONCLIENTMETRICSW),
72 &nclmw, fWinIni))
73 return FALSE;
74
75 nclma->iBorderWidth = nclmw.iBorderWidth;
76 nclma->iScrollWidth = nclmw.iScrollWidth;
77 nclma->iScrollHeight = nclmw.iScrollHeight;
78 nclma->iCaptionWidth = nclmw.iCaptionWidth;
79 nclma->iCaptionHeight = nclmw.iCaptionHeight;
80 nclma->iSmCaptionWidth = nclmw.iSmCaptionWidth;
81 nclma->iSmCaptionHeight = nclmw.iSmCaptionHeight;
82 nclma->iMenuWidth = nclmw.iMenuWidth;
83 nclma->iMenuHeight = nclmw.iMenuHeight;
84 RosRtlLogFontW2A(&(nclma->lfCaptionFont), &(nclmw.lfCaptionFont));
85 RosRtlLogFontW2A(&(nclma->lfSmCaptionFont), &(nclmw.lfSmCaptionFont));
86 RosRtlLogFontW2A(&(nclma->lfMenuFont), &(nclmw.lfMenuFont));
87 RosRtlLogFontW2A(&(nclma->lfStatusFont), &(nclmw.lfStatusFont));
88 RosRtlLogFontW2A(&(nclma->lfMessageFont), &(nclmw.lfMessageFont));
89 return TRUE;
90 }
91 case SPI_GETICONTITLELOGFONT:
92 {
93 LOGFONTW lfw;
94 if (!SystemParametersInfoW(uiAction, 0, &lfw, fWinIni))
95 return FALSE;
96 RosRtlLogFontW2A(pvParam, &lfw);
97 return TRUE;
98 }
99 case SPI_GETDESKWALLPAPER:
100 {
101 HKEY hKey;
102 BOOL Ret = FALSE;
103
104 #if 0
105 /* Get the desktop bitmap handle, this does NOT return the file name! */
106 if(!NtUserSystemParametersInfo(SPI_GETDESKWALLPAPER, 0, &hbmWallpaper, 0))
107 {
108 /* Return an empty string, no wallpapaper is set */
109 *(CHAR*)pvParam = '\0';
110 return TRUE;
111 }
112 #endif
113
114 /* FIXME - Read the registry key for now, but what happens if the wallpaper was
115 changed without SPIF_UPDATEINIFILE?! */
116 if(RegOpenKeyExW(HKEY_CURRENT_USER,
117 L"Control Panel\\Desktop",
118 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
119 {
120 DWORD Type, Size;
121 Size = uiParam;
122 if(RegQueryValueExA(hKey,
123 "Wallpaper",
124 NULL,
125 &Type,
126 (LPBYTE)pvParam,
127 &Size) == ERROR_SUCCESS
128 && Type == REG_SZ)
129 {
130 Ret = TRUE;
131 }
132 RegCloseKey(hKey);
133 }
134 return Ret;
135 }
136 case SPI_SETDESKWALLPAPER:
137 {
138 HBITMAP hNewWallpaper;
139 BOOL Ret;
140 LPSTR lpWallpaper = (LPSTR)pvParam;
141
142 if(lpWallpaper != NULL && *lpWallpaper != '\0')
143 {
144 hNewWallpaper = LoadImageA(0, lpWallpaper, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
145 if(hNewWallpaper == NULL)
146 {
147 return FALSE;
148 }
149 }
150 else
151 {
152 hNewWallpaper = NULL;
153 lpWallpaper = NULL;
154 }
155
156 /* Set the wallpaper bitmap */
157 if(!NtUserSystemParametersInfo(SPI_SETDESKWALLPAPER, 0, &hNewWallpaper, fWinIni & SPIF_SENDCHANGE))
158 {
159 if(hNewWallpaper != NULL)
160 DeleteObject(hNewWallpaper);
161 return FALSE;
162 }
163 /* Do not use the bitmap handle anymore, it doesn't belong to our process anymore! */
164
165 Ret = TRUE;
166 if(fWinIni & SPIF_UPDATEINIFILE)
167 {
168 /* Save the path to the file in the registry */
169 HKEY hKey;
170 if(RegOpenKeyExW(HKEY_CURRENT_USER,
171 L"Control Panel\\Desktop",
172 0, KEY_SET_VALUE, &hKey) == ERROR_SUCCESS)
173 {
174 Ret = RegSetValueExA(hKey, "Wallpaper", 0, REG_SZ, (LPBYTE)(lpWallpaper != NULL ? lpWallpaper : ""),
175 (lpWallpaper != NULL ? (lstrlenA(lpWallpaper) + 1) * sizeof(CHAR) : sizeof(CHAR)) == ERROR_SUCCESS);
176 RegCloseKey(hKey);
177 }
178 }
179
180 RedrawWindow(GetDesktopWindow(), NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
181
182 return Ret;
183 }
184 }
185
186 return FALSE;
187 }
188
189
190 /*
191 * @implemented
192 */
193 BOOL STDCALL
194 SystemParametersInfoW(UINT uiAction,
195 UINT uiParam,
196 PVOID pvParam,
197 UINT fWinIni)
198 {
199 switch(uiAction)
200 {
201 case SPI_GETDESKWALLPAPER:
202 {
203 HKEY hKey;
204 BOOL Ret = FALSE;
205
206 #if 0
207 /* Get the desktop bitmap handle, this does NOT return the file name! */
208 if(!NtUserSystemParametersInfo(SPI_GETDESKWALLPAPER, 0, &hbmWallpaper, 0))
209 {
210 /* Return an empty string, no wallpapaper is set */
211 *(WCHAR*)pvParam = L'\0';
212 return TRUE;
213 }
214 #endif
215
216 /* FIXME - Read the registry key for now, but what happens if the wallpaper was
217 changed without SPIF_UPDATEINIFILE?! */
218 if(RegOpenKeyExW(HKEY_CURRENT_USER,
219 L"Control Panel\\Desktop",
220 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
221 {
222 DWORD Type, Size;
223 Size = uiParam * sizeof(WCHAR);
224 if(RegQueryValueExW(hKey,
225 L"Wallpaper",
226 NULL,
227 &Type,
228 (LPBYTE)pvParam,
229 &Size) == ERROR_SUCCESS
230 && Type == REG_SZ)
231 {
232 Ret = TRUE;
233 }
234 RegCloseKey(hKey);
235 }
236 return Ret;
237 }
238 case SPI_SETDESKWALLPAPER:
239 {
240 HBITMAP hNewWallpaper;
241 BOOL Ret;
242 LPWSTR lpWallpaper = (LPWSTR)pvParam;
243
244 if(lpWallpaper != NULL && *lpWallpaper != L'\0')
245 {
246 hNewWallpaper = LoadImageW(0, lpWallpaper, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
247
248 if(hNewWallpaper == NULL)
249 {
250 return FALSE;
251 }
252 }
253 else
254 {
255 hNewWallpaper = NULL;
256 lpWallpaper = NULL;
257 }
258
259 /* Set the wallpaper bitmap */
260 if(!NtUserSystemParametersInfo(SPI_SETDESKWALLPAPER, 0, &hNewWallpaper, fWinIni & SPIF_SENDCHANGE))
261 {
262 if(hNewWallpaper != NULL)
263 DeleteObject(hNewWallpaper);
264 return FALSE;
265 }
266 /* Do not use the bitmap handle anymore, it doesn't belong to our process anymore! */
267 Ret = TRUE;
268 if(fWinIni & SPIF_UPDATEINIFILE)
269 {
270 /* Save the path to the file in the registry */
271 HKEY hKey;
272
273 if(RegOpenKeyExW(HKEY_CURRENT_USER,
274 L"Control Panel\\Desktop",
275 0, KEY_SET_VALUE, &hKey) == ERROR_SUCCESS)
276 {
277 Ret = RegSetValueExW(hKey, L"Wallpaper", 0, REG_SZ, (lpWallpaper != NULL ? (LPBYTE)lpWallpaper : (LPBYTE)L""),
278 (lpWallpaper != NULL ? (lstrlenW(lpWallpaper) + 1) * sizeof(WCHAR) : sizeof(WCHAR)) == ERROR_SUCCESS);
279 RegCloseKey(hKey);
280 }
281 }
282
283 RedrawWindow(GetDesktopWindow(), NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
284
285 return Ret;
286 }
287 }
288 return NtUserSystemParametersInfo(uiAction, uiParam, pvParam, fWinIni);
289 }
290
291
292 /*
293 * @implemented
294 */
295 BOOL
296 STDCALL
297 CloseDesktop(
298 HDESK hDesktop)
299 {
300 return NtUserCloseDesktop(hDesktop);
301 }
302
303
304 /*
305 * @implemented
306 */
307 HDESK STDCALL
308 CreateDesktopA(LPCSTR lpszDesktop,
309 LPCSTR lpszDevice,
310 LPDEVMODEA pDevmode,
311 DWORD dwFlags,
312 ACCESS_MASK dwDesiredAccess,
313 LPSECURITY_ATTRIBUTES lpsa)
314 {
315 ANSI_STRING DesktopNameA;
316 UNICODE_STRING DesktopNameU;
317 HDESK hDesktop;
318 DEVMODEW DevmodeW;
319
320 if (lpszDesktop != NULL)
321 {
322 RtlInitAnsiString(&DesktopNameA, (LPSTR)lpszDesktop);
323 RtlAnsiStringToUnicodeString(&DesktopNameU, &DesktopNameA, TRUE);
324 }
325 else
326 {
327 RtlInitUnicodeString(&DesktopNameU, NULL);
328 }
329
330 RosRtlDevModeA2W ( &DevmodeW, pDevmode );
331
332 hDesktop = CreateDesktopW(DesktopNameU.Buffer,
333 NULL,
334 &DevmodeW,
335 dwFlags,
336 dwDesiredAccess,
337 lpsa);
338
339 RtlFreeUnicodeString(&DesktopNameU);
340 return(hDesktop);
341 }
342
343
344 /*
345 * @implemented
346 */
347 HDESK STDCALL
348 CreateDesktopW(LPCWSTR lpszDesktop,
349 LPCWSTR lpszDevice,
350 LPDEVMODEW pDevmode,
351 DWORD dwFlags,
352 ACCESS_MASK dwDesiredAccess,
353 LPSECURITY_ATTRIBUTES lpsa)
354 {
355 UNICODE_STRING DesktopName;
356 HWINSTA hWinSta;
357 HDESK hDesktop;
358
359 hWinSta = NtUserGetProcessWindowStation();
360
361 RtlInitUnicodeString(&DesktopName, lpszDesktop);
362
363 hDesktop = NtUserCreateDesktop(&DesktopName,
364 dwFlags,
365 dwDesiredAccess,
366 lpsa,
367 hWinSta);
368
369 return(hDesktop);
370 }
371
372
373 /*
374 * @implemented
375 */
376 BOOL
377 STDCALL
378 EnumDesktopsA(
379 HWINSTA WindowStation,
380 DESKTOPENUMPROCA EnumFunc,
381 LPARAM Context)
382 {
383 return EnumNamesA(WindowStation, EnumFunc, Context, TRUE);
384 }
385
386
387 /*
388 * @implemented
389 */
390 BOOL
391 STDCALL
392 EnumDesktopsW(
393 HWINSTA WindowStation,
394 DESKTOPENUMPROCW EnumFunc,
395 LPARAM Context)
396 {
397 return EnumNamesW(WindowStation, EnumFunc, Context, TRUE);
398 }
399
400
401 /*
402 * @implemented
403 */
404 HDESK
405 STDCALL
406 GetThreadDesktop(
407 DWORD dwThreadId)
408 {
409 return NtUserGetThreadDesktop(dwThreadId, 0);
410 }
411
412
413 /*
414 * @implemented
415 */
416 HDESK
417 STDCALL
418 OpenDesktopA(
419 LPSTR lpszDesktop,
420 DWORD dwFlags,
421 BOOL fInherit,
422 ACCESS_MASK dwDesiredAccess)
423 {
424 ANSI_STRING DesktopNameA;
425 UNICODE_STRING DesktopNameU;
426 HDESK hDesktop;
427
428 if (lpszDesktop != NULL) {
429 RtlInitAnsiString(&DesktopNameA, lpszDesktop);
430 RtlAnsiStringToUnicodeString(&DesktopNameU, &DesktopNameA, TRUE);
431 } else {
432 RtlInitUnicodeString(&DesktopNameU, NULL);
433 }
434
435 hDesktop = OpenDesktopW(
436 DesktopNameU.Buffer,
437 dwFlags,
438 fInherit,
439 dwDesiredAccess);
440
441 RtlFreeUnicodeString(&DesktopNameU);
442
443 return hDesktop;
444 }
445
446
447 /*
448 * @implemented
449 */
450 HDESK
451 STDCALL
452 OpenDesktopW(
453 LPWSTR lpszDesktop,
454 DWORD dwFlags,
455 BOOL fInherit,
456 ACCESS_MASK dwDesiredAccess)
457 {
458 UNICODE_STRING DesktopName;
459
460 RtlInitUnicodeString(&DesktopName, lpszDesktop);
461
462 return NtUserOpenDesktop(
463 &DesktopName,
464 dwFlags,
465 dwDesiredAccess);
466 }
467
468
469 /*
470 * @implemented
471 */
472 HDESK
473 STDCALL
474 OpenInputDesktop(
475 DWORD dwFlags,
476 BOOL fInherit,
477 ACCESS_MASK dwDesiredAccess)
478 {
479 return NtUserOpenInputDesktop(
480 dwFlags,
481 fInherit,
482 dwDesiredAccess);
483 }
484
485
486 /*
487 * @implemented
488 */
489 BOOL
490 STDCALL
491 PaintDesktop(
492 HDC hdc)
493 {
494 return NtUserPaintDesktop(hdc);
495 }
496
497
498 /*
499 * @implemented
500 */
501 BOOL
502 STDCALL
503 SetThreadDesktop(
504 HDESK hDesktop)
505 {
506 return NtUserSetThreadDesktop(hDesktop);
507 }
508
509
510 /*
511 * @implemented
512 */
513 BOOL
514 STDCALL
515 SwitchDesktop(
516 HDESK hDesktop)
517 {
518 return NtUserSwitchDesktop(hDesktop);
519 }
520
521
522 /*
523 * @implemented
524 */
525 BOOL STDCALL
526 SetShellWindowEx(HWND hwndShell, HWND hwndShellListView)
527 {
528 return NtUserSetShellWindowEx(hwndShell, hwndShellListView);
529 }
530
531
532 /*
533 * @implemented
534 */
535 BOOL STDCALL
536 SetShellWindow(HWND hwndShell)
537 {
538 return SetShellWindowEx(hwndShell, hwndShell);
539 }
540
541
542 /*
543 * @implemented
544 */
545 HWND STDCALL
546 GetShellWindow(VOID)
547 {
548 return NtUserGetShellWindow();
549 }
550
551
552 /* EOF */