2 * System parameters functions
4 * Copyright 1994 Alexandre Julliard
17 #include "wine/winuser16.h"
22 #include "debugtools.h"
23 #include "sysmetrics.h"
25 DEFAULT_DEBUG_CHANNEL(system);
27 /* System parameter indexes */
28 #define SPI_SETBEEP_IDX 0
29 #define SPI_SETBORDER_IDX 1
30 #define SPI_ICONHORIZONTALSPACING_IDX 2
31 #define SPI_ICONVERTICALSPACING_IDX 3
32 #define SPI_SETSHOWSOUNDS_IDX 4
33 #define SPI_WINE_IDX SPI_SETSHOWSOUNDS_IDX
36 * Names of the registry subkeys of HKEY_CURRENT_USER key and value names
37 * for the system parameters.
38 * Names of the keys are created by adding string "_REGKEY" to
39 * "SET" action names, value names are created by adding "_REG_NAME"
40 * to the "SET" action name.
42 #define SPI_SETBEEP_REGKEY "Control Panel\\Sound"
43 #define SPI_SETBEEP_VALNAME "Beep"
44 #define SPI_SETBORDER_REGKEY "Control Panel\\Desktop"
45 #define SPI_SETBORDER_VALNAME "BorderWidth"
46 #define SPI_ICONHORIZONTALSPACING_REGKEY "Control Panel\\Desktop"
47 #define SPI_ICONHORIZONTALSPACING_VALNAME "IconSpacing"
48 #define SPI_ICONVERTICALSPACING_REGKEY "Control Panel\\Desktop"
49 #define SPI_ICONVERTICALSPACING_VALNAME "IconVerticalSpacing"
50 #define SPI_SETSHOWSOUNDS_REGKEY "Control Panel\\Accessibility\\ShowSounds"
51 #define SPI_SETSHOWSOUNDS_VALNAME "On"
53 /* volatile registry branch under CURRENT_USER_REGKEY for temporary values storage */
54 #define WINE_CURRENT_USER_REGKEY "Wine"
56 /* Indicators whether system parameter value is loaded */
57 static char spi_loaded[SPI_WINE_IDX + 1];
59 static BOOL notify_change = TRUE;
61 /* System parameters storage */
62 static BOOL beep_active = TRUE;
63 static int border = 1;
66 /***********************************************************************
67 * GetTimerResolution (USER.14)
69 LONG WINAPI GetTimerResolution16(void)
74 /***********************************************************************
75 * ControlPanelInfo (USER.273)
77 void WINAPI ControlPanelInfo16( INT16 nInfoType, WORD wData, LPSTR lpBuffer )
79 FIXME("(%d, %04x, %p): stub.\n", nInfoType, wData, lpBuffer);
82 /* This function is a copy of the one in objects/font.c */
83 static void SYSPARAMS_LogFont32ATo16( const LOGFONTA* font32, LPLOGFONT16 font16 )
85 font16->lfHeight = font32->lfHeight;
86 font16->lfWidth = font32->lfWidth;
87 font16->lfEscapement = font32->lfEscapement;
88 font16->lfOrientation = font32->lfOrientation;
89 font16->lfWeight = font32->lfWeight;
90 font16->lfItalic = font32->lfItalic;
91 font16->lfUnderline = font32->lfUnderline;
92 font16->lfStrikeOut = font32->lfStrikeOut;
93 font16->lfCharSet = font32->lfCharSet;
94 font16->lfOutPrecision = font32->lfOutPrecision;
95 font16->lfClipPrecision = font32->lfClipPrecision;
96 font16->lfQuality = font32->lfQuality;
97 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
98 lstrcpynA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
101 static void SYSPARAMS_LogFont32ATo32W( const LOGFONTA* font32A, LPLOGFONTW font32W )
103 font32W->lfHeight = font32A->lfHeight;
104 font32W->lfWidth = font32A->lfWidth;
105 font32W->lfEscapement = font32A->lfEscapement;
106 font32W->lfOrientation = font32A->lfOrientation;
107 font32W->lfWeight = font32A->lfWeight;
108 font32W->lfItalic = font32A->lfItalic;
109 font32W->lfUnderline = font32A->lfUnderline;
110 font32W->lfStrikeOut = font32A->lfStrikeOut;
111 font32W->lfCharSet = font32A->lfCharSet;
112 font32W->lfOutPrecision = font32A->lfOutPrecision;
113 font32W->lfClipPrecision = font32A->lfClipPrecision;
114 font32W->lfQuality = font32A->lfQuality;
115 font32W->lfPitchAndFamily = font32A->lfPitchAndFamily;
116 MultiByteToWideChar( CP_ACP, 0, font32A->lfFaceName, -1, font32W->lfFaceName, LF_FACESIZE );
117 font32W->lfFaceName[LF_FACESIZE-1] = 0;
120 static void SYSPARAMS_NonClientMetrics32ATo16( const NONCLIENTMETRICSA* lpnm32, LPNONCLIENTMETRICS16 lpnm16 )
122 lpnm16->iBorderWidth = lpnm32->iBorderWidth;
123 lpnm16->iScrollWidth = lpnm32->iScrollWidth;
124 lpnm16->iScrollHeight = lpnm32->iScrollHeight;
125 lpnm16->iCaptionWidth = lpnm32->iCaptionWidth;
126 lpnm16->iCaptionHeight = lpnm32->iCaptionHeight;
127 SYSPARAMS_LogFont32ATo16( &lpnm32->lfCaptionFont, &lpnm16->lfCaptionFont );
128 lpnm16->iSmCaptionWidth = lpnm32->iSmCaptionWidth;
129 lpnm16->iSmCaptionHeight = lpnm32->iSmCaptionHeight;
130 SYSPARAMS_LogFont32ATo16( &lpnm32->lfSmCaptionFont, &lpnm16->lfSmCaptionFont );
131 lpnm16->iMenuWidth = lpnm32->iMenuWidth;
132 lpnm16->iMenuHeight = lpnm32->iMenuHeight;
133 SYSPARAMS_LogFont32ATo16( &lpnm32->lfMenuFont, &lpnm16->lfMenuFont );
134 SYSPARAMS_LogFont32ATo16( &lpnm32->lfStatusFont, &lpnm16->lfStatusFont );
135 SYSPARAMS_LogFont32ATo16( &lpnm32->lfMessageFont, &lpnm16->lfMessageFont );
138 static void SYSPARAMS_NonClientMetrics32ATo32W( const NONCLIENTMETRICSA* lpnm32A, LPNONCLIENTMETRICSW lpnm32W )
140 lpnm32W->iBorderWidth = lpnm32A->iBorderWidth;
141 lpnm32W->iScrollWidth = lpnm32A->iScrollWidth;
142 lpnm32W->iScrollHeight = lpnm32A->iScrollHeight;
143 lpnm32W->iCaptionWidth = lpnm32A->iCaptionWidth;
144 lpnm32W->iCaptionHeight = lpnm32A->iCaptionHeight;
145 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfCaptionFont, &lpnm32W->lfCaptionFont );
146 lpnm32W->iSmCaptionWidth = lpnm32A->iSmCaptionWidth;
147 lpnm32W->iSmCaptionHeight = lpnm32A->iSmCaptionHeight;
148 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfSmCaptionFont, &lpnm32W->lfSmCaptionFont );
149 lpnm32W->iMenuWidth = lpnm32A->iMenuWidth;
150 lpnm32W->iMenuHeight = lpnm32A->iMenuHeight;
151 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfMenuFont, &lpnm32W->lfMenuFont );
152 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfStatusFont, &lpnm32W->lfStatusFont );
153 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfMessageFont, &lpnm32W->lfMessageFont );
156 /***********************************************************************
159 * Sets the system parameter which should be always loaded to
160 * current value stored in registry.
161 * Invalidates lazy loaded parameter, so it will be loaded the next time
165 * uiAction - system parameter to reload value for.
166 * Note, only "SET" values can be used for this parameter.
167 * If uiAction is 0 all system parameters are reset.
169 void SYSPARAMS_Reset( UINT uiAction )
171 #define WINE_RELOAD_SPI(x) \
173 spi_loaded[x##_IDX] = FALSE; \
174 SystemParametersInfoA( x, 0, dummy_buf, 0 );\
178 #define WINE_INVALIDATE_SPI(x) \
180 spi_loaded[x##_IDX] = FALSE; \
183 BOOL not_all_processed = TRUE;
186 /* Execution falls through all the branches for uiAction == 0 */
190 memset( spi_loaded, 0, sizeof(spi_loaded) );
192 WINE_RELOAD_SPI(SPI_SETBORDER);
193 WINE_RELOAD_SPI(SPI_ICONHORIZONTALSPACING);
194 WINE_RELOAD_SPI(SPI_ICONVERTICALSPACING);
195 WINE_RELOAD_SPI(SPI_SETSHOWSOUNDS);
200 /* lazy loaded parameters */
203 WINE_INVALIDATE_SPI(SPI_SETBEEP);
205 FIXME( "Unknown action reset: %u\n", uiAction );
210 not_all_processed = FALSE;
214 if (!uiAction && not_all_processed)
215 ERR( "Incorrect implementation of SYSPARAMS_Reset. "
216 "Not all params are reloaded.\n" );
217 #undef WINE_INVALIDATE_SPI
218 #undef WINE_RELOAD_SPI
221 /***********************************************************************
222 * get_volatile_regkey
224 * Return a handle to the volatile registry key used to store
225 * non-permanently modified parameters.
227 static HKEY get_volatile_regkey(void)
229 static HKEY volatile_key;
233 /* FIXME - check whether the key exists
234 notify_change = FALSE;
235 if (WINE_CURRENT_USER_REGKEY does not exist)
237 initialize system parameters info which take values from X settings,
238 if(current settings differ from X)
239 change current setting and save it;
241 notify_change = TRUE;
244 if (RegCreateKeyExA( HKEY_CURRENT_USER, WINE_CURRENT_USER_REGKEY,
245 0, 0, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, 0,
246 &volatile_key, 0 ) != ERROR_SUCCESS)
247 ERR("Can't create wine configuration registry branch");
252 /***********************************************************************
253 * SYSPARAMS_NotifyChange
255 * Sends notification about system parameter update.
257 void SYSPARAMS_NotifyChange( UINT uiAction, UINT fWinIni )
261 if (fWinIni & SPIF_UPDATEINIFILE)
263 if (fWinIni & (SPIF_SENDWININICHANGE | SPIF_SENDCHANGE))
264 SendMessageA(HWND_BROADCAST, WM_SETTINGCHANGE,
265 uiAction, (LPARAM) "");
269 /* FIXME notify other wine processes with internal message */
275 /***********************************************************************
276 * Loads system parameter from user profile.
278 BOOL SYSPARAMS_Load( LPSTR lpRegKey, LPSTR lpValName, LPSTR lpBuf )
285 if ((RegOpenKeyA( get_volatile_regkey(), lpRegKey,
286 &hKey ) == ERROR_SUCCESS) ||
287 (RegOpenKeyA( HKEY_CURRENT_USER, lpRegKey,
288 &hKey ) == ERROR_SUCCESS))
290 ret = !RegQueryValueExA( hKey, lpValName, NULL, &type, lpBuf, &count );
296 /***********************************************************************
297 * Saves system parameter to user profile.
299 BOOL SYSPARAMS_Save( LPSTR lpRegKey, LPSTR lpValName, LPSTR lpValue,
307 if (fWinIni & SPIF_UPDATEINIFILE)
309 hBaseKey = HKEY_CURRENT_USER;
314 hBaseKey = get_volatile_regkey();
315 dwOptions = REG_OPTION_VOLATILE;
318 if (RegCreateKeyExA( hBaseKey, lpRegKey,
319 0, 0, dwOptions, KEY_ALL_ACCESS,
320 0, &hKey, 0 ) == ERROR_SUCCESS)
322 if (RegSetValueExA( hKey, lpValName, 0, REG_SZ,
323 lpValue, strlen(lpValue) + 1 ) == ERROR_SUCCESS)
326 if (hBaseKey == HKEY_CURRENT_USER)
327 RegDeleteKeyA( get_volatile_regkey(), lpRegKey );
334 /***********************************************************************
335 * SystemParametersInfoA (USER32.@)
337 * Each system parameter has flag which shows whether the parameter
338 * is loaded or not. Parameters, stored directly in SysParametersInfo are
339 * loaded from registry only when they are requested and the flag is
340 * "false", after the loading the flag is set to "true". On interprocess
341 * notification of the parameter change the corresponding parameter flag is
342 * set to "false". The parameter value will be reloaded when it is requested
344 * Parameters, backed by or depend on GetSystemMetrics are processed
345 * differently. These parameters are always loaded. They are reloaded right
346 * away on interprocess change notification. We can't do lazy loading because
347 * we don't want to complicate GetSystemMetrics.
348 * When parameter value is updated the changed value is stored in permanent
349 * registry branch if saving is requested. Otherwise it is stored
350 * in temporary branch
353 BOOL WINAPI SystemParametersInfoA( UINT uiAction, UINT uiParam,
354 PVOID pvParam, UINT fWinIni )
356 #define WINE_SPI_FIXME(x) \
358 FIXME( "Unimplemented action: %u (%s)\n", x, #x ); \
359 SetLastError( ERROR_INVALID_SPI_VALUE ); \
362 #define WINE_SPI_WARN(x) \
364 WARN( "Ignored action: %u (%s)\n", x, #x ); \
368 unsigned spi_idx = 0;
370 TRACE("(%u, %u, %p, %u)\n", uiAction, uiParam, pvParam, fWinIni);
374 case SPI_GETBEEP: /* 1 */
375 spi_idx = SPI_SETBEEP_IDX;
376 if (!spi_loaded[spi_idx])
380 if (SYSPARAMS_Load( SPI_SETBEEP_REGKEY, SPI_SETBEEP_VALNAME, buf ))
381 beep_active = !strcasecmp( "Yes", buf );
382 spi_loaded[spi_idx] = TRUE;
385 *(BOOL *)pvParam = beep_active;
387 case SPI_SETBEEP: /* 2 */
388 spi_idx = SPI_SETBEEP_IDX;
389 if (SYSPARAMS_Save( SPI_SETBEEP_REGKEY, SPI_SETBEEP_VALNAME,
390 (uiParam ? "Yes" : "No"), fWinIni ))
392 beep_active = uiParam;
393 spi_loaded[spi_idx] = TRUE;
399 WINE_SPI_FIXME(SPI_GETMOUSE); /* 3 */
400 WINE_SPI_FIXME(SPI_SETMOUSE); /* 4 */
402 case SPI_GETBORDER: /* 5 */
403 spi_idx = SPI_SETBORDER_IDX;
404 if (!spi_loaded[spi_idx])
408 if (SYSPARAMS_Load( SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME,
412 if (i > 0) border = i;
414 spi_loaded[spi_idx] = TRUE;
415 if (TWEAK_WineLook > WIN31_LOOK)
417 SYSMETRICS_Set( SM_CXFRAME, border + GetSystemMetrics( SM_CXDLGFRAME ) );
418 SYSMETRICS_Set( SM_CYFRAME, border + GetSystemMetrics( SM_CXDLGFRAME ) );
421 *(INT *)pvParam = border;
424 case SPI_SETBORDER: /* 6 */
428 spi_idx = SPI_SETBORDER_IDX;
429 sprintf(buf, "%u", uiParam);
431 if (SYSPARAMS_Save( SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME,
437 spi_loaded[spi_idx] = TRUE;
438 if (TWEAK_WineLook > WIN31_LOOK)
440 SYSMETRICS_Set( SM_CXFRAME, uiParam + GetSystemMetrics( SM_CXDLGFRAME ) );
441 SYSMETRICS_Set( SM_CYFRAME, uiParam + GetSystemMetrics( SM_CXDLGFRAME ) );
450 case SPI_GETKEYBOARDSPEED: /* 10 */
451 *(DWORD *)pvParam = GetProfileIntA( "keyboard", "KeyboardSpeed", 30 );
453 WINE_SPI_WARN(SPI_SETKEYBOARDSPEED); /* 11 */
455 WINE_SPI_WARN(SPI_LANGDRIVER); /* 12 */
457 case SPI_ICONHORIZONTALSPACING: /* 13 */
458 spi_idx = SPI_ICONHORIZONTALSPACING_IDX;
461 if (!spi_loaded[spi_idx])
465 if (SYSPARAMS_Load( SPI_ICONHORIZONTALSPACING_REGKEY,
466 SPI_ICONHORIZONTALSPACING_VALNAME, buf ))
468 SYSMETRICS_Set( SM_CXICONSPACING, atoi( buf ) );
470 spi_loaded[spi_idx] = TRUE;
473 *(INT *)pvParam = GetSystemMetrics( SM_CXICONSPACING );
479 if (uiParam < 32) uiParam = 32;
481 sprintf(buf, "%u", uiParam);
482 if (SYSPARAMS_Save( SPI_ICONHORIZONTALSPACING_REGKEY,
483 SPI_ICONHORIZONTALSPACING_VALNAME,
486 SYSMETRICS_Set( SM_CXICONSPACING, uiParam );
487 spi_loaded[spi_idx] = TRUE;
495 case SPI_GETSCREENSAVETIMEOUT: /* 14 */
498 timeout = USER_Driver.pGetScreenSaveTimeout();
500 timeout = GetProfileIntA( "windows", "ScreenSaveTimeout", 300 );
501 *(INT *)pvParam = timeout;
504 case SPI_SETSCREENSAVETIMEOUT: /* 15 */
505 USER_Driver.pSetScreenSaveTimeout( uiParam );
508 case SPI_GETSCREENSAVEACTIVE: /* 16 */
509 if (USER_Driver.pGetScreenSaveActive() ||
510 GetProfileIntA( "windows", "ScreenSaveActive", 1 ) == 1)
511 *(BOOL *)pvParam = TRUE;
513 *(BOOL *)pvParam = FALSE;
515 case SPI_SETSCREENSAVEACTIVE: /* 17 */
516 USER_Driver.pSetScreenSaveActive( uiParam );
519 case SPI_GETGRIDGRANULARITY: /* 18 */
520 *(INT *)pvParam = GetProfileIntA( "desktop", "GridGranularity", 1 );
522 WINE_SPI_FIXME(SPI_SETGRIDGRANULARITY); /* 19 */
524 case SPI_SETDESKWALLPAPER: /* 20 */
525 ret = SetDeskWallPaper( (LPSTR)pvParam );
527 case SPI_SETDESKPATTERN: /* 21 */
528 /* FIXME: the ability to specify a pattern in pvParam
529 doesn't seem to be documented for Win32 */
530 if ((INT16)uiParam == -1)
533 GetProfileStringA( "Desktop", "Pattern",
534 "170 85 170 85 170 85 170 85",
535 buffer, sizeof(buffer) );
536 ret = DESKTOP_SetPattern( (LPSTR)buffer );
538 ret = DESKTOP_SetPattern( (LPSTR)pvParam );
541 case SPI_GETKEYBOARDDELAY: /* 22 */
542 *(INT *)pvParam = GetProfileIntA( "keyboard", "KeyboardDelay", 1 );
544 WINE_SPI_WARN(SPI_SETKEYBOARDDELAY); /* 23 */
546 case SPI_ICONVERTICALSPACING: /* 24 */
547 spi_idx = SPI_ICONVERTICALSPACING_IDX;
550 if (!spi_loaded[spi_idx])
554 if (SYSPARAMS_Load( SPI_ICONVERTICALSPACING_REGKEY,
555 SPI_ICONVERTICALSPACING_VALNAME, buf ))
557 SYSMETRICS_Set( SM_CYICONSPACING, atoi( buf ) );
559 spi_loaded[spi_idx] = TRUE;
562 *(INT *)pvParam = GetSystemMetrics( SM_CYICONSPACING );
568 if (uiParam < 32) uiParam = 32;
570 sprintf(buf, "%u", uiParam);
571 if (SYSPARAMS_Save( SPI_ICONVERTICALSPACING_REGKEY,
572 SPI_ICONVERTICALSPACING_VALNAME,
575 SYSMETRICS_Set( SM_CYICONSPACING, uiParam );
576 spi_loaded[spi_idx] = TRUE;
584 case SPI_GETICONTITLEWRAP: /* 25 */
585 *(BOOL *)pvParam = GetProfileIntA( "desktop", "IconTitleWrap", TRUE );
587 WINE_SPI_FIXME(SPI_SETICONTITLEWRAP); /* 26 */
589 case SPI_GETMENUDROPALIGNMENT: /* 27 */
590 *(BOOL *)pvParam = GetSystemMetrics( SM_MENUDROPALIGNMENT ); /* XXX check this */
592 WINE_SPI_FIXME(SPI_SETMENUDROPALIGNMENT); /* 28 */
594 WINE_SPI_WARN(SPI_SETDOUBLECLKWIDTH); /* 29 */
595 WINE_SPI_WARN(SPI_SETDOUBLECLKHEIGHT); /* 30 */
597 case SPI_GETICONTITLELOGFONT: /* 31 */
599 LPLOGFONTA lpLogFont = (LPLOGFONTA)pvParam;
601 /* from now on we always have an alias for MS Sans Serif */
603 GetProfileStringA( "Desktop", "IconTitleFaceName", "MS Sans Serif",
604 lpLogFont->lfFaceName, LF_FACESIZE );
605 lpLogFont->lfHeight = -GetProfileIntA( "Desktop", "IconTitleSize", 13 );
606 lpLogFont->lfWidth = 0;
607 lpLogFont->lfEscapement = lpLogFont->lfOrientation = 0;
608 lpLogFont->lfWeight = FW_NORMAL;
609 lpLogFont->lfItalic = FALSE;
610 lpLogFont->lfStrikeOut = FALSE;
611 lpLogFont->lfUnderline = FALSE;
612 lpLogFont->lfCharSet = ANSI_CHARSET;
613 lpLogFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
614 lpLogFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
615 lpLogFont->lfPitchAndFamily = DEFAULT_PITCH | FF_SWISS;
619 WINE_SPI_WARN(SPI_SETDOUBLECLICKTIME); /* 32 */
621 WINE_SPI_FIXME(SPI_SETMOUSEBUTTONSWAP); /* 33 */
622 WINE_SPI_FIXME(SPI_SETICONTITLELOGFONT); /* 34 */
624 case SPI_GETFASTTASKSWITCH: /* 35 */
625 if (GetProfileIntA( "windows", "CoolSwitch", 1 ) == 1)
626 *(BOOL *)pvParam = TRUE;
628 *(BOOL *)pvParam = FALSE;
630 WINE_SPI_WARN(SPI_SETFASTTASKSWITCH); /* 36 */
632 WINE_SPI_WARN(SPI_SETDRAGFULLWINDOWS); /* 37 WINVER >= 0x0400 */
633 case SPI_GETDRAGFULLWINDOWS: /* 38 WINVER >= 0x0400 */
637 DWORD dwBufferSize = sizeof(buffer);
639 *(BOOL *)pvParam = FALSE;
640 if (RegOpenKeyExA( HKEY_CURRENT_USER,
641 "Control Panel\\desktop",
642 0, KEY_QUERY_VALUE, &hKey ) == ERROR_SUCCESS)
644 if (RegQueryValueExA( hKey, "DragFullWindows", NULL,
645 0, buffer, &dwBufferSize ) == ERROR_SUCCESS)
646 *(BOOL *)pvParam = atoi( buffer ) != 0;
653 case SPI_GETNONCLIENTMETRICS: /* 41 WINVER >= 0x400 */
655 LPNONCLIENTMETRICSA lpnm = (LPNONCLIENTMETRICSA)pvParam;
657 if (lpnm->cbSize == sizeof(NONCLIENTMETRICSA))
659 LPLOGFONTA lpLogFont = &(lpnm->lfMenuFont);
661 /* clear the struct, so we have 'sane' members */
663 (char *)pvParam + sizeof(lpnm->cbSize),
665 lpnm->cbSize - sizeof(lpnm->cbSize)
668 /* FIXME: initialize geometry entries */
669 /* FIXME: As these values are presumably in device units,
670 * we should calculate the defaults based on the screen dpi
673 lpnm->iCaptionWidth = ((TWEAK_WineLook > WIN31_LOOK) ? 32 : 20);
674 lpnm->iCaptionHeight = lpnm->iCaptionWidth;
675 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0, (LPVOID)&(lpnm->lfCaptionFont), 0 );
676 lpnm->lfCaptionFont.lfWeight = FW_BOLD;
679 lpnm->iSmCaptionWidth = ((TWEAK_WineLook > WIN31_LOOK) ? 32 : 17);
680 lpnm->iSmCaptionHeight = lpnm->iSmCaptionWidth;
681 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0, (LPVOID)&(lpnm->lfSmCaptionFont), 0 );
683 /* menus, FIXME: names of wine.conf entries are bogus */
685 lpnm->iMenuWidth = GetProfileIntA( "Desktop", "MenuWidth", 13 ); /* size of the menu buttons*/
686 lpnm->iMenuHeight = GetProfileIntA( "Desktop", "MenuHeight",
687 (TWEAK_WineLook > WIN31_LOOK) ? 13 : 27 );
689 GetProfileStringA( "Desktop", "MenuFont",
690 (TWEAK_WineLook > WIN31_LOOK) ? "MS Sans Serif": "System",
691 lpLogFont->lfFaceName, LF_FACESIZE );
693 lpLogFont->lfHeight = -GetProfileIntA( "Desktop", "MenuFontSize", 13 );
694 lpLogFont->lfWidth = 0;
695 lpLogFont->lfEscapement = lpLogFont->lfOrientation = 0;
696 lpLogFont->lfWeight = (TWEAK_WineLook > WIN31_LOOK) ? FW_NORMAL : FW_BOLD;
697 lpLogFont->lfItalic = FALSE;
698 lpLogFont->lfStrikeOut = FALSE;
699 lpLogFont->lfUnderline = FALSE;
700 lpLogFont->lfCharSet = ANSI_CHARSET;
701 lpLogFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
702 lpLogFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
703 lpLogFont->lfPitchAndFamily = DEFAULT_PITCH | FF_SWISS;
705 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0,
706 (LPVOID)&(lpnm->lfStatusFont), 0 );
707 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0,
708 (LPVOID)&(lpnm->lfMessageFont), 0 );
712 WARN("size mismatch !! (is %d; should be %d)\n", lpnm->cbSize, sizeof(NONCLIENTMETRICSA));
713 /* FIXME: SetLastError? */
718 WINE_SPI_FIXME(SPI_SETNONCLIENTMETRICS); /* 42 WINVER >= 0x400 */
720 WINE_SPI_FIXME(SPI_GETMINIMIZEDMETRICS); /* 43 WINVER >= 0x400 */
721 WINE_SPI_FIXME(SPI_SETMINIMIZEDMETRICS); /* 44 WINVER >= 0x400 */
723 case SPI_GETICONMETRICS: /* 45 WINVER >= 0x400 */
725 LPICONMETRICSA lpIcon = pvParam;
726 if(lpIcon && lpIcon->cbSize == sizeof(*lpIcon))
728 SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0,
729 &lpIcon->iHorzSpacing, FALSE );
730 SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0,
731 &lpIcon->iVertSpacing, FALSE );
732 SystemParametersInfoA( SPI_GETICONTITLEWRAP, 0,
733 &lpIcon->iTitleWrap, FALSE );
734 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0,
735 &lpIcon->lfFont, FALSE );
743 WINE_SPI_FIXME(SPI_SETICONMETRICS); /* 46 WINVER >= 0x400 */
745 WINE_SPI_FIXME(SPI_SETWORKAREA); /* 47 WINVER >= 0x400 */
746 case SPI_GETWORKAREA: /* 48 WINVER >= 0x400 */
747 SetRect( (RECT *)pvParam, 0, 0,
748 GetSystemMetrics( SM_CXSCREEN ),
749 GetSystemMetrics( SM_CYSCREEN ) );
752 WINE_SPI_FIXME(SPI_SETPENWINDOWS); /* 49 WINVER >= 0x400 */
754 WINE_SPI_FIXME(SPI_GETFILTERKEYS); /* 50 */
755 WINE_SPI_FIXME(SPI_SETFILTERKEYS); /* 51 */
756 WINE_SPI_FIXME(SPI_GETTOGGLEKEYS); /* 52 */
757 WINE_SPI_FIXME(SPI_SETTOGGLEKEYS); /* 53 */
758 WINE_SPI_FIXME(SPI_GETMOUSEKEYS); /* 54 */
759 WINE_SPI_FIXME(SPI_SETMOUSEKEYS); /* 55 */
760 case SPI_GETSHOWSOUNDS: /* 56 */
761 spi_idx = SPI_SETSHOWSOUNDS_IDX;
763 if (!spi_loaded[spi_idx])
767 if (SYSPARAMS_Load( SPI_SETSHOWSOUNDS_REGKEY,
768 SPI_SETSHOWSOUNDS_VALNAME, buf ))
770 SYSMETRICS_Set( SM_SHOWSOUNDS, atoi( buf ) );
772 spi_loaded[spi_idx] = TRUE;
776 *(INT *)pvParam = GetSystemMetrics( SM_SHOWSOUNDS );
779 case SPI_SETSHOWSOUNDS: /* 57 */
782 spi_idx = SPI_SETSHOWSOUNDS_IDX;
784 sprintf(buf, "%u", uiParam);
785 if (SYSPARAMS_Save( SPI_SETSHOWSOUNDS_REGKEY,
786 SPI_SETSHOWSOUNDS_VALNAME,
789 SYSMETRICS_Set( SM_SHOWSOUNDS, uiParam );
790 spi_loaded[spi_idx] = TRUE;
796 WINE_SPI_FIXME(SPI_GETSTICKYKEYS); /* 58 */
797 WINE_SPI_FIXME(SPI_SETSTICKYKEYS); /* 59 */
798 WINE_SPI_FIXME(SPI_GETACCESSTIMEOUT); /* 60 */
799 WINE_SPI_FIXME(SPI_SETACCESSTIMEOUT); /* 61 */
801 WINE_SPI_FIXME(SPI_GETSERIALKEYS); /* 62 WINVER >= 0x400 */
802 WINE_SPI_FIXME(SPI_SETSERIALKEYS); /* 63 WINVER >= 0x400 */
804 WINE_SPI_FIXME(SPI_GETSOUNDSENTRY); /* 64 */
805 WINE_SPI_FIXME(SPI_SETSOUNDSENTRY); /* 65 */
807 case SPI_GETHIGHCONTRAST: /* 66 WINVER >= 0x400 */
809 LPHIGHCONTRASTA lpHighContrastA = (LPHIGHCONTRASTA)pvParam;
810 WARN("SPI_GETHIGHCONTRAST not fully implemented\n");
811 if (lpHighContrastA->cbSize == sizeof(HIGHCONTRASTA))
813 /* Indicate that there is no high contrast available */
814 lpHighContrastA->dwFlags = 0;
815 lpHighContrastA->lpszDefaultScheme = NULL;
823 WINE_SPI_FIXME(SPI_SETHIGHCONTRAST); /* 67 WINVER >= 0x400 */
825 WINE_SPI_FIXME(SPI_GETKEYBOARDPREF); /* 68 WINVER >= 0x400 */
826 WINE_SPI_FIXME(SPI_SETKEYBOARDPREF); /* 69 WINVER >= 0x400 */
828 case SPI_GETSCREENREADER:
830 LPBOOL bool = (LPBOOL)pvParam;
835 WINE_SPI_FIXME(SPI_SETSCREENREADER); /* 71 WINVER >= 0x400 */
837 case SPI_GETANIMATION: /* 72 WINVER >= 0x400 */
839 LPANIMATIONINFO lpAnimInfo = (LPANIMATIONINFO)pvParam;
841 /* Tell it "disabled" */
842 if (lpAnimInfo->cbSize == sizeof(ANIMATIONINFO))
843 lpAnimInfo->iMinAnimate = 0; /* Minimise and restore animation is disabled (nonzero == enabled) */
848 WINE_SPI_WARN(SPI_SETANIMATION); /* 73 WINVER >= 0x400 */
850 WINE_SPI_FIXME(SPI_GETFONTSMOOTHING); /* 74 WINVER >= 0x400 */
851 WINE_SPI_FIXME(SPI_SETFONTSMOOTHING); /* 75 WINVER >= 0x400 */
853 WINE_SPI_FIXME(SPI_SETDRAGWIDTH); /* 76 WINVER >= 0x400 */
854 WINE_SPI_FIXME(SPI_SETDRAGHEIGHT); /* 77 WINVER >= 0x400 */
856 WINE_SPI_FIXME(SPI_SETHANDHELD); /* 78 WINVER >= 0x400 */
858 WINE_SPI_FIXME(SPI_GETLOWPOWERTIMEOUT); /* 79 WINVER >= 0x400 */
859 WINE_SPI_FIXME(SPI_GETPOWEROFFTIMEOUT); /* 80 WINVER >= 0x400 */
860 WINE_SPI_FIXME(SPI_SETLOWPOWERTIMEOUT); /* 81 WINVER >= 0x400 */
861 WINE_SPI_FIXME(SPI_SETPOWEROFFTIMEOUT); /* 82 WINVER >= 0x400 */
862 WINE_SPI_FIXME(SPI_GETLOWPOWERACTIVE); /* 83 WINVER >= 0x400 */
863 WINE_SPI_FIXME(SPI_GETPOWEROFFACTIVE); /* 84 WINVER >= 0x400 */
864 WINE_SPI_FIXME(SPI_SETLOWPOWERACTIVE); /* 85 WINVER >= 0x400 */
865 WINE_SPI_FIXME(SPI_SETPOWEROFFACTIVE); /* 86 WINVER >= 0x400 */
867 WINE_SPI_FIXME(SPI_SETCURSORS); /* 87 WINVER >= 0x400 */
868 WINE_SPI_FIXME(SPI_SETICONS); /* 88 WINVER >= 0x400 */
870 WINE_SPI_FIXME(SPI_GETDEFAULTINPUTLANG); /* 89 WINVER >= 0x400 */
871 WINE_SPI_FIXME(SPI_SETDEFAULTINPUTLANG); /* 90 WINVER >= 0x400 */
873 WINE_SPI_FIXME(SPI_SETLANGTOGGLE); /* 91 WINVER >= 0x400 */
875 case SPI_GETWINDOWSEXTENSION: /* 92 WINVER >= 0x400 */
876 WARN("pretend no support for Win9x Plus! for now.\n");
877 ret = FALSE; /* yes, this is the result value */
880 WINE_SPI_FIXME(SPI_SETMOUSETRAILS); /* 93 WINVER >= 0x400 */
881 WINE_SPI_FIXME(SPI_GETMOUSETRAILS); /* 94 WINVER >= 0x400 */
883 WINE_SPI_FIXME(SPI_SETSCREENSAVERRUNNING); /* 97 WINVER >= 0x400 */
884 /* SPI_SCREENSAVERRUNNING is an alias for SPI_SETSCREENSAVERRUNNING */
886 case SPI_GETMOUSEHOVERWIDTH: /* 98 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
887 *(UINT *)pvParam = 4;
889 WINE_SPI_FIXME(SPI_SETMOUSEHOVERWIDTH); /* 99 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
891 case SPI_GETMOUSEHOVERHEIGHT: /* 100 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
892 *(UINT *)pvParam = 4;
894 WINE_SPI_FIXME(SPI_SETMOUSEHOVERHEIGHT); /* 101 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
896 case SPI_GETMOUSEHOVERTIME: /* 102 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
897 *(UINT *)pvParam = 400; /* default for menu dropdowns */
899 WINE_SPI_FIXME(SPI_SETMOUSEHOVERTIME); /* 103 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
901 case SPI_GETWHEELSCROLLLINES: /* 104 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
902 *(UINT *)pvParam = 3; /* default for num scroll lines */
905 WINE_SPI_FIXME(SPI_SETWHEELSCROLLLINES); /* 105 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
907 case SPI_GETMENUSHOWDELAY: /* 106 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
908 *(UINT *)pvParam = 400; /* Tested against Windows NT 4.0 and Windows 2000 */
911 WINE_SPI_FIXME(SPI_GETSHOWIMEUI); /* 110 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
912 WINE_SPI_FIXME(SPI_SETSHOWIMEUI); /* 111 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
915 FIXME( "Unknown action: %u\n", uiAction );
916 SetLastError( ERROR_INVALID_SPI_VALUE );
922 SYSPARAMS_NotifyChange( uiAction, fWinIni );
925 #undef WINE_SPI_FIXME
930 /***********************************************************************
931 * SystemParametersInfo (USER.483)
933 BOOL16 WINAPI SystemParametersInfo16( UINT16 uAction, UINT16 uParam,
934 LPVOID lpvParam, UINT16 fuWinIni )
938 TRACE("(%u, %u, %p, %u)\n", uAction, uParam, lpvParam, fuWinIni);
942 case SPI_GETBEEP: /* 1 */
943 case SPI_GETSCREENSAVEACTIVE: /* 16 */
944 case SPI_GETICONTITLEWRAP: /* 25 */
945 case SPI_GETMENUDROPALIGNMENT: /* 27 */
946 case SPI_GETFASTTASKSWITCH: /* 35 */
947 case SPI_GETDRAGFULLWINDOWS: /* 38 WINVER >= 0x0400 */
950 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
952 *(BOOL16 *)lpvParam = tmp;
956 case SPI_GETBORDER: /* 5 */
957 case SPI_ICONHORIZONTALSPACING: /* 13 */
958 case SPI_GETSCREENSAVETIMEOUT: /* 14 */
959 case SPI_GETGRIDGRANULARITY: /* 18 */
960 case SPI_GETKEYBOARDDELAY: /* 22 */
961 case SPI_ICONVERTICALSPACING: /* 24 */
964 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
966 *(INT16 *)lpvParam = tmp;
970 case SPI_GETKEYBOARDSPEED: /* 10 */
973 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
975 *(WORD *)lpvParam = tmp;
979 case SPI_GETICONTITLELOGFONT: /* 31 */
982 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
984 SYSPARAMS_LogFont32ATo16( &tmp, (LPLOGFONT16)lpvParam );
988 case SPI_GETNONCLIENTMETRICS: /* 41 WINVER >= 0x400 */
990 NONCLIENTMETRICSA tmp;
991 LPNONCLIENTMETRICS16 lpnm16 = (LPNONCLIENTMETRICS16)lpvParam;
992 if (lpnm16 && lpnm16->cbSize == sizeof(NONCLIENTMETRICS16))
994 tmp.cbSize = sizeof(NONCLIENTMETRICSA);
995 ret = SystemParametersInfoA( uAction, uParam, &tmp, fuWinIni );
997 SYSPARAMS_NonClientMetrics32ATo16( &tmp, lpnm16 );
999 else /* winfile 95 sets cbSize to 340 */
1000 ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
1004 case SPI_GETWORKAREA: /* 48 WINVER >= 0x400 */
1007 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1008 if (ret && lpvParam)
1009 CONV_RECT32TO16( &tmp, (RECT16 *)lpvParam );
1013 case SPI_GETMOUSEHOVERWIDTH: /* 98 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1014 case SPI_GETMOUSEHOVERHEIGHT: /* 100 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1015 case SPI_GETMOUSEHOVERTIME: /* 102 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1018 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1019 if (ret && lpvParam)
1020 *(UINT16 *)lpvParam = tmp;
1025 ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
1031 /***********************************************************************
1032 * SystemParametersInfoW (USER32.@)
1034 BOOL WINAPI SystemParametersInfoW( UINT uiAction, UINT uiParam,
1035 PVOID pvParam, UINT fuWinIni )
1039 TRACE("(%u, %u, %p, %u)\n", uiAction, uiParam, pvParam, fuWinIni);
1043 case SPI_SETDESKWALLPAPER: /* 20 */
1044 case SPI_SETDESKPATTERN: /* 21 */
1048 if (!WideCharToMultiByte( CP_ACP, 0, (LPWSTR)pvParam, -1,
1049 buffer, sizeof(buffer), NULL, NULL ))
1050 buffer[sizeof(buffer)-1] = 0;
1051 ret = SystemParametersInfoA( uiAction, uiParam, pvParam ? buffer : NULL, fuWinIni );
1055 case SPI_GETICONTITLELOGFONT: /* 31 */
1058 ret = SystemParametersInfoA( uiAction, uiParam, pvParam ? &tmp : NULL, fuWinIni );
1060 SYSPARAMS_LogFont32ATo32W( &tmp, (LPLOGFONTW)pvParam );
1064 case SPI_GETNONCLIENTMETRICS: /* 41 WINVER >= 0x400 */
1066 NONCLIENTMETRICSA tmp;
1067 LPNONCLIENTMETRICSW lpnmW = (LPNONCLIENTMETRICSW)pvParam;
1068 if (lpnmW && lpnmW->cbSize == sizeof(NONCLIENTMETRICSW))
1070 tmp.cbSize = sizeof(NONCLIENTMETRICSA);
1071 ret = SystemParametersInfoA( uiAction, uiParam, &tmp, fuWinIni );
1073 SYSPARAMS_NonClientMetrics32ATo32W( &tmp, lpnmW );
1080 case SPI_GETICONMETRICS: /* 45 WINVER >= 0x400 */
1083 LPICONMETRICSW lpimW = (LPICONMETRICSW)pvParam;
1084 if (lpimW && lpimW->cbSize == sizeof(ICONMETRICSW))
1086 tmp.cbSize = sizeof(ICONMETRICSA);
1087 ret = SystemParametersInfoA( uiAction, uiParam, &tmp, fuWinIni );
1090 lpimW->iHorzSpacing = tmp.iHorzSpacing;
1091 lpimW->iVertSpacing = tmp.iVertSpacing;
1092 lpimW->iTitleWrap = tmp.iTitleWrap;
1093 SYSPARAMS_LogFont32ATo32W( &tmp.lfFont, &lpimW->lfFont );
1101 case SPI_GETHIGHCONTRAST: /* 66 WINVER >= 0x400 */
1104 LPHIGHCONTRASTW lphcW = (LPHIGHCONTRASTW)pvParam;
1105 if (lphcW && lphcW->cbSize == sizeof(HIGHCONTRASTW))
1107 tmp.cbSize = sizeof(HIGHCONTRASTA);
1108 ret = SystemParametersInfoA( uiAction, uiParam, &tmp, fuWinIni );
1111 lphcW->dwFlags = tmp.dwFlags;
1112 lphcW->lpszDefaultScheme = NULL; /* FIXME? */
1121 ret = SystemParametersInfoA( uiAction, uiParam, pvParam, fuWinIni );