Converted servprov.h to IDL.
[wine/hacks.git] / windows / sysparams.c
blob87464f7d8e0de5a9d078e4717328d2bb654ee2a9
1 /*
2 * System parameters functions
4 * Copyright 1994 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "config.h"
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winnls.h"
29 #include "wingdi.h"
30 #include "winreg.h"
31 #include "wine/winuser16.h"
32 #include "winerror.h"
34 #include "controls.h"
35 #include "user.h"
36 #include "wine/debug.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(system);
40 /* System parameter indexes */
41 #define SPI_SETBEEP_IDX 0
42 #define SPI_SETMOUSE_IDX 1
43 #define SPI_SETBORDER_IDX 2
44 #define SPI_SETKEYBOARDSPEED_IDX 3
45 #define SPI_ICONHORIZONTALSPACING_IDX 4
46 #define SPI_SETSCREENSAVETIMEOUT_IDX 5
47 #define SPI_SETGRIDGRANULARITY_IDX 6
48 #define SPI_SETKEYBOARDDELAY_IDX 7
49 #define SPI_ICONVERTICALSPACING_IDX 8
50 #define SPI_SETICONTITLEWRAP_IDX 9
51 #define SPI_SETMENUDROPALIGNMENT_IDX 10
52 #define SPI_SETDOUBLECLKWIDTH_IDX 11
53 #define SPI_SETDOUBLECLKHEIGHT_IDX 12
54 #define SPI_SETDOUBLECLICKTIME_IDX 13
55 #define SPI_SETMOUSEBUTTONSWAP_IDX 14
56 #define SPI_SETDRAGFULLWINDOWS_IDX 15
57 #define SPI_SETWORKAREA_IDX 16
58 #define SPI_SETSHOWSOUNDS_IDX 17
59 #define SPI_SETKEYBOARDPREF_IDX 18
60 #define SPI_SETSCREENREADER_IDX 19
61 #define SPI_SETSCREENSAVERRUNNING_IDX 20
62 #define SPI_WINE_IDX SPI_SETSCREENSAVERRUNNING_IDX
64 /**
65 * Names of the registry subkeys of HKEY_CURRENT_USER key and value names
66 * for the system parameters.
67 * Names of the keys are created by adding string "_REGKEY" to
68 * "SET" action names, value names are created by adding "_REG_NAME"
69 * to the "SET" action name.
71 #define SPI_SETBEEP_REGKEY "Control Panel\\Sound"
72 #define SPI_SETBEEP_VALNAME "Beep"
73 #define SPI_SETMOUSE_REGKEY "Control Panel\\Mouse"
74 #define SPI_SETMOUSE_VALNAME1 "MouseThreshold1"
75 #define SPI_SETMOUSE_VALNAME2 "MouseThreshold2"
76 #define SPI_SETMOUSE_VALNAME3 "MouseSpeed"
77 #define SPI_SETBORDER_REGKEY "Control Panel\\Desktop"
78 #define SPI_SETBORDER_VALNAME "BorderWidth"
79 #define SPI_SETKEYBOARDSPEED_REGKEY "Control Panel\\Keyboard"
80 #define SPI_SETKEYBOARDSPEED_VALNAME "KeyboardSpeed"
81 #define SPI_ICONHORIZONTALSPACING_REGKEY "Control Panel\\Desktop\\WindowMetrics"
82 #define SPI_ICONHORIZONTALSPACING_VALNAME "IconSpacing"
83 #define SPI_SETSCREENSAVETIMEOUT_REGKEY "Control Panel\\Desktop"
84 #define SPI_SETSCREENSAVETIMEOUT_VALNAME "ScreenSaveTimeOut"
85 #define SPI_SETSCREENSAVEACTIVE_REGKEY "Control Panel\\Desktop"
86 #define SPI_SETSCREENSAVEACTIVE_VALNAME "ScreenSaveActive"
87 #define SPI_SETGRIDGRANULARITY_REGKEY "Control Panel\\Desktop"
88 #define SPI_SETGRIDGRANULARITY_VALNAME "GridGranularity"
89 #define SPI_SETKEYBOARDDELAY_REGKEY "Control Panel\\Keyboard"
90 #define SPI_SETKEYBOARDDELAY_VALNAME "KeyboardDelay"
91 #define SPI_ICONVERTICALSPACING_REGKEY "Control Panel\\Desktop\\WindowMetrics"
92 #define SPI_ICONVERTICALSPACING_VALNAME "IconVerticalSpacing"
93 #define SPI_SETICONTITLEWRAP_REGKEY1 "Control Panel\\Desktop\\WindowMetrics"
94 #define SPI_SETICONTITLEWRAP_REGKEY2 "Control Panel\\Desktop"
95 #define SPI_SETICONTITLEWRAP_VALNAME "IconTitleWrap"
96 #define SPI_SETMENUDROPALIGNMENT_REGKEY1 "Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows"
97 #define SPI_SETMENUDROPALIGNMENT_REGKEY2 "Control Panel\\Desktop"
98 #define SPI_SETMENUDROPALIGNMENT_VALNAME "MenuDropAlignment"
99 #define SPI_SETDOUBLECLKWIDTH_REGKEY1 "Control Panel\\Mouse"
100 #define SPI_SETDOUBLECLKWIDTH_REGKEY2 "Control Panel\\Desktop"
101 #define SPI_SETDOUBLECLKWIDTH_VALNAME "DoubleClickWidth"
102 #define SPI_SETDOUBLECLKHEIGHT_REGKEY1 "Control Panel\\Mouse"
103 #define SPI_SETDOUBLECLKHEIGHT_REGKEY2 "Control Panel\\Desktop"
104 #define SPI_SETDOUBLECLKHEIGHT_VALNAME "DoubleClickHeight"
105 #define SPI_SETDOUBLECLICKTIME_REGKEY "Control Panel\\Mouse"
106 #define SPI_SETDOUBLECLICKTIME_VALNAME "DoubleClickSpeed"
107 #define SPI_SETMOUSEBUTTONSWAP_REGKEY "Control Panel\\Mouse"
108 #define SPI_SETMOUSEBUTTONSWAP_VALNAME "SwapMouseButtons"
109 #define SPI_SETDRAGFULLWINDOWS_REGKEY "Control Panel\\Desktop"
110 #define SPI_SETDRAGFULLWINDOWS_VALNAME "DragFullWindows"
111 #define SPI_SETWORKAREA_REGKEY "Control Panel\\Desktop"
112 #define SPI_SETWORKAREA_VALNAME "WINE_WorkArea"
113 #define SPI_SETSHOWSOUNDS_REGKEY "Control Panel\\Accessibility\\ShowSounds"
114 #define SPI_SETSHOWSOUNDS_VALNAME "On"
115 #define SPI_SETDESKWALLPAPER_REGKEY "Control Panel\\Desktop"
116 #define SPI_SETDESKWALLPAPER_VALNAME "Wallpaper"
117 /* FIXME - real values */
118 #define SPI_SETKEYBOARDPREF_REGKEY "Control Panel\\Desktop"
119 #define SPI_SETKEYBOARDPREF_VALNAME "WINE_KeyboardPref"
120 #define SPI_SETSCREENREADER_REGKEY "Control Panel\\Desktop"
121 #define SPI_SETSCREENREADER_VALNAME "WINE_ScreenReader"
122 #define SPI_SETSCREENSAVERRUNNING_REGKEY "Control Panel\\Desktop"
123 #define SPI_SETSCREENSAVERRUNNING_VALNAME "WINE_ScreenSaverRunning"
125 /* volatile registry branch under CURRENT_USER_REGKEY for temporary values storage */
126 #define WINE_CURRENT_USER_REGKEY "Wine"
128 /* Indicators whether system parameter value is loaded */
129 static char spi_loaded[SPI_WINE_IDX + 1];
131 static BOOL notify_change = TRUE;
133 /* System parameters storage */
134 static BOOL beep_active = TRUE;
135 static int mouse_threshold1 = 6;
136 static int mouse_threshold2 = 10;
137 static int mouse_speed = 1;
138 static int border = 1;
139 static int keyboard_speed = 31;
140 static int screensave_timeout = 300;
141 static int grid_granularity = 0;
142 static int keyboard_delay = 1;
143 static BOOL icon_title_wrap = TRUE;
144 static int double_click_time = 500;
145 static BOOL drag_full_windows = FALSE;
146 static RECT work_area;
147 static BOOL keyboard_pref = TRUE;
148 static BOOL screen_reader = FALSE;
149 static BOOL screensaver_running = FALSE;
151 /***********************************************************************
152 * GetTimerResolution (USER.14)
154 LONG WINAPI GetTimerResolution16(void)
156 return (1000);
159 /***********************************************************************
160 * ControlPanelInfo (USER.273)
162 void WINAPI ControlPanelInfo16( INT16 nInfoType, WORD wData, LPSTR lpBuffer )
164 FIXME("(%d, %04x, %p): stub.\n", nInfoType, wData, lpBuffer);
167 /* This function is a copy of the one in objects/font.c */
168 static void SYSPARAMS_LogFont32ATo16( const LOGFONTA* font32, LPLOGFONT16 font16 )
170 font16->lfHeight = font32->lfHeight;
171 font16->lfWidth = font32->lfWidth;
172 font16->lfEscapement = font32->lfEscapement;
173 font16->lfOrientation = font32->lfOrientation;
174 font16->lfWeight = font32->lfWeight;
175 font16->lfItalic = font32->lfItalic;
176 font16->lfUnderline = font32->lfUnderline;
177 font16->lfStrikeOut = font32->lfStrikeOut;
178 font16->lfCharSet = font32->lfCharSet;
179 font16->lfOutPrecision = font32->lfOutPrecision;
180 font16->lfClipPrecision = font32->lfClipPrecision;
181 font16->lfQuality = font32->lfQuality;
182 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
183 lstrcpynA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
186 static void SYSPARAMS_LogFont32ATo32W( const LOGFONTA* font32A, LPLOGFONTW font32W )
188 font32W->lfHeight = font32A->lfHeight;
189 font32W->lfWidth = font32A->lfWidth;
190 font32W->lfEscapement = font32A->lfEscapement;
191 font32W->lfOrientation = font32A->lfOrientation;
192 font32W->lfWeight = font32A->lfWeight;
193 font32W->lfItalic = font32A->lfItalic;
194 font32W->lfUnderline = font32A->lfUnderline;
195 font32W->lfStrikeOut = font32A->lfStrikeOut;
196 font32W->lfCharSet = font32A->lfCharSet;
197 font32W->lfOutPrecision = font32A->lfOutPrecision;
198 font32W->lfClipPrecision = font32A->lfClipPrecision;
199 font32W->lfQuality = font32A->lfQuality;
200 font32W->lfPitchAndFamily = font32A->lfPitchAndFamily;
201 MultiByteToWideChar( CP_ACP, 0, font32A->lfFaceName, -1, font32W->lfFaceName, LF_FACESIZE );
202 font32W->lfFaceName[LF_FACESIZE-1] = 0;
205 static void SYSPARAMS_NonClientMetrics32ATo16( const NONCLIENTMETRICSA* lpnm32, LPNONCLIENTMETRICS16 lpnm16 )
207 lpnm16->iBorderWidth = lpnm32->iBorderWidth;
208 lpnm16->iScrollWidth = lpnm32->iScrollWidth;
209 lpnm16->iScrollHeight = lpnm32->iScrollHeight;
210 lpnm16->iCaptionWidth = lpnm32->iCaptionWidth;
211 lpnm16->iCaptionHeight = lpnm32->iCaptionHeight;
212 SYSPARAMS_LogFont32ATo16( &lpnm32->lfCaptionFont, &lpnm16->lfCaptionFont );
213 lpnm16->iSmCaptionWidth = lpnm32->iSmCaptionWidth;
214 lpnm16->iSmCaptionHeight = lpnm32->iSmCaptionHeight;
215 SYSPARAMS_LogFont32ATo16( &lpnm32->lfSmCaptionFont, &lpnm16->lfSmCaptionFont );
216 lpnm16->iMenuWidth = lpnm32->iMenuWidth;
217 lpnm16->iMenuHeight = lpnm32->iMenuHeight;
218 SYSPARAMS_LogFont32ATo16( &lpnm32->lfMenuFont, &lpnm16->lfMenuFont );
219 SYSPARAMS_LogFont32ATo16( &lpnm32->lfStatusFont, &lpnm16->lfStatusFont );
220 SYSPARAMS_LogFont32ATo16( &lpnm32->lfMessageFont, &lpnm16->lfMessageFont );
223 static void SYSPARAMS_NonClientMetrics32ATo32W( const NONCLIENTMETRICSA* lpnm32A, LPNONCLIENTMETRICSW lpnm32W )
225 lpnm32W->iBorderWidth = lpnm32A->iBorderWidth;
226 lpnm32W->iScrollWidth = lpnm32A->iScrollWidth;
227 lpnm32W->iScrollHeight = lpnm32A->iScrollHeight;
228 lpnm32W->iCaptionWidth = lpnm32A->iCaptionWidth;
229 lpnm32W->iCaptionHeight = lpnm32A->iCaptionHeight;
230 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfCaptionFont, &lpnm32W->lfCaptionFont );
231 lpnm32W->iSmCaptionWidth = lpnm32A->iSmCaptionWidth;
232 lpnm32W->iSmCaptionHeight = lpnm32A->iSmCaptionHeight;
233 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfSmCaptionFont, &lpnm32W->lfSmCaptionFont );
234 lpnm32W->iMenuWidth = lpnm32A->iMenuWidth;
235 lpnm32W->iMenuHeight = lpnm32A->iMenuHeight;
236 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfMenuFont, &lpnm32W->lfMenuFont );
237 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfStatusFont, &lpnm32W->lfStatusFont );
238 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfMessageFont, &lpnm32W->lfMessageFont );
241 /***********************************************************************
242 * SYSPARAMS_Reset
244 * Sets the system parameter which should be always loaded to
245 * current value stored in registry.
246 * Invalidates lazy loaded parameter, so it will be loaded the next time
247 * it is requested.
249 * Parameters:
250 * uiAction - system parameter to reload value for.
251 * Note, only "SET" values can be used for this parameter.
252 * If uiAction is 0 all system parameters are reset.
254 void SYSPARAMS_Reset( UINT uiAction )
256 #define WINE_RELOAD_SPI(x) \
257 case x: \
258 spi_loaded[x##_IDX] = FALSE; \
259 SystemParametersInfoA( x, 0, dummy_buf, 0 );\
260 if (uiAction) \
261 break
263 #define WINE_IGNORE_SPI(x) \
264 case x: \
265 if (uiAction) \
266 break
268 #define WINE_INVALIDATE_SPI(x) \
269 case x: \
270 spi_loaded[x##_IDX] = FALSE; \
271 break
273 BOOL not_all_processed = TRUE;
274 char dummy_buf[10];
276 /* Execution falls through all the branches for uiAction == 0 */
277 switch (uiAction)
279 case 0:
280 memset( spi_loaded, 0, sizeof(spi_loaded) );
282 WINE_RELOAD_SPI(SPI_SETBORDER);
283 WINE_RELOAD_SPI(SPI_ICONHORIZONTALSPACING);
284 WINE_RELOAD_SPI(SPI_ICONVERTICALSPACING);
285 WINE_IGNORE_SPI(SPI_SETSCREENSAVEACTIVE);
286 WINE_RELOAD_SPI(SPI_SETDOUBLECLKWIDTH);
287 WINE_RELOAD_SPI(SPI_SETDOUBLECLKHEIGHT);
288 WINE_RELOAD_SPI(SPI_SETMOUSEBUTTONSWAP);
289 WINE_RELOAD_SPI(SPI_SETSHOWSOUNDS);
290 WINE_RELOAD_SPI(SPI_SETMENUDROPALIGNMENT);
292 default:
293 if (uiAction)
295 /* lazy loaded parameters */
296 switch (uiAction)
298 WINE_INVALIDATE_SPI(SPI_SETBEEP);
299 WINE_INVALIDATE_SPI(SPI_SETMOUSE);
300 WINE_INVALIDATE_SPI(SPI_SETKEYBOARDSPEED);
301 WINE_INVALIDATE_SPI(SPI_SETSCREENSAVETIMEOUT);
302 WINE_INVALIDATE_SPI(SPI_SETGRIDGRANULARITY);
303 WINE_INVALIDATE_SPI(SPI_SETKEYBOARDDELAY);
304 WINE_INVALIDATE_SPI(SPI_SETICONTITLEWRAP);
305 WINE_INVALIDATE_SPI(SPI_SETDOUBLECLICKTIME);
306 WINE_INVALIDATE_SPI(SPI_SETDRAGFULLWINDOWS);
307 WINE_INVALIDATE_SPI(SPI_SETWORKAREA);
308 WINE_INVALIDATE_SPI(SPI_SETKEYBOARDPREF);
309 WINE_INVALIDATE_SPI(SPI_SETSCREENREADER);
310 WINE_INVALIDATE_SPI(SPI_SETSCREENSAVERRUNNING);
311 default:
312 FIXME( "Unknown action reset: %u\n", uiAction );
313 break;
316 else
317 not_all_processed = FALSE;
318 break;
321 if (!uiAction && not_all_processed)
322 ERR( "Incorrect implementation of SYSPARAMS_Reset. "
323 "Not all params are reloaded.\n" );
324 #undef WINE_INVALIDATE_SPI
325 #undef WINE_IGNORE_SPI
326 #undef WINE_RELOAD_SPI
329 /***********************************************************************
330 * get_volatile_regkey
332 * Return a handle to the volatile registry key used to store
333 * non-permanently modified parameters.
335 static HKEY get_volatile_regkey(void)
337 static HKEY volatile_key;
339 if (!volatile_key)
341 if (RegCreateKeyExA( HKEY_CURRENT_USER, WINE_CURRENT_USER_REGKEY,
342 0, 0, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, 0,
343 &volatile_key, 0 ) != ERROR_SUCCESS)
344 ERR("Can't create wine configuration registry branch\n");
346 return volatile_key;
349 /***********************************************************************
350 * SYSPARAMS_NotifyChange
352 * Sends notification about system parameter update.
354 void SYSPARAMS_NotifyChange( UINT uiAction, UINT fWinIni )
356 if (notify_change)
358 if (fWinIni & SPIF_UPDATEINIFILE)
360 if (fWinIni & (SPIF_SENDWININICHANGE | SPIF_SENDCHANGE))
361 SendMessageA(HWND_BROADCAST, WM_SETTINGCHANGE,
362 uiAction, (LPARAM) "");
364 else
366 /* FIXME notify other wine processes with internal message */
372 /***********************************************************************
373 * Loads system parameter from user profile.
375 BOOL SYSPARAMS_Load( LPSTR lpRegKey, LPSTR lpValName, LPSTR lpBuf, DWORD count )
377 BOOL ret = FALSE;
378 DWORD type;
379 HKEY hKey;
381 if ((RegOpenKeyA( get_volatile_regkey(), lpRegKey, &hKey ) == ERROR_SUCCESS) ||
382 (RegOpenKeyA( HKEY_CURRENT_USER, lpRegKey, &hKey ) == ERROR_SUCCESS))
384 ret = !RegQueryValueExA( hKey, lpValName, NULL, &type, lpBuf, &count );
385 RegCloseKey( hKey );
387 return ret;
390 /***********************************************************************
391 * Saves system parameter to user profile.
393 BOOL SYSPARAMS_Save( LPSTR lpRegKey, LPSTR lpValName, LPSTR lpValue,
394 UINT fWinIni )
396 HKEY hKey;
397 HKEY hBaseKey;
398 DWORD dwOptions;
399 BOOL ret = FALSE;
401 if (fWinIni & SPIF_UPDATEINIFILE)
403 hBaseKey = HKEY_CURRENT_USER;
404 dwOptions = 0;
406 else
408 hBaseKey = get_volatile_regkey();
409 dwOptions = REG_OPTION_VOLATILE;
412 if (RegCreateKeyExA( hBaseKey, lpRegKey,
413 0, 0, dwOptions, KEY_ALL_ACCESS,
414 0, &hKey, 0 ) == ERROR_SUCCESS)
416 if (RegSetValueExA( hKey, lpValName, 0, REG_SZ,
417 lpValue, strlen(lpValue) + 1 ) == ERROR_SUCCESS)
419 ret = TRUE;
420 if (hBaseKey == HKEY_CURRENT_USER)
421 RegDeleteKeyA( get_volatile_regkey(), lpRegKey );
423 RegCloseKey( hKey );
425 return ret;
429 /***********************************************************************
430 * SYSPARAMS_GetDoubleClickSize
432 * There is no SPI_GETDOUBLECLK* so we export this function instead.
434 void SYSPARAMS_GetDoubleClickSize( INT *width, INT *height )
436 char buf[10];
438 if (!spi_loaded[SPI_SETDOUBLECLKWIDTH_IDX])
440 char buf[10];
442 if (SYSPARAMS_Load( SPI_SETDOUBLECLKWIDTH_REGKEY1,
443 SPI_SETDOUBLECLKWIDTH_VALNAME, buf, sizeof(buf) ))
445 SYSMETRICS_Set( SM_CXDOUBLECLK, atoi( buf ) );
447 spi_loaded[SPI_SETDOUBLECLKWIDTH_IDX] = TRUE;
449 if (!spi_loaded[SPI_SETDOUBLECLKHEIGHT_IDX])
451 if (SYSPARAMS_Load( SPI_SETDOUBLECLKHEIGHT_REGKEY1,
452 SPI_SETDOUBLECLKHEIGHT_VALNAME, buf, sizeof(buf) ))
454 SYSMETRICS_Set( SM_CYDOUBLECLK, atoi( buf ) );
456 spi_loaded[SPI_SETDOUBLECLKHEIGHT_IDX] = TRUE;
458 *width = GetSystemMetrics( SM_CXDOUBLECLK );
459 *height = GetSystemMetrics( SM_CYDOUBLECLK );
463 /***********************************************************************
464 * SYSPARAMS_GetMouseButtonSwap
466 * There is no SPI_GETMOUSEBUTTONSWAP so we export this function instead.
468 INT SYSPARAMS_GetMouseButtonSwap( void )
470 int spi_idx = SPI_SETMOUSEBUTTONSWAP_IDX;
472 if (!spi_loaded[spi_idx])
474 char buf[5];
476 if (SYSPARAMS_Load( SPI_SETMOUSEBUTTONSWAP_REGKEY,
477 SPI_SETMOUSEBUTTONSWAP_VALNAME, buf, sizeof(buf) ))
479 SYSMETRICS_Set( SM_SWAPBUTTON, atoi( buf ) );
481 spi_loaded[spi_idx] = TRUE;
484 return GetSystemMetrics( SM_SWAPBUTTON );
487 /***********************************************************************
489 * SYSPARAMS_GetGUIFont
491 * fills LOGFONT with 'default GUI font'.
494 static void SYSPARAMS_GetGUIFont( LOGFONTA* plf )
496 HFONT hf;
498 memset( plf, 0, sizeof(LOGFONTA) );
499 hf = (HFONT)GetStockObject( DEFAULT_GUI_FONT );
500 if ( GetObjectA( hf, sizeof(LOGFONTA), plf ) != sizeof(LOGFONTA) )
503 * GetObjectA() would be succeeded always
504 * since this is a stock object
506 ERR("GetObjectA() failed\n");
510 /* copied from GetSystemMetrics()'s RegistryTwips2Pixels() */
511 inline static int SYSPARAMS_Twips2Pixels(int x)
513 if (x < 0)
514 x = (-x+7)/15;
515 return x;
518 /***********************************************************************
519 * SystemParametersInfoA (USER32.@)
521 * Each system parameter has flag which shows whether the parameter
522 * is loaded or not. Parameters, stored directly in SysParametersInfo are
523 * loaded from registry only when they are requested and the flag is
524 * "false", after the loading the flag is set to "true". On interprocess
525 * notification of the parameter change the corresponding parameter flag is
526 * set to "false". The parameter value will be reloaded when it is requested
527 * the next time.
528 * Parameters, backed by or depend on GetSystemMetrics are processed
529 * differently. These parameters are always loaded. They are reloaded right
530 * away on interprocess change notification. We can't do lazy loading because
531 * we don't want to complicate GetSystemMetrics.
532 * Parameters, backed by X settings are read from corresponding setting.
533 * On the parameter change request the setting is changed. Interprocess change
534 * notifications are ignored.
535 * When parameter value is updated the changed value is stored in permanent
536 * registry branch if saving is requested. Otherwise it is stored
537 * in temporary branch
539 * Some SPI values can also be stored as Twips values in the registry,
540 * don't forget the conversion!
542 BOOL WINAPI SystemParametersInfoA( UINT uiAction, UINT uiParam,
543 PVOID pvParam, UINT fWinIni )
545 #define WINE_SPI_FIXME(x) \
546 case x: \
547 FIXME( "Unimplemented action: %u (%s)\n", x, #x ); \
548 SetLastError( ERROR_INVALID_SPI_VALUE ); \
549 ret = FALSE; \
550 break
551 #define WINE_SPI_WARN(x) \
552 case x: \
553 WARN( "Ignored action: %u (%s)\n", x, #x ); \
554 break
556 BOOL ret = TRUE;
557 unsigned spi_idx = 0;
559 TRACE("(%u, %u, %p, %u)\n", uiAction, uiParam, pvParam, fWinIni);
561 switch (uiAction)
563 case SPI_GETBEEP: /* 1 */
564 if (!pvParam) return FALSE;
566 spi_idx = SPI_SETBEEP_IDX;
567 if (!spi_loaded[spi_idx])
569 char buf[5];
571 if (SYSPARAMS_Load( SPI_SETBEEP_REGKEY, SPI_SETBEEP_VALNAME, buf, sizeof(buf) ))
572 beep_active = !strcasecmp( "Yes", buf );
573 spi_loaded[spi_idx] = TRUE;
576 *(BOOL *)pvParam = beep_active;
577 break;
579 case SPI_SETBEEP: /* 2 */
580 spi_idx = SPI_SETBEEP_IDX;
581 if (SYSPARAMS_Save( SPI_SETBEEP_REGKEY, SPI_SETBEEP_VALNAME,
582 (uiParam ? "Yes" : "No"), fWinIni ))
584 beep_active = uiParam;
585 spi_loaded[spi_idx] = TRUE;
587 else
588 ret = FALSE;
589 break;
591 case SPI_GETMOUSE: /* 3 */
592 if (!pvParam) return FALSE;
594 spi_idx = SPI_SETMOUSE_IDX;
595 if (!spi_loaded[spi_idx])
597 char buf[10];
599 if (SYSPARAMS_Load( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME1,
600 buf, sizeof(buf) ))
601 mouse_threshold1 = atoi( buf );
602 if (SYSPARAMS_Load( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME2,
603 buf, sizeof(buf) ))
604 mouse_threshold2 = atoi( buf );
605 if (SYSPARAMS_Load( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME3,
606 buf, sizeof(buf) ))
607 mouse_speed = atoi( buf );
608 spi_loaded[spi_idx] = TRUE;
610 ((INT *)pvParam)[0] = mouse_threshold1;
611 ((INT *)pvParam)[1] = mouse_threshold2;
612 ((INT *)pvParam)[2] = mouse_speed;
613 break;
615 case SPI_SETMOUSE: /* 4 */
617 char buf[10];
619 if (!pvParam) return FALSE;
621 spi_idx = SPI_SETMOUSE_IDX;
622 sprintf(buf, "%d", ((INT *)pvParam)[0]);
624 if (SYSPARAMS_Save( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME1,
625 buf, fWinIni ))
627 mouse_threshold1 = ((INT *)pvParam)[0];
628 spi_loaded[spi_idx] = TRUE;
630 sprintf(buf, "%d", ((INT *)pvParam)[1]);
631 SYSPARAMS_Save( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME2,
632 buf, fWinIni );
633 mouse_threshold2 = ((INT *)pvParam)[1];
635 sprintf(buf, "%d", ((INT *)pvParam)[2]);
636 SYSPARAMS_Save( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME3,
637 buf, fWinIni );
638 mouse_speed = ((INT *)pvParam)[2];
640 else
641 ret = FALSE;
642 break;
645 case SPI_GETBORDER: /* 5 */
646 if (!pvParam) return FALSE;
648 spi_idx = SPI_SETBORDER_IDX;
649 if (!spi_loaded[spi_idx])
651 char buf[10];
653 if (SYSPARAMS_Load( SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME, buf, sizeof(buf) ))
654 border = SYSPARAMS_Twips2Pixels( atoi(buf) );
656 spi_loaded[spi_idx] = TRUE;
657 if (TWEAK_WineLook > WIN31_LOOK)
659 SYSMETRICS_Set( SM_CXFRAME, border + GetSystemMetrics( SM_CXDLGFRAME ) );
660 SYSMETRICS_Set( SM_CYFRAME, border + GetSystemMetrics( SM_CXDLGFRAME ) );
663 *(INT *)pvParam = border;
664 break;
666 case SPI_SETBORDER: /* 6 */
668 char buf[10];
670 spi_idx = SPI_SETBORDER_IDX;
671 sprintf(buf, "%u", uiParam);
673 if (SYSPARAMS_Save( SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME,
674 buf, fWinIni ))
676 if (uiParam > 0)
678 border = uiParam;
679 spi_loaded[spi_idx] = TRUE;
680 if (TWEAK_WineLook > WIN31_LOOK)
682 SYSMETRICS_Set( SM_CXFRAME, uiParam + GetSystemMetrics( SM_CXDLGFRAME ) );
683 SYSMETRICS_Set( SM_CYFRAME, uiParam + GetSystemMetrics( SM_CXDLGFRAME ) );
687 else
688 ret = FALSE;
689 break;
692 case SPI_GETKEYBOARDSPEED: /* 10 */
693 if (!pvParam) return FALSE;
695 spi_idx = SPI_SETKEYBOARDSPEED_IDX;
696 if (!spi_loaded[spi_idx])
698 char buf[10];
700 if (SYSPARAMS_Load( SPI_SETKEYBOARDSPEED_REGKEY,
701 SPI_SETKEYBOARDSPEED_VALNAME,
702 buf, sizeof(buf) ))
703 keyboard_speed = atoi( buf );
704 spi_loaded[spi_idx] = TRUE;
706 *(INT *)pvParam = keyboard_speed;
707 break;
709 case SPI_SETKEYBOARDSPEED: /* 11 */
711 char buf[10];
713 spi_idx = SPI_SETKEYBOARDSPEED_IDX;
714 if (uiParam > 31)
715 uiParam = 31;
716 sprintf(buf, "%u", uiParam);
718 if (SYSPARAMS_Save( SPI_SETKEYBOARDSPEED_REGKEY,
719 SPI_SETKEYBOARDSPEED_VALNAME,
720 buf, fWinIni ))
722 keyboard_speed = uiParam;
723 spi_loaded[spi_idx] = TRUE;
725 else
726 ret = FALSE;
727 break;
730 /* not implemented in Windows */
731 WINE_SPI_WARN(SPI_LANGDRIVER); /* 12 */
733 case SPI_ICONHORIZONTALSPACING: /* 13 */
734 spi_idx = SPI_ICONHORIZONTALSPACING_IDX;
735 if (pvParam != NULL)
737 if (!spi_loaded[spi_idx])
739 char buf[10];
740 int val;
742 if (SYSPARAMS_Load( SPI_ICONHORIZONTALSPACING_REGKEY,
743 SPI_ICONHORIZONTALSPACING_VALNAME, buf, sizeof(buf) ))
745 val = SYSPARAMS_Twips2Pixels( atoi(buf) );
746 SYSMETRICS_Set( SM_CXICONSPACING, val );
748 spi_loaded[spi_idx] = TRUE;
751 *(INT *)pvParam = GetSystemMetrics( SM_CXICONSPACING );
753 else
755 char buf[10];
757 if (uiParam < 32) uiParam = 32;
759 sprintf(buf, "%u", uiParam);
760 if (SYSPARAMS_Save( SPI_ICONHORIZONTALSPACING_REGKEY,
761 SPI_ICONHORIZONTALSPACING_VALNAME,
762 buf, fWinIni ))
764 SYSMETRICS_Set( SM_CXICONSPACING, uiParam );
765 spi_loaded[spi_idx] = TRUE;
767 else
768 ret = FALSE;
770 break;
772 case SPI_GETSCREENSAVETIMEOUT: /* 14 */
773 if (!pvParam) return FALSE;
775 spi_idx = SPI_SETSCREENSAVETIMEOUT_IDX;
776 if (!spi_loaded[spi_idx])
778 char buf[10];
780 if (SYSPARAMS_Load( SPI_SETSCREENSAVETIMEOUT_REGKEY,
781 SPI_SETSCREENSAVETIMEOUT_VALNAME,
782 buf, sizeof(buf) ))
783 screensave_timeout = atoi( buf );
785 spi_loaded[spi_idx] = TRUE;
787 *(INT *)pvParam = screensave_timeout;
788 break;
790 case SPI_SETSCREENSAVETIMEOUT: /* 15 */
792 char buf[10];
794 spi_idx = SPI_SETSCREENSAVETIMEOUT_IDX;
795 sprintf(buf, "%u", uiParam);
797 if (SYSPARAMS_Save( SPI_SETSCREENSAVETIMEOUT_REGKEY,
798 SPI_SETSCREENSAVETIMEOUT_VALNAME,
799 buf, fWinIni ))
801 screensave_timeout = uiParam;
802 spi_loaded[spi_idx] = TRUE;
804 else
805 ret = FALSE;
806 break;
809 case SPI_GETSCREENSAVEACTIVE: /* 16 */
810 if (!pvParam) return FALSE;
811 *(BOOL *)pvParam = USER_Driver.pGetScreenSaveActive();
812 break;
814 case SPI_SETSCREENSAVEACTIVE: /* 17 */
816 char buf[5];
818 sprintf(buf, "%u", uiParam);
819 USER_Driver.pSetScreenSaveActive( uiParam );
820 /* saved value does not affect Wine */
821 SYSPARAMS_Save( SPI_SETSCREENSAVEACTIVE_REGKEY,
822 SPI_SETSCREENSAVEACTIVE_VALNAME,
823 buf, fWinIni );
824 break;
827 case SPI_GETGRIDGRANULARITY: /* 18 */
828 if (!pvParam) return FALSE;
830 spi_idx = SPI_SETGRIDGRANULARITY_IDX;
831 if (!spi_loaded[spi_idx])
833 char buf[10];
835 if (SYSPARAMS_Load( SPI_SETGRIDGRANULARITY_REGKEY,
836 SPI_SETGRIDGRANULARITY_VALNAME,
837 buf, sizeof(buf) ))
838 grid_granularity = atoi( buf );
840 spi_loaded[spi_idx] = TRUE;
842 *(INT *)pvParam = grid_granularity;
843 break;
845 case SPI_SETGRIDGRANULARITY: /* 19 */
847 char buf[10];
849 spi_idx = SPI_SETGRIDGRANULARITY_IDX;
850 sprintf(buf, "%u", uiParam);
852 if (SYSPARAMS_Save( SPI_SETGRIDGRANULARITY_REGKEY,
853 SPI_SETGRIDGRANULARITY_VALNAME,
854 buf, fWinIni ))
856 grid_granularity = uiParam;
857 spi_loaded[spi_idx] = TRUE;
859 else
860 ret = FALSE;
861 break;
864 case SPI_SETDESKWALLPAPER: /* 20 */
865 if (!pvParam || !SetDeskWallPaper( (LPSTR)pvParam )) return FALSE;
866 SYSPARAMS_Save(SPI_SETDESKWALLPAPER_REGKEY, SPI_SETDESKWALLPAPER_VALNAME, pvParam, fWinIni);
867 break;
868 case SPI_SETDESKPATTERN: /* 21 */
869 /* FIXME: the ability to specify a pattern in pvParam
870 doesn't seem to be documented for Win32 */
871 if ((INT16)uiParam == -1)
873 char buffer[256];
874 GetProfileStringA( "Desktop", "Pattern",
875 "170 85 170 85 170 85 170 85",
876 buffer, sizeof(buffer) );
877 ret = DESKTOP_SetPattern( (LPSTR)buffer );
878 } else
879 ret = DESKTOP_SetPattern( (LPSTR)pvParam );
880 break;
882 case SPI_GETKEYBOARDDELAY: /* 22 */
883 if (!pvParam) return FALSE;
885 spi_idx = SPI_SETKEYBOARDDELAY_IDX;
886 if (!spi_loaded[spi_idx])
888 char buf[10];
890 if (SYSPARAMS_Load( SPI_SETKEYBOARDDELAY_REGKEY,
891 SPI_SETKEYBOARDDELAY_VALNAME,
892 buf, sizeof(buf) ))
894 int i = atoi( buf );
895 if ( (i >= 0) && (i <= 3)) keyboard_delay = i;
898 spi_loaded[spi_idx] = TRUE;
900 *(INT *)pvParam = keyboard_delay;
901 break;
903 case SPI_SETKEYBOARDDELAY: /* 23 */
905 char buf[10];
907 spi_idx = SPI_SETKEYBOARDDELAY_IDX;
908 sprintf(buf, "%u", uiParam);
910 if (SYSPARAMS_Save( SPI_SETKEYBOARDDELAY_REGKEY,
911 SPI_SETKEYBOARDDELAY_VALNAME,
912 buf, fWinIni ))
914 if (uiParam <= 3)
915 keyboard_delay = uiParam;
916 spi_loaded[spi_idx] = TRUE;
918 else
919 ret = FALSE;
920 break;
923 case SPI_ICONVERTICALSPACING: /* 24 */
924 spi_idx = SPI_ICONVERTICALSPACING_IDX;
925 if (pvParam != NULL)
927 if (!spi_loaded[spi_idx])
929 char buf[10];
930 int val;
932 if (SYSPARAMS_Load( SPI_ICONVERTICALSPACING_REGKEY,
933 SPI_ICONVERTICALSPACING_VALNAME, buf, sizeof(buf) ))
935 val = SYSPARAMS_Twips2Pixels( atoi(buf) );
936 SYSMETRICS_Set( SM_CYICONSPACING, val );
938 spi_loaded[spi_idx] = TRUE;
941 *(INT *)pvParam = GetSystemMetrics( SM_CYICONSPACING );
943 else
945 char buf[10];
947 if (uiParam < 32) uiParam = 32;
949 sprintf(buf, "%u", uiParam);
950 if (SYSPARAMS_Save( SPI_ICONVERTICALSPACING_REGKEY,
951 SPI_ICONVERTICALSPACING_VALNAME,
952 buf, fWinIni ))
954 SYSMETRICS_Set( SM_CYICONSPACING, uiParam );
955 spi_loaded[spi_idx] = TRUE;
957 else
958 ret = FALSE;
961 break;
963 case SPI_GETICONTITLEWRAP: /* 25 */
964 if (!pvParam) return FALSE;
966 spi_idx = SPI_SETICONTITLEWRAP_IDX;
967 if (!spi_loaded[spi_idx])
969 char buf[5];
971 if (SYSPARAMS_Load( SPI_SETICONTITLEWRAP_REGKEY1,
972 SPI_SETICONTITLEWRAP_VALNAME, buf, sizeof(buf) ))
973 icon_title_wrap = atoi(buf);
974 spi_loaded[spi_idx] = TRUE;
977 *(BOOL *)pvParam = icon_title_wrap;
978 break;
980 case SPI_SETICONTITLEWRAP: /* 26 */
982 char buf[5];
984 spi_idx = SPI_SETICONTITLEWRAP_IDX;
985 sprintf(buf, "%u", uiParam);
986 if (SYSPARAMS_Save( SPI_SETICONTITLEWRAP_REGKEY1,
987 SPI_SETICONTITLEWRAP_VALNAME,
988 buf, fWinIni ))
990 SYSPARAMS_Save( SPI_SETICONTITLEWRAP_REGKEY2,
991 SPI_SETICONTITLEWRAP_VALNAME,
992 buf, fWinIni );
993 icon_title_wrap = uiParam;
994 spi_loaded[spi_idx] = TRUE;
996 else
997 ret = FALSE;
998 break;
1001 case SPI_GETMENUDROPALIGNMENT: /* 27 */
1002 if (!pvParam) return FALSE;
1004 spi_idx = SPI_SETMENUDROPALIGNMENT_IDX;
1006 if (!spi_loaded[spi_idx])
1008 char buf[5];
1010 if (SYSPARAMS_Load( SPI_SETMENUDROPALIGNMENT_REGKEY1,
1011 SPI_SETMENUDROPALIGNMENT_VALNAME, buf, sizeof(buf) ))
1013 SYSMETRICS_Set( SM_MENUDROPALIGNMENT, atoi( buf ) );
1015 spi_loaded[spi_idx] = TRUE;
1018 *(BOOL *)pvParam = GetSystemMetrics( SM_MENUDROPALIGNMENT );
1019 break;
1021 case SPI_SETMENUDROPALIGNMENT: /* 28 */
1023 char buf[5];
1024 spi_idx = SPI_SETMENUDROPALIGNMENT_IDX;
1026 sprintf(buf, "%u", uiParam);
1027 if (SYSPARAMS_Save( SPI_SETMENUDROPALIGNMENT_REGKEY1,
1028 SPI_SETMENUDROPALIGNMENT_VALNAME,
1029 buf, fWinIni ))
1031 SYSPARAMS_Save( SPI_SETMENUDROPALIGNMENT_REGKEY2,
1032 SPI_SETMENUDROPALIGNMENT_VALNAME,
1033 buf, fWinIni );
1034 SYSMETRICS_Set( SM_MENUDROPALIGNMENT, uiParam );
1035 spi_loaded[spi_idx] = TRUE;
1037 else
1038 ret = FALSE;
1039 break;
1042 case SPI_SETDOUBLECLKWIDTH: /* 29 */
1044 char buf[10];
1045 spi_idx = SPI_SETDOUBLECLKWIDTH_IDX;
1047 sprintf(buf, "%u", uiParam);
1048 if (SYSPARAMS_Save( SPI_SETDOUBLECLKWIDTH_REGKEY1,
1049 SPI_SETDOUBLECLKWIDTH_VALNAME,
1050 buf, fWinIni ))
1052 SYSPARAMS_Save( SPI_SETDOUBLECLKWIDTH_REGKEY2,
1053 SPI_SETDOUBLECLKWIDTH_VALNAME,
1054 buf, fWinIni );
1055 SYSMETRICS_Set( SM_CXDOUBLECLK, uiParam );
1056 spi_loaded[spi_idx] = TRUE;
1058 else
1059 ret = FALSE;
1060 break;
1063 case SPI_SETDOUBLECLKHEIGHT: /* 30 */
1065 char buf[10];
1066 spi_idx = SPI_SETDOUBLECLKHEIGHT_IDX;
1068 sprintf(buf, "%u", uiParam);
1069 if (SYSPARAMS_Save( SPI_SETDOUBLECLKHEIGHT_REGKEY1,
1070 SPI_SETDOUBLECLKHEIGHT_VALNAME,
1071 buf, fWinIni ))
1073 SYSPARAMS_Save( SPI_SETDOUBLECLKHEIGHT_REGKEY2,
1074 SPI_SETDOUBLECLKHEIGHT_VALNAME,
1075 buf, fWinIni );
1076 SYSMETRICS_Set( SM_CYDOUBLECLK, uiParam );
1077 spi_loaded[spi_idx] = TRUE;
1079 else
1080 ret = FALSE;
1081 break;
1084 case SPI_GETICONTITLELOGFONT: /* 31 */
1086 LPLOGFONTA lpLogFont = (LPLOGFONTA)pvParam;
1087 LOGFONTA lfDefault;
1089 if (!pvParam) return FALSE;
1092 * The 'default GDI fonts' seems to be returned.
1093 * If a returned font is not a correct font in your environment,
1094 * please try to fix objects/gdiobj.c at first.
1096 SYSPARAMS_GetGUIFont( &lfDefault );
1098 GetProfileStringA( "Desktop", "IconTitleFaceName",
1099 lfDefault.lfFaceName,
1100 lpLogFont->lfFaceName, LF_FACESIZE );
1101 lpLogFont->lfHeight = -GetProfileIntA( "Desktop", "IconTitleSize", 11 );
1102 lpLogFont->lfWidth = 0;
1103 lpLogFont->lfEscapement = lpLogFont->lfOrientation = 0;
1104 lpLogFont->lfWeight = FW_NORMAL;
1105 lpLogFont->lfItalic = FALSE;
1106 lpLogFont->lfStrikeOut = FALSE;
1107 lpLogFont->lfUnderline = FALSE;
1108 lpLogFont->lfCharSet = lfDefault.lfCharSet; /* at least 'charset' should not be hard-coded */
1109 lpLogFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
1110 lpLogFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
1111 lpLogFont->lfPitchAndFamily = DEFAULT_PITCH;
1112 lpLogFont->lfQuality = DEFAULT_QUALITY;
1113 break;
1116 case SPI_SETDOUBLECLICKTIME: /* 32 */
1118 char buf[10];
1120 spi_idx = SPI_SETDOUBLECLICKTIME_IDX;
1121 sprintf(buf, "%u", uiParam);
1123 if (SYSPARAMS_Save( SPI_SETDOUBLECLICKTIME_REGKEY,
1124 SPI_SETDOUBLECLICKTIME_VALNAME,
1125 buf, fWinIni ))
1127 if (!uiParam)
1128 uiParam = 500;
1129 double_click_time = uiParam;
1130 spi_loaded[spi_idx] = TRUE;
1132 else
1133 ret = FALSE;
1134 break;
1137 case SPI_SETMOUSEBUTTONSWAP: /* 33 */
1139 char buf[5];
1140 spi_idx = SPI_SETMOUSEBUTTONSWAP_IDX;
1142 sprintf(buf, "%u", uiParam);
1143 if (SYSPARAMS_Save( SPI_SETMOUSEBUTTONSWAP_REGKEY,
1144 SPI_SETMOUSEBUTTONSWAP_VALNAME,
1145 buf, fWinIni ))
1147 SYSMETRICS_Set( SM_SWAPBUTTON, uiParam );
1148 spi_loaded[spi_idx] = TRUE;
1150 else
1151 ret = FALSE;
1152 break;
1155 WINE_SPI_FIXME(SPI_SETICONTITLELOGFONT); /* 34 */
1157 case SPI_GETFASTTASKSWITCH: /* 35 */
1158 if (!pvParam) return FALSE;
1159 *(BOOL *)pvParam = 1;
1160 break;
1162 case SPI_SETFASTTASKSWITCH: /* 36 */
1163 /* the action is disabled */
1164 ret = FALSE;
1165 break;
1167 case SPI_SETDRAGFULLWINDOWS: /* 37 WINVER >= 0x0400 */
1169 char buf[5];
1171 spi_idx = SPI_SETDRAGFULLWINDOWS_IDX;
1172 sprintf(buf, "%u", uiParam);
1173 if (SYSPARAMS_Save( SPI_SETDRAGFULLWINDOWS_REGKEY,
1174 SPI_SETDRAGFULLWINDOWS_VALNAME,
1175 buf, fWinIni ))
1177 drag_full_windows = uiParam;
1178 spi_loaded[spi_idx] = TRUE;
1180 else
1181 ret = FALSE;
1182 break;
1185 case SPI_GETDRAGFULLWINDOWS: /* 38 WINVER >= 0x0400 */
1186 if (!pvParam) return FALSE;
1188 spi_idx = SPI_SETDRAGFULLWINDOWS_IDX;
1189 if (!spi_loaded[spi_idx])
1191 char buf[5];
1193 if (SYSPARAMS_Load( SPI_SETDRAGFULLWINDOWS_REGKEY,
1194 SPI_SETDRAGFULLWINDOWS_VALNAME, buf, sizeof(buf) ))
1195 drag_full_windows = atoi(buf);
1196 spi_loaded[spi_idx] = TRUE;
1199 *(BOOL *)pvParam = drag_full_windows;
1200 break;
1202 case SPI_GETNONCLIENTMETRICS: /* 41 WINVER >= 0x400 */
1204 LPNONCLIENTMETRICSA lpnm = (LPNONCLIENTMETRICSA)pvParam;
1206 if (!pvParam) return FALSE;
1208 if (lpnm->cbSize == sizeof(NONCLIENTMETRICSA))
1210 /* clear the struct, so we have 'sane' members */
1211 memset(
1212 (char *)pvParam + sizeof(lpnm->cbSize),
1214 lpnm->cbSize - sizeof(lpnm->cbSize)
1217 /* initialize geometry entries */
1218 lpnm->iBorderWidth = 1;
1219 lpnm->iScrollWidth = GetSystemMetrics(SM_CXVSCROLL);
1220 lpnm->iScrollHeight = GetSystemMetrics(SM_CYHSCROLL);
1222 /* size of the normal caption buttons */
1223 lpnm->iCaptionWidth = GetSystemMetrics(SM_CXSIZE);
1224 lpnm->iCaptionHeight = GetSystemMetrics(SM_CYSIZE);
1226 /* caption font metrics */
1227 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0, (LPVOID)&(lpnm->lfCaptionFont), 0 );
1228 lpnm->lfCaptionFont.lfWeight = FW_BOLD;
1230 /* size of the small caption buttons */
1231 lpnm->iSmCaptionWidth = GetSystemMetrics(SM_CXSMSIZE);
1232 lpnm->iSmCaptionHeight = GetSystemMetrics(SM_CYSMSIZE);
1234 /* small caption font metrics */
1235 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0, (LPVOID)&(lpnm->lfSmCaptionFont), 0 );
1237 /* menus, FIXME: names of wine.conf entries are bogus */
1239 /* size of the menu (MDI) buttons */
1240 lpnm->iMenuWidth = GetSystemMetrics(SM_CXMENUSIZE);
1241 lpnm->iMenuHeight = GetSystemMetrics(SM_CYMENUSIZE);
1243 /* menu font metrics */
1244 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0, (LPVOID)&(lpnm->lfMenuFont), 0 );
1245 GetProfileStringA( "Desktop", "MenuFont",
1246 (TWEAK_WineLook > WIN31_LOOK) ? lpnm->lfCaptionFont.lfFaceName : "System",
1247 lpnm->lfMenuFont.lfFaceName, LF_FACESIZE );
1248 lpnm->lfMenuFont.lfHeight = -GetProfileIntA( "Desktop", "MenuFontSize", 11 );
1249 lpnm->lfMenuFont.lfWeight = (TWEAK_WineLook > WIN31_LOOK) ? FW_NORMAL : FW_BOLD;
1251 /* status bar font metrics */
1252 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0,
1253 (LPVOID)&(lpnm->lfStatusFont), 0 );
1254 /* message font metrics */
1255 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0,
1256 (LPVOID)&(lpnm->lfMessageFont), 0 );
1258 else
1260 WARN("size mismatch !! (is %d; should be %d)\n", lpnm->cbSize, sizeof(NONCLIENTMETRICSA));
1261 /* FIXME: SetLastError? */
1262 ret = FALSE;
1264 break;
1266 WINE_SPI_FIXME(SPI_SETNONCLIENTMETRICS); /* 42 WINVER >= 0x400 */
1268 case SPI_GETMINIMIZEDMETRICS: /* 43 WINVER >= 0x400 */
1270 MINIMIZEDMETRICS * lpMm = pvParam;
1271 if (lpMm && lpMm->cbSize == sizeof(*lpMm))
1273 /* these taken from Win2k SP3 */
1274 lpMm->iWidth = 154;
1275 lpMm->iHorzGap = 0;
1276 lpMm->iVertGap = 0;
1277 lpMm->iArrange = 8;
1279 else
1280 ret = FALSE;
1281 break;
1283 WINE_SPI_FIXME(SPI_SETMINIMIZEDMETRICS); /* 44 WINVER >= 0x400 */
1285 case SPI_GETICONMETRICS: /* 45 WINVER >= 0x400 */
1287 LPICONMETRICSA lpIcon = pvParam;
1288 if(lpIcon && lpIcon->cbSize == sizeof(*lpIcon))
1290 SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0,
1291 &lpIcon->iHorzSpacing, FALSE );
1292 SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0,
1293 &lpIcon->iVertSpacing, FALSE );
1294 SystemParametersInfoA( SPI_GETICONTITLEWRAP, 0,
1295 &lpIcon->iTitleWrap, FALSE );
1296 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0,
1297 &lpIcon->lfFont, FALSE );
1299 else
1301 ret = FALSE;
1303 break;
1305 WINE_SPI_FIXME(SPI_SETICONMETRICS); /* 46 WINVER >= 0x400 */
1307 case SPI_SETWORKAREA: /* 47 WINVER >= 0x400 */
1309 char buf[20];
1310 RECT *pr = (RECT *) pvParam;
1312 if (!pvParam) return FALSE;
1314 spi_idx = SPI_SETWORKAREA_IDX;
1315 sprintf(buf, "%ld %ld %ld %ld",
1316 pr->left, pr->top,
1317 pr->right, pr->bottom );
1319 if (SYSPARAMS_Save( SPI_SETWORKAREA_REGKEY,
1320 SPI_SETWORKAREA_VALNAME,
1321 buf, fWinIni ))
1323 CopyRect( &work_area, (RECT *)pvParam );
1324 spi_loaded[spi_idx] = TRUE;
1326 else
1327 ret = FALSE;
1328 break;
1331 case SPI_GETWORKAREA: /* 48 WINVER >= 0x400 */
1332 if (!pvParam) return FALSE;
1334 spi_idx = SPI_SETWORKAREA_IDX;
1335 if (!spi_loaded[spi_idx])
1337 char buf[20];
1339 SetRect( &work_area, 0, 0,
1340 GetSystemMetrics( SM_CXSCREEN ),
1341 GetSystemMetrics( SM_CYSCREEN ) );
1343 if (SYSPARAMS_Load( SPI_SETWORKAREA_REGKEY,
1344 SPI_SETWORKAREA_VALNAME,
1345 buf, sizeof(buf) ))
1347 sscanf( buf, "%ld %ld %ld %ld",
1348 &work_area.left, &work_area.top,
1349 &work_area.right, &work_area.bottom );
1351 spi_loaded[spi_idx] = TRUE;
1353 CopyRect( (RECT *)pvParam, &work_area );
1355 break;
1357 WINE_SPI_FIXME(SPI_SETPENWINDOWS); /* 49 WINVER >= 0x400 */
1359 case SPI_GETFILTERKEYS: /* 50 */
1361 LPFILTERKEYS lpFilterKeys = (LPFILTERKEYS)pvParam;
1362 WARN("SPI_GETFILTERKEYS not fully implemented\n");
1363 if (lpFilterKeys && lpFilterKeys->cbSize == sizeof(FILTERKEYS))
1365 /* Indicate that no FilterKeys feature available */
1366 lpFilterKeys->dwFlags = 0;
1367 lpFilterKeys->iWaitMSec = 0;
1368 lpFilterKeys->iDelayMSec = 0;
1369 lpFilterKeys->iRepeatMSec = 0;
1370 lpFilterKeys->iBounceMSec = 0;
1372 else
1374 ret = FALSE;
1376 break;
1378 WINE_SPI_FIXME(SPI_SETFILTERKEYS); /* 51 */
1380 case SPI_GETTOGGLEKEYS: /* 52 */
1382 LPTOGGLEKEYS lpToggleKeys = (LPTOGGLEKEYS)pvParam;
1383 WARN("SPI_GETTOGGLEKEYS not fully implemented\n");
1384 if (lpToggleKeys && lpToggleKeys->cbSize == sizeof(TOGGLEKEYS))
1386 /* Indicate that no ToggleKeys feature available */
1387 lpToggleKeys->dwFlags = 0;
1389 else
1391 ret = FALSE;
1393 break;
1395 WINE_SPI_FIXME(SPI_SETTOGGLEKEYS); /* 53 */
1397 case SPI_GETMOUSEKEYS: /* 54 */
1399 LPMOUSEKEYS lpMouseKeys = (LPMOUSEKEYS)pvParam;
1400 WARN("SPI_GETMOUSEKEYS not fully implemented\n");
1401 if (lpMouseKeys && lpMouseKeys->cbSize == sizeof(MOUSEKEYS))
1403 /* Indicate that no MouseKeys feature available */
1404 lpMouseKeys->dwFlags = 0;
1405 lpMouseKeys->iMaxSpeed = 360;
1406 lpMouseKeys->iTimeToMaxSpeed = 1000;
1407 lpMouseKeys->iCtrlSpeed = 0;
1408 lpMouseKeys->dwReserved1 = 0;
1409 lpMouseKeys->dwReserved2 = 0;
1411 else
1413 ret = FALSE;
1415 break;
1417 WINE_SPI_FIXME(SPI_SETMOUSEKEYS); /* 55 */
1419 case SPI_GETSHOWSOUNDS: /* 56 */
1420 if (!pvParam) return FALSE;
1422 spi_idx = SPI_SETSHOWSOUNDS_IDX;
1424 if (!spi_loaded[spi_idx])
1426 char buf[10];
1428 if (SYSPARAMS_Load( SPI_SETSHOWSOUNDS_REGKEY,
1429 SPI_SETSHOWSOUNDS_VALNAME, buf, sizeof(buf) ))
1431 SYSMETRICS_Set( SM_SHOWSOUNDS, atoi( buf ) );
1433 spi_loaded[spi_idx] = TRUE;
1436 *(INT *)pvParam = GetSystemMetrics( SM_SHOWSOUNDS );
1437 break;
1439 case SPI_SETSHOWSOUNDS: /* 57 */
1441 char buf[10];
1442 spi_idx = SPI_SETSHOWSOUNDS_IDX;
1444 sprintf(buf, "%u", uiParam);
1445 if (SYSPARAMS_Save( SPI_SETSHOWSOUNDS_REGKEY,
1446 SPI_SETSHOWSOUNDS_VALNAME,
1447 buf, fWinIni ))
1449 SYSMETRICS_Set( SM_SHOWSOUNDS, uiParam );
1450 spi_loaded[spi_idx] = TRUE;
1452 else
1453 ret = FALSE;
1454 break;
1457 case SPI_GETSTICKYKEYS: /* 58 */
1459 LPSTICKYKEYS lpStickyKeys = (LPSTICKYKEYS)pvParam;
1460 WARN("SPI_GETSTICKYKEYS not fully implemented\n");
1461 if (lpStickyKeys && lpStickyKeys->cbSize == sizeof(STICKYKEYS))
1463 /* Indicate that no StickyKeys feature available */
1464 lpStickyKeys->dwFlags = 0;
1466 else
1468 ret = FALSE;
1470 break;
1472 WINE_SPI_FIXME(SPI_SETSTICKYKEYS); /* 59 */
1474 case SPI_GETACCESSTIMEOUT: /* 60 */
1476 LPACCESSTIMEOUT lpAccessTimeout = (LPACCESSTIMEOUT)pvParam;
1477 WARN("SPI_GETACCESSTIMEOUT not fully implemented\n");
1478 if (lpAccessTimeout && lpAccessTimeout->cbSize == sizeof(ACCESSTIMEOUT))
1480 /* Indicate that no accessibility features timeout is available */
1481 lpAccessTimeout->dwFlags = 0;
1482 lpAccessTimeout->iTimeOutMSec = 0;
1484 else
1486 ret = FALSE;
1488 break;
1490 WINE_SPI_FIXME(SPI_SETACCESSTIMEOUT); /* 61 */
1492 case SPI_GETSERIALKEYS: /* 62 WINVER >= 0x400 */
1494 LPSERIALKEYSA lpSerialKeysA = (LPSERIALKEYSA)pvParam;
1495 WARN("SPI_GETSERIALKEYS not fully implemented\n");
1496 if (lpSerialKeysA && lpSerialKeysA->cbSize == sizeof(SERIALKEYSA))
1498 /* Indicate that no SerialKeys feature available */
1499 lpSerialKeysA->dwFlags = 0;
1500 lpSerialKeysA->lpszActivePort = NULL;
1501 lpSerialKeysA->lpszPort = NULL;
1502 lpSerialKeysA->iBaudRate = 0;
1503 lpSerialKeysA->iPortState = 0;
1505 else
1507 ret = FALSE;
1509 break;
1511 WINE_SPI_FIXME(SPI_SETSERIALKEYS); /* 63 WINVER >= 0x400 */
1513 case SPI_GETSOUNDSENTRY: /* 64 */
1515 LPSOUNDSENTRYA lpSoundSentryA = (LPSOUNDSENTRYA)pvParam;
1516 WARN("SPI_GETSOUNDSENTRY not fully implemented\n");
1517 if (lpSoundSentryA && lpSoundSentryA->cbSize == sizeof(SOUNDSENTRYA))
1519 /* Indicate that no SoundSentry feature available */
1520 lpSoundSentryA->dwFlags = 0;
1521 lpSoundSentryA->iFSTextEffect = 0;
1522 lpSoundSentryA->iFSTextEffectMSec = 0;
1523 lpSoundSentryA->iFSTextEffectColorBits = 0;
1524 lpSoundSentryA->iFSGrafEffect = 0;
1525 lpSoundSentryA->iFSGrafEffectMSec = 0;
1526 lpSoundSentryA->iFSGrafEffectColor = 0;
1527 lpSoundSentryA->iWindowsEffect = 0;
1528 lpSoundSentryA->iWindowsEffectMSec = 0;
1529 lpSoundSentryA->lpszWindowsEffectDLL = 0;
1530 lpSoundSentryA->iWindowsEffectOrdinal = 0;
1532 else
1534 ret = FALSE;
1536 break;
1538 WINE_SPI_FIXME(SPI_SETSOUNDSENTRY); /* 65 */
1540 case SPI_GETHIGHCONTRAST: /* 66 WINVER >= 0x400 */
1542 LPHIGHCONTRASTA lpHighContrastA = (LPHIGHCONTRASTA)pvParam;
1543 WARN("SPI_GETHIGHCONTRAST not fully implemented\n");
1544 if (lpHighContrastA && lpHighContrastA->cbSize == sizeof(HIGHCONTRASTA))
1546 /* Indicate that no high contrast feature available */
1547 lpHighContrastA->dwFlags = 0;
1548 lpHighContrastA->lpszDefaultScheme = NULL;
1550 else
1552 ret = FALSE;
1554 break;
1556 WINE_SPI_FIXME(SPI_SETHIGHCONTRAST); /* 67 WINVER >= 0x400 */
1558 case SPI_GETKEYBOARDPREF: /* 68 WINVER >= 0x400 */
1559 if (!pvParam) return FALSE;
1561 spi_idx = SPI_SETKEYBOARDPREF_IDX;
1562 if (!spi_loaded[spi_idx])
1564 char buf[5];
1566 if (SYSPARAMS_Load( SPI_SETKEYBOARDPREF_REGKEY,
1567 SPI_SETKEYBOARDPREF_VALNAME, buf, sizeof(buf) ))
1568 keyboard_pref = atoi(buf);
1569 spi_loaded[spi_idx] = TRUE;
1572 *(BOOL *)pvParam = keyboard_pref;
1573 break;
1575 case SPI_SETKEYBOARDPREF: /* 69 WINVER >= 0x400 */
1577 char buf[5];
1579 spi_idx = SPI_SETKEYBOARDPREF_IDX;
1580 sprintf(buf, "%u", uiParam);
1581 if (SYSPARAMS_Save( SPI_SETKEYBOARDPREF_REGKEY,
1582 SPI_SETKEYBOARDPREF_VALNAME,
1583 buf, fWinIni ))
1585 keyboard_pref = uiParam;
1586 spi_loaded[spi_idx] = TRUE;
1588 else
1589 ret = FALSE;
1590 break;
1593 case SPI_GETSCREENREADER: /* 70 WINVER >= 0x400 */
1594 if (!pvParam) return FALSE;
1596 spi_idx = SPI_SETSCREENREADER_IDX;
1597 if (!spi_loaded[spi_idx])
1599 char buf[5];
1601 if (SYSPARAMS_Load( SPI_SETSCREENREADER_REGKEY,
1602 SPI_SETSCREENREADER_VALNAME, buf, sizeof(buf) ))
1603 screen_reader = atoi(buf);
1604 spi_loaded[spi_idx] = TRUE;
1607 *(BOOL *)pvParam = screen_reader;
1608 break;
1610 case SPI_SETSCREENREADER: /* 71 WINVER >= 0x400 */
1612 char buf[5];
1614 spi_idx = SPI_SETSCREENREADER_IDX;
1615 sprintf(buf, "%u", uiParam);
1616 if (SYSPARAMS_Save( SPI_SETSCREENREADER_REGKEY,
1617 SPI_SETSCREENREADER_VALNAME,
1618 buf, fWinIni ))
1620 screen_reader = uiParam;
1621 spi_loaded[spi_idx] = TRUE;
1623 else
1624 ret = FALSE;
1625 break;
1628 case SPI_GETANIMATION: /* 72 WINVER >= 0x400 */
1630 LPANIMATIONINFO lpAnimInfo = (LPANIMATIONINFO)pvParam;
1632 /* Tell it "disabled" */
1633 if (lpAnimInfo && lpAnimInfo->cbSize == sizeof(ANIMATIONINFO))
1634 lpAnimInfo->iMinAnimate = 0; /* Minimise and restore animation is disabled (nonzero == enabled) */
1635 else
1636 ret = FALSE;
1637 break;
1639 WINE_SPI_WARN(SPI_SETANIMATION); /* 73 WINVER >= 0x400 */
1641 WINE_SPI_FIXME(SPI_GETFONTSMOOTHING); /* 74 WINVER >= 0x400 */
1642 WINE_SPI_FIXME(SPI_SETFONTSMOOTHING); /* 75 WINVER >= 0x400 */
1644 WINE_SPI_FIXME(SPI_SETDRAGWIDTH); /* 76 WINVER >= 0x400 */
1645 WINE_SPI_FIXME(SPI_SETDRAGHEIGHT); /* 77 WINVER >= 0x400 */
1647 WINE_SPI_FIXME(SPI_SETHANDHELD); /* 78 WINVER >= 0x400 */
1649 WINE_SPI_FIXME(SPI_GETLOWPOWERTIMEOUT); /* 79 WINVER >= 0x400 */
1650 WINE_SPI_FIXME(SPI_GETPOWEROFFTIMEOUT); /* 80 WINVER >= 0x400 */
1651 WINE_SPI_FIXME(SPI_SETLOWPOWERTIMEOUT); /* 81 WINVER >= 0x400 */
1652 WINE_SPI_FIXME(SPI_SETPOWEROFFTIMEOUT); /* 82 WINVER >= 0x400 */
1653 WINE_SPI_FIXME(SPI_GETLOWPOWERACTIVE); /* 83 WINVER >= 0x400 */
1654 WINE_SPI_FIXME(SPI_GETPOWEROFFACTIVE); /* 84 WINVER >= 0x400 */
1655 WINE_SPI_FIXME(SPI_SETLOWPOWERACTIVE); /* 85 WINVER >= 0x400 */
1656 WINE_SPI_FIXME(SPI_SETPOWEROFFACTIVE); /* 86 WINVER >= 0x400 */
1658 WINE_SPI_FIXME(SPI_SETCURSORS); /* 87 WINVER >= 0x400 */
1659 WINE_SPI_FIXME(SPI_SETICONS); /* 88 WINVER >= 0x400 */
1661 case SPI_GETDEFAULTINPUTLANG: /* 89 WINVER >= 0x400 */
1662 ret = GetKeyboardLayout(0) ? TRUE : FALSE;
1663 break;
1665 WINE_SPI_FIXME(SPI_SETDEFAULTINPUTLANG); /* 90 WINVER >= 0x400 */
1667 WINE_SPI_FIXME(SPI_SETLANGTOGGLE); /* 91 WINVER >= 0x400 */
1669 case SPI_GETWINDOWSEXTENSION: /* 92 WINVER >= 0x400 */
1670 WARN("pretend no support for Win9x Plus! for now.\n");
1671 ret = FALSE; /* yes, this is the result value */
1672 break;
1674 WINE_SPI_FIXME(SPI_SETMOUSETRAILS); /* 93 WINVER >= 0x400 */
1675 WINE_SPI_FIXME(SPI_GETMOUSETRAILS); /* 94 WINVER >= 0x400 */
1677 case SPI_SETSCREENSAVERRUNNING: /* 97 WINVER >= 0x400 */
1679 /* SPI_SCREENSAVERRUNNING is an alias for SPI_SETSCREENSAVERRUNNING */
1680 char buf[5];
1682 spi_idx = SPI_SETSCREENSAVERRUNNING_IDX;
1683 sprintf(buf, "%u", uiParam);
1685 /* save only temporarily */
1686 if (SYSPARAMS_Save( SPI_SETSCREENSAVERRUNNING_REGKEY,
1687 SPI_SETSCREENSAVERRUNNING_VALNAME,
1688 buf, 0 ))
1690 screensaver_running = uiParam;
1691 spi_loaded[spi_idx] = TRUE;
1693 else
1694 ret = FALSE;
1695 break;
1698 case SPI_GETMOUSEHOVERWIDTH: /* 98 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1699 if (!pvParam) return FALSE;
1700 *(UINT *)pvParam = 4;
1701 break;
1702 WINE_SPI_FIXME(SPI_SETMOUSEHOVERWIDTH); /* 99 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1704 case SPI_GETMOUSEHOVERHEIGHT: /* 100 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1705 if (!pvParam) return FALSE;
1706 *(UINT *)pvParam = 4;
1707 break;
1708 WINE_SPI_FIXME(SPI_SETMOUSEHOVERHEIGHT); /* 101 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1710 case SPI_GETMOUSEHOVERTIME: /* 102 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1711 if (!pvParam) return FALSE;
1712 *(UINT *)pvParam = 400; /* default for menu dropdowns */
1713 break;
1714 WINE_SPI_FIXME(SPI_SETMOUSEHOVERTIME); /* 103 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1716 case SPI_GETWHEELSCROLLLINES: /* 104 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1717 if (!pvParam) return FALSE;
1718 *(UINT *)pvParam = 3; /* default for num scroll lines */
1719 break;
1721 WINE_SPI_FIXME(SPI_SETWHEELSCROLLLINES); /* 105 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1723 case SPI_GETMENUSHOWDELAY: /* 106 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1724 if (!pvParam) return FALSE;
1725 *(UINT *)pvParam = 400; /* Tested against Windows NT 4.0 and Windows 2000 */
1726 break;
1728 WINE_SPI_FIXME(SPI_GETSHOWIMEUI); /* 110 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1729 WINE_SPI_FIXME(SPI_SETSHOWIMEUI); /* 111 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1731 case SPI_GETSCREENSAVERRUNNING: /* 114 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1732 if (!pvParam) return FALSE;
1734 spi_idx = SPI_SETSCREENSAVERRUNNING_IDX;
1735 if (!spi_loaded[spi_idx])
1737 char buf[5];
1739 if (SYSPARAMS_Load( SPI_SETSCREENSAVERRUNNING_REGKEY,
1740 SPI_SETSCREENSAVERRUNNING_VALNAME, buf, sizeof(buf) ))
1741 screensaver_running = atoi( buf );
1742 spi_loaded[spi_idx] = TRUE;
1745 *(BOOL *)pvParam = screensaver_running;
1746 break;
1748 case SPI_GETDESKWALLPAPER: /* 115 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1750 char buf[MAX_PATH];
1752 if (!pvParam) return FALSE;
1754 if (uiParam > MAX_PATH)
1756 uiParam = MAX_PATH;
1759 if (SYSPARAMS_Load(SPI_SETDESKWALLPAPER_REGKEY, SPI_SETDESKWALLPAPER_VALNAME, buf, sizeof(buf)))
1761 strncpy((char*)pvParam, buf, uiParam);
1763 else
1765 /* Return an empty string */
1766 memset((char*)pvParam, 0, uiParam);
1769 break;
1772 WINE_SPI_FIXME(SPI_GETACTIVEWINDOWTRACKING);/* 0x1000 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1773 WINE_SPI_FIXME(SPI_SETACTIVEWINDOWTRACKING);/* 0x1001 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1774 WINE_SPI_FIXME(SPI_GETMENUANIMATION); /* 0x1002 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1775 WINE_SPI_FIXME(SPI_SETMENUANIMATION); /* 0x1003 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1776 WINE_SPI_FIXME(SPI_GETCOMBOBOXANIMATION); /* 0x1004 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1777 WINE_SPI_FIXME(SPI_SETCOMBOBOXANIMATION); /* 0x1005 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1778 WINE_SPI_FIXME(SPI_GETLISTBOXSMOOTHSCROLLING);/* 0x1006 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1779 WINE_SPI_FIXME(SPI_SETLISTBOXSMOOTHSCROLLING);/* 0x1007 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1781 case SPI_GETGRADIENTCAPTIONS: /* 0x1008 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1782 if (!pvParam) return FALSE;
1783 FIXME("case SPI_GETGRADIENTCAPTIONS always return false\n");
1784 *(BOOL *)pvParam = FALSE;
1785 break;
1787 WINE_SPI_FIXME(SPI_SETGRADIENTCAPTIONS); /* 0x1009 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1788 WINE_SPI_FIXME(SPI_GETKEYBOARDCUES); /* 0x100A _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1789 WINE_SPI_FIXME(SPI_SETKEYBOARDCUES); /* 0x100B _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1790 WINE_SPI_FIXME(SPI_GETACTIVEWNDTRKZORDER); /* 0x100C _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1791 WINE_SPI_FIXME(SPI_SETACTIVEWNDTRKZORDER); /* 0x100D _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1792 WINE_SPI_FIXME(SPI_GETHOTTRACKING); /* 0x100E _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1793 WINE_SPI_FIXME(SPI_SETHOTTRACKING); /* 0x100F _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1794 WINE_SPI_FIXME(SPI_GETSELECTIONFADE); /* 0x1014 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1795 WINE_SPI_FIXME(SPI_SETSELECTIONFADE); /* 0x1015 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1796 WINE_SPI_FIXME(SPI_GETDROPSHADOW); /* 0x1024 _WIN32_WINNT >= 0x510 */
1797 WINE_SPI_FIXME(SPI_SETDROPSHADOW); /* 0x1025 _WIN32_WINNT >= 0x510 */
1798 WINE_SPI_FIXME(SPI_GETFOREGROUNDLOCKTIMEOUT);/* 0x2000 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1799 WINE_SPI_FIXME(SPI_SETFOREGROUNDLOCKTIMEOUT);/* 0x2001 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1800 WINE_SPI_FIXME(SPI_GETACTIVEWNDTRKTIMEOUT); /* 0x2002 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1801 WINE_SPI_FIXME(SPI_SETACTIVEWNDTRKTIMEOUT); /* 0x2003 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1802 WINE_SPI_FIXME(SPI_GETFOREGROUNDFLASHCOUNT);/* 0x2004 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1803 WINE_SPI_FIXME(SPI_SETFOREGROUNDFLASHCOUNT);/* 0x2005 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1805 default:
1806 FIXME( "Unknown action: %u\n", uiAction );
1807 SetLastError( ERROR_INVALID_SPI_VALUE );
1808 ret = FALSE;
1809 break;
1812 if (ret)
1813 SYSPARAMS_NotifyChange( uiAction, fWinIni );
1814 return ret;
1816 #undef WINE_SPI_FIXME
1817 #undef WINE_SPI_WARN
1821 /***********************************************************************
1822 * SystemParametersInfo (USER.483)
1824 BOOL16 WINAPI SystemParametersInfo16( UINT16 uAction, UINT16 uParam,
1825 LPVOID lpvParam, UINT16 fuWinIni )
1827 BOOL16 ret;
1829 TRACE("(%u, %u, %p, %u)\n", uAction, uParam, lpvParam, fuWinIni);
1831 switch (uAction)
1833 case SPI_GETBEEP: /* 1 */
1834 case SPI_GETSCREENSAVEACTIVE: /* 16 */
1835 case SPI_GETICONTITLEWRAP: /* 25 */
1836 case SPI_GETMENUDROPALIGNMENT: /* 27 */
1837 case SPI_GETFASTTASKSWITCH: /* 35 */
1838 case SPI_GETDRAGFULLWINDOWS: /* 38 WINVER >= 0x0400 */
1840 BOOL tmp;
1841 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1842 if (ret && lpvParam)
1843 *(BOOL16 *)lpvParam = tmp;
1844 break;
1847 case SPI_GETBORDER: /* 5 */
1848 case SPI_ICONHORIZONTALSPACING: /* 13 */
1849 case SPI_GETSCREENSAVETIMEOUT: /* 14 */
1850 case SPI_GETGRIDGRANULARITY: /* 18 */
1851 case SPI_GETKEYBOARDDELAY: /* 22 */
1852 case SPI_ICONVERTICALSPACING: /* 24 */
1854 INT tmp;
1855 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1856 if (ret && lpvParam)
1857 *(INT16 *)lpvParam = tmp;
1858 break;
1861 case SPI_GETKEYBOARDSPEED: /* 10 */
1863 DWORD tmp;
1864 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1865 if (ret && lpvParam)
1866 *(WORD *)lpvParam = tmp;
1867 break;
1870 case SPI_GETICONTITLELOGFONT: /* 31 */
1872 LOGFONTA tmp;
1873 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1874 if (ret && lpvParam)
1875 SYSPARAMS_LogFont32ATo16( &tmp, (LPLOGFONT16)lpvParam );
1876 break;
1879 case SPI_GETNONCLIENTMETRICS: /* 41 WINVER >= 0x400 */
1881 NONCLIENTMETRICSA tmp;
1882 LPNONCLIENTMETRICS16 lpnm16 = (LPNONCLIENTMETRICS16)lpvParam;
1883 if (lpnm16 && lpnm16->cbSize == sizeof(NONCLIENTMETRICS16))
1885 tmp.cbSize = sizeof(NONCLIENTMETRICSA);
1886 ret = SystemParametersInfoA( uAction, uParam, &tmp, fuWinIni );
1887 if (ret)
1888 SYSPARAMS_NonClientMetrics32ATo16( &tmp, lpnm16 );
1890 else /* winfile 95 sets cbSize to 340 */
1891 ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
1892 break;
1895 case SPI_GETWORKAREA: /* 48 WINVER >= 0x400 */
1897 RECT tmp;
1898 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1899 if (ret && lpvParam)
1900 CONV_RECT32TO16( &tmp, (RECT16 *)lpvParam );
1901 break;
1904 case SPI_GETMOUSEHOVERWIDTH: /* 98 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1905 case SPI_GETMOUSEHOVERHEIGHT: /* 100 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1906 case SPI_GETMOUSEHOVERTIME: /* 102 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1908 UINT tmp;
1909 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1910 if (ret && lpvParam)
1911 *(UINT16 *)lpvParam = tmp;
1912 break;
1915 default:
1916 ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
1919 return ret;
1922 /***********************************************************************
1923 * SystemParametersInfoW (USER32.@)
1925 BOOL WINAPI SystemParametersInfoW( UINT uiAction, UINT uiParam,
1926 PVOID pvParam, UINT fuWinIni )
1928 BOOL ret;
1930 TRACE("(%u, %u, %p, %u)\n", uiAction, uiParam, pvParam, fuWinIni);
1932 switch (uiAction)
1934 case SPI_SETDESKWALLPAPER: /* 20 */
1935 case SPI_SETDESKPATTERN: /* 21 */
1937 char buffer[256];
1938 if (pvParam)
1939 if (!WideCharToMultiByte( CP_ACP, 0, (LPWSTR)pvParam, -1,
1940 buffer, sizeof(buffer), NULL, NULL ))
1941 buffer[sizeof(buffer)-1] = 0;
1942 ret = SystemParametersInfoA( uiAction, uiParam, pvParam ? buffer : NULL, fuWinIni );
1943 break;
1946 case SPI_GETICONTITLELOGFONT: /* 31 */
1948 LOGFONTA tmp;
1949 ret = SystemParametersInfoA( uiAction, uiParam, pvParam ? &tmp : NULL, fuWinIni );
1950 if (ret && pvParam)
1951 SYSPARAMS_LogFont32ATo32W( &tmp, (LPLOGFONTW)pvParam );
1952 break;
1955 case SPI_GETNONCLIENTMETRICS: /* 41 WINVER >= 0x400 */
1957 NONCLIENTMETRICSA tmp;
1958 LPNONCLIENTMETRICSW lpnmW = (LPNONCLIENTMETRICSW)pvParam;
1959 if (lpnmW && lpnmW->cbSize == sizeof(NONCLIENTMETRICSW))
1961 tmp.cbSize = sizeof(NONCLIENTMETRICSA);
1962 ret = SystemParametersInfoA( uiAction, uiParam, &tmp, fuWinIni );
1963 if (ret)
1964 SYSPARAMS_NonClientMetrics32ATo32W( &tmp, lpnmW );
1966 else
1967 ret = FALSE;
1968 break;
1971 case SPI_GETICONMETRICS: /* 45 WINVER >= 0x400 */
1973 ICONMETRICSA tmp;
1974 LPICONMETRICSW lpimW = (LPICONMETRICSW)pvParam;
1975 if (lpimW && lpimW->cbSize == sizeof(ICONMETRICSW))
1977 tmp.cbSize = sizeof(ICONMETRICSA);
1978 ret = SystemParametersInfoA( uiAction, uiParam, &tmp, fuWinIni );
1979 if (ret)
1981 lpimW->iHorzSpacing = tmp.iHorzSpacing;
1982 lpimW->iVertSpacing = tmp.iVertSpacing;
1983 lpimW->iTitleWrap = tmp.iTitleWrap;
1984 SYSPARAMS_LogFont32ATo32W( &tmp.lfFont, &lpimW->lfFont );
1987 else
1988 ret = FALSE;
1989 break;
1992 case SPI_GETHIGHCONTRAST: /* 66 WINVER >= 0x400 */
1994 HIGHCONTRASTA tmp;
1995 LPHIGHCONTRASTW lphcW = (LPHIGHCONTRASTW)pvParam;
1996 if (lphcW && lphcW->cbSize == sizeof(HIGHCONTRASTW))
1998 tmp.cbSize = sizeof(HIGHCONTRASTA);
1999 ret = SystemParametersInfoA( uiAction, uiParam, &tmp, fuWinIni );
2000 if (ret)
2002 lphcW->dwFlags = tmp.dwFlags;
2003 lphcW->lpszDefaultScheme = NULL; /* FIXME? */
2006 else
2007 ret = FALSE;
2008 break;
2011 default:
2012 ret = SystemParametersInfoA( uiAction, uiParam, pvParam, fuWinIni );
2013 break;
2015 return ret;
2019 /**********************************************************************
2020 * SetDoubleClickTime (USER32.@)
2022 BOOL WINAPI SetDoubleClickTime( UINT interval )
2024 return SystemParametersInfoA(SPI_SETDOUBLECLICKTIME, interval, 0, 0);
2028 /**********************************************************************
2029 * GetDoubleClickTime (USER32.@)
2031 UINT WINAPI GetDoubleClickTime(void)
2033 char buf[10];
2035 if (!spi_loaded[SPI_SETDOUBLECLICKTIME_IDX])
2037 if (SYSPARAMS_Load( SPI_SETDOUBLECLICKTIME_REGKEY,
2038 SPI_SETDOUBLECLICKTIME_VALNAME,
2039 buf, sizeof(buf) ))
2041 double_click_time = atoi( buf );
2042 if (!double_click_time) double_click_time = 500;
2044 spi_loaded[SPI_SETDOUBLECLICKTIME_IDX] = TRUE;
2046 return double_click_time;