Mask off bit 0x80 in the accelerator table entry field fVirt if it's
[wine.git] / windows / sysparams.c
blob7b48a61246fa37e8aac6df12db9d47411ace5c10
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 <stdarg.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winnls.h"
30 #include "wingdi.h"
31 #include "winreg.h"
32 #include "wine/winuser16.h"
33 #include "winerror.h"
35 #include "controls.h"
36 #include "user.h"
37 #include "wine/debug.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(system);
41 /* System parameter indexes */
42 #define SPI_SETBEEP_IDX 0
43 #define SPI_SETMOUSE_IDX 1
44 #define SPI_SETBORDER_IDX 2
45 #define SPI_SETKEYBOARDSPEED_IDX 3
46 #define SPI_ICONHORIZONTALSPACING_IDX 4
47 #define SPI_SETSCREENSAVETIMEOUT_IDX 5
48 #define SPI_SETGRIDGRANULARITY_IDX 6
49 #define SPI_SETKEYBOARDDELAY_IDX 7
50 #define SPI_ICONVERTICALSPACING_IDX 8
51 #define SPI_SETICONTITLEWRAP_IDX 9
52 #define SPI_SETMENUDROPALIGNMENT_IDX 10
53 #define SPI_SETDOUBLECLKWIDTH_IDX 11
54 #define SPI_SETDOUBLECLKHEIGHT_IDX 12
55 #define SPI_SETDOUBLECLICKTIME_IDX 13
56 #define SPI_SETMOUSEBUTTONSWAP_IDX 14
57 #define SPI_SETDRAGFULLWINDOWS_IDX 15
58 #define SPI_SETWORKAREA_IDX 16
59 #define SPI_SETSHOWSOUNDS_IDX 17
60 #define SPI_SETKEYBOARDPREF_IDX 18
61 #define SPI_SETSCREENREADER_IDX 19
62 #define SPI_SETSCREENSAVERRUNNING_IDX 20
63 #define SPI_WINE_IDX SPI_SETSCREENSAVERRUNNING_IDX
65 /**
66 * Names of the registry subkeys of HKEY_CURRENT_USER key and value names
67 * for the system parameters.
68 * Names of the keys are created by adding string "_REGKEY" to
69 * "SET" action names, value names are created by adding "_REG_NAME"
70 * to the "SET" action name.
72 #define SPI_SETBEEP_REGKEY "Control Panel\\Sound"
73 #define SPI_SETBEEP_VALNAME "Beep"
74 #define SPI_SETMOUSE_REGKEY "Control Panel\\Mouse"
75 #define SPI_SETMOUSE_VALNAME1 "MouseThreshold1"
76 #define SPI_SETMOUSE_VALNAME2 "MouseThreshold2"
77 #define SPI_SETMOUSE_VALNAME3 "MouseSpeed"
78 #define SPI_SETBORDER_REGKEY "Control Panel\\Desktop"
79 #define SPI_SETBORDER_VALNAME "BorderWidth"
80 #define SPI_SETKEYBOARDSPEED_REGKEY "Control Panel\\Keyboard"
81 #define SPI_SETKEYBOARDSPEED_VALNAME "KeyboardSpeed"
82 #define SPI_ICONHORIZONTALSPACING_REGKEY "Control Panel\\Desktop\\WindowMetrics"
83 #define SPI_ICONHORIZONTALSPACING_VALNAME "IconSpacing"
84 #define SPI_SETSCREENSAVETIMEOUT_REGKEY "Control Panel\\Desktop"
85 #define SPI_SETSCREENSAVETIMEOUT_VALNAME "ScreenSaveTimeOut"
86 #define SPI_SETSCREENSAVEACTIVE_REGKEY "Control Panel\\Desktop"
87 #define SPI_SETSCREENSAVEACTIVE_VALNAME "ScreenSaveActive"
88 #define SPI_SETGRIDGRANULARITY_REGKEY "Control Panel\\Desktop"
89 #define SPI_SETGRIDGRANULARITY_VALNAME "GridGranularity"
90 #define SPI_SETKEYBOARDDELAY_REGKEY "Control Panel\\Keyboard"
91 #define SPI_SETKEYBOARDDELAY_VALNAME "KeyboardDelay"
92 #define SPI_ICONVERTICALSPACING_REGKEY "Control Panel\\Desktop\\WindowMetrics"
93 #define SPI_ICONVERTICALSPACING_VALNAME "IconVerticalSpacing"
94 #define SPI_SETICONTITLEWRAP_REGKEY1 "Control Panel\\Desktop\\WindowMetrics"
95 #define SPI_SETICONTITLEWRAP_REGKEY2 "Control Panel\\Desktop"
96 #define SPI_SETICONTITLEWRAP_VALNAME "IconTitleWrap"
97 #define SPI_SETMENUDROPALIGNMENT_REGKEY1 "Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows"
98 #define SPI_SETMENUDROPALIGNMENT_REGKEY2 "Control Panel\\Desktop"
99 #define SPI_SETMENUDROPALIGNMENT_VALNAME "MenuDropAlignment"
100 #define SPI_SETDOUBLECLKWIDTH_REGKEY1 "Control Panel\\Mouse"
101 #define SPI_SETDOUBLECLKWIDTH_REGKEY2 "Control Panel\\Desktop"
102 #define SPI_SETDOUBLECLKWIDTH_VALNAME "DoubleClickWidth"
103 #define SPI_SETDOUBLECLKHEIGHT_REGKEY1 "Control Panel\\Mouse"
104 #define SPI_SETDOUBLECLKHEIGHT_REGKEY2 "Control Panel\\Desktop"
105 #define SPI_SETDOUBLECLKHEIGHT_VALNAME "DoubleClickHeight"
106 #define SPI_SETDOUBLECLICKTIME_REGKEY "Control Panel\\Mouse"
107 #define SPI_SETDOUBLECLICKTIME_VALNAME "DoubleClickSpeed"
108 #define SPI_SETMOUSEBUTTONSWAP_REGKEY "Control Panel\\Mouse"
109 #define SPI_SETMOUSEBUTTONSWAP_VALNAME "SwapMouseButtons"
110 #define SPI_SETDRAGFULLWINDOWS_REGKEY "Control Panel\\Desktop"
111 #define SPI_SETDRAGFULLWINDOWS_VALNAME "DragFullWindows"
112 #define SPI_SETWORKAREA_REGKEY "Control Panel\\Desktop"
113 #define SPI_SETWORKAREA_VALNAME "WINE_WorkArea"
114 #define SPI_SETSHOWSOUNDS_REGKEY "Control Panel\\Accessibility\\ShowSounds"
115 #define SPI_SETSHOWSOUNDS_VALNAME "On"
116 #define SPI_SETDESKWALLPAPER_REGKEY "Control Panel\\Desktop"
117 #define SPI_SETDESKWALLPAPER_VALNAME "Wallpaper"
118 /* FIXME - real values */
119 #define SPI_SETKEYBOARDPREF_REGKEY "Control Panel\\Desktop"
120 #define SPI_SETKEYBOARDPREF_VALNAME "WINE_KeyboardPref"
121 #define SPI_SETSCREENREADER_REGKEY "Control Panel\\Desktop"
122 #define SPI_SETSCREENREADER_VALNAME "WINE_ScreenReader"
123 #define SPI_SETSCREENSAVERRUNNING_REGKEY "Control Panel\\Desktop"
124 #define SPI_SETSCREENSAVERRUNNING_VALNAME "WINE_ScreenSaverRunning"
126 /* volatile registry branch under CURRENT_USER_REGKEY for temporary values storage */
127 #define WINE_CURRENT_USER_REGKEY "Wine"
129 /* Indicators whether system parameter value is loaded */
130 static char spi_loaded[SPI_WINE_IDX + 1];
132 static BOOL notify_change = TRUE;
134 /* System parameters storage */
135 static BOOL beep_active = TRUE;
136 static int mouse_threshold1 = 6;
137 static int mouse_threshold2 = 10;
138 static int mouse_speed = 1;
139 static int border = 1;
140 static int keyboard_speed = 31;
141 static int screensave_timeout = 300;
142 static int grid_granularity = 0;
143 static int keyboard_delay = 1;
144 static BOOL icon_title_wrap = TRUE;
145 static int double_click_time = 500;
146 static BOOL drag_full_windows = FALSE;
147 static RECT work_area;
148 static BOOL keyboard_pref = TRUE;
149 static BOOL screen_reader = FALSE;
150 static BOOL screensaver_running = FALSE;
152 /***********************************************************************
153 * GetTimerResolution (USER.14)
155 LONG WINAPI GetTimerResolution16(void)
157 return (1000);
160 /***********************************************************************
161 * ControlPanelInfo (USER.273)
163 void WINAPI ControlPanelInfo16( INT16 nInfoType, WORD wData, LPSTR lpBuffer )
165 FIXME("(%d, %04x, %p): stub.\n", nInfoType, wData, lpBuffer);
168 /* This function is a copy of the one in objects/font.c */
169 static void SYSPARAMS_LogFont32ATo16( const LOGFONTA* font32, LPLOGFONT16 font16 )
171 font16->lfHeight = font32->lfHeight;
172 font16->lfWidth = font32->lfWidth;
173 font16->lfEscapement = font32->lfEscapement;
174 font16->lfOrientation = font32->lfOrientation;
175 font16->lfWeight = font32->lfWeight;
176 font16->lfItalic = font32->lfItalic;
177 font16->lfUnderline = font32->lfUnderline;
178 font16->lfStrikeOut = font32->lfStrikeOut;
179 font16->lfCharSet = font32->lfCharSet;
180 font16->lfOutPrecision = font32->lfOutPrecision;
181 font16->lfClipPrecision = font32->lfClipPrecision;
182 font16->lfQuality = font32->lfQuality;
183 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
184 lstrcpynA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
187 static void SYSPARAMS_LogFont32ATo32W( const LOGFONTA* font32A, LPLOGFONTW font32W )
189 font32W->lfHeight = font32A->lfHeight;
190 font32W->lfWidth = font32A->lfWidth;
191 font32W->lfEscapement = font32A->lfEscapement;
192 font32W->lfOrientation = font32A->lfOrientation;
193 font32W->lfWeight = font32A->lfWeight;
194 font32W->lfItalic = font32A->lfItalic;
195 font32W->lfUnderline = font32A->lfUnderline;
196 font32W->lfStrikeOut = font32A->lfStrikeOut;
197 font32W->lfCharSet = font32A->lfCharSet;
198 font32W->lfOutPrecision = font32A->lfOutPrecision;
199 font32W->lfClipPrecision = font32A->lfClipPrecision;
200 font32W->lfQuality = font32A->lfQuality;
201 font32W->lfPitchAndFamily = font32A->lfPitchAndFamily;
202 MultiByteToWideChar( CP_ACP, 0, font32A->lfFaceName, -1, font32W->lfFaceName, LF_FACESIZE );
203 font32W->lfFaceName[LF_FACESIZE-1] = 0;
206 static void SYSPARAMS_NonClientMetrics32ATo16( const NONCLIENTMETRICSA* lpnm32, LPNONCLIENTMETRICS16 lpnm16 )
208 lpnm16->iBorderWidth = lpnm32->iBorderWidth;
209 lpnm16->iScrollWidth = lpnm32->iScrollWidth;
210 lpnm16->iScrollHeight = lpnm32->iScrollHeight;
211 lpnm16->iCaptionWidth = lpnm32->iCaptionWidth;
212 lpnm16->iCaptionHeight = lpnm32->iCaptionHeight;
213 SYSPARAMS_LogFont32ATo16( &lpnm32->lfCaptionFont, &lpnm16->lfCaptionFont );
214 lpnm16->iSmCaptionWidth = lpnm32->iSmCaptionWidth;
215 lpnm16->iSmCaptionHeight = lpnm32->iSmCaptionHeight;
216 SYSPARAMS_LogFont32ATo16( &lpnm32->lfSmCaptionFont, &lpnm16->lfSmCaptionFont );
217 lpnm16->iMenuWidth = lpnm32->iMenuWidth;
218 lpnm16->iMenuHeight = lpnm32->iMenuHeight;
219 SYSPARAMS_LogFont32ATo16( &lpnm32->lfMenuFont, &lpnm16->lfMenuFont );
220 SYSPARAMS_LogFont32ATo16( &lpnm32->lfStatusFont, &lpnm16->lfStatusFont );
221 SYSPARAMS_LogFont32ATo16( &lpnm32->lfMessageFont, &lpnm16->lfMessageFont );
224 static void SYSPARAMS_NonClientMetrics32ATo32W( const NONCLIENTMETRICSA* lpnm32A, LPNONCLIENTMETRICSW lpnm32W )
226 lpnm32W->iBorderWidth = lpnm32A->iBorderWidth;
227 lpnm32W->iScrollWidth = lpnm32A->iScrollWidth;
228 lpnm32W->iScrollHeight = lpnm32A->iScrollHeight;
229 lpnm32W->iCaptionWidth = lpnm32A->iCaptionWidth;
230 lpnm32W->iCaptionHeight = lpnm32A->iCaptionHeight;
231 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfCaptionFont, &lpnm32W->lfCaptionFont );
232 lpnm32W->iSmCaptionWidth = lpnm32A->iSmCaptionWidth;
233 lpnm32W->iSmCaptionHeight = lpnm32A->iSmCaptionHeight;
234 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfSmCaptionFont, &lpnm32W->lfSmCaptionFont );
235 lpnm32W->iMenuWidth = lpnm32A->iMenuWidth;
236 lpnm32W->iMenuHeight = lpnm32A->iMenuHeight;
237 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfMenuFont, &lpnm32W->lfMenuFont );
238 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfStatusFont, &lpnm32W->lfStatusFont );
239 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfMessageFont, &lpnm32W->lfMessageFont );
242 /***********************************************************************
243 * SYSPARAMS_Reset
245 * Sets the system parameter which should be always loaded to
246 * current value stored in registry.
247 * Invalidates lazy loaded parameter, so it will be loaded the next time
248 * it is requested.
250 * Parameters:
251 * uiAction - system parameter to reload value for.
252 * Note, only "SET" values can be used for this parameter.
253 * If uiAction is 0 all system parameters are reset.
255 void SYSPARAMS_Reset( UINT uiAction )
257 #define WINE_RELOAD_SPI(x) \
258 case x: \
259 spi_loaded[x##_IDX] = FALSE; \
260 SystemParametersInfoA( x, 0, dummy_buf, 0 );\
261 if (uiAction) \
262 break
264 #define WINE_IGNORE_SPI(x) \
265 case x: \
266 if (uiAction) \
267 break
269 #define WINE_INVALIDATE_SPI(x) \
270 case x: \
271 spi_loaded[x##_IDX] = FALSE; \
272 break
274 BOOL not_all_processed = TRUE;
275 char dummy_buf[10];
277 /* Execution falls through all the branches for uiAction == 0 */
278 switch (uiAction)
280 case 0:
281 memset( spi_loaded, 0, sizeof(spi_loaded) );
283 WINE_RELOAD_SPI(SPI_SETBORDER);
284 WINE_RELOAD_SPI(SPI_ICONHORIZONTALSPACING);
285 WINE_RELOAD_SPI(SPI_ICONVERTICALSPACING);
286 WINE_IGNORE_SPI(SPI_SETSCREENSAVEACTIVE);
287 WINE_RELOAD_SPI(SPI_SETDOUBLECLKWIDTH);
288 WINE_RELOAD_SPI(SPI_SETDOUBLECLKHEIGHT);
289 WINE_RELOAD_SPI(SPI_SETMOUSEBUTTONSWAP);
290 WINE_RELOAD_SPI(SPI_SETSHOWSOUNDS);
291 WINE_RELOAD_SPI(SPI_SETMENUDROPALIGNMENT);
293 default:
294 if (uiAction)
296 /* lazy loaded parameters */
297 switch (uiAction)
299 WINE_INVALIDATE_SPI(SPI_SETBEEP);
300 WINE_INVALIDATE_SPI(SPI_SETMOUSE);
301 WINE_INVALIDATE_SPI(SPI_SETKEYBOARDSPEED);
302 WINE_INVALIDATE_SPI(SPI_SETSCREENSAVETIMEOUT);
303 WINE_INVALIDATE_SPI(SPI_SETGRIDGRANULARITY);
304 WINE_INVALIDATE_SPI(SPI_SETKEYBOARDDELAY);
305 WINE_INVALIDATE_SPI(SPI_SETICONTITLEWRAP);
306 WINE_INVALIDATE_SPI(SPI_SETDOUBLECLICKTIME);
307 WINE_INVALIDATE_SPI(SPI_SETDRAGFULLWINDOWS);
308 WINE_INVALIDATE_SPI(SPI_SETWORKAREA);
309 WINE_INVALIDATE_SPI(SPI_SETKEYBOARDPREF);
310 WINE_INVALIDATE_SPI(SPI_SETSCREENREADER);
311 WINE_INVALIDATE_SPI(SPI_SETSCREENSAVERRUNNING);
312 default:
313 FIXME( "Unknown action reset: %u\n", uiAction );
314 break;
317 else
318 not_all_processed = FALSE;
319 break;
322 if (!uiAction && not_all_processed)
323 ERR( "Incorrect implementation of SYSPARAMS_Reset. "
324 "Not all params are reloaded.\n" );
325 #undef WINE_INVALIDATE_SPI
326 #undef WINE_IGNORE_SPI
327 #undef WINE_RELOAD_SPI
330 /***********************************************************************
331 * get_volatile_regkey
333 * Return a handle to the volatile registry key used to store
334 * non-permanently modified parameters.
336 static HKEY get_volatile_regkey(void)
338 static HKEY volatile_key;
340 if (!volatile_key)
342 if (RegCreateKeyExA( HKEY_CURRENT_USER, WINE_CURRENT_USER_REGKEY,
343 0, 0, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, 0,
344 &volatile_key, 0 ) != ERROR_SUCCESS)
345 ERR("Can't create wine configuration registry branch\n");
347 return volatile_key;
350 /***********************************************************************
351 * SYSPARAMS_NotifyChange
353 * Sends notification about system parameter update.
355 void SYSPARAMS_NotifyChange( UINT uiAction, UINT fWinIni )
357 static const WCHAR emptyW[1];
359 if (notify_change)
361 if (fWinIni & SPIF_UPDATEINIFILE)
363 if (fWinIni & (SPIF_SENDWININICHANGE | SPIF_SENDCHANGE))
364 SendMessageTimeoutW(HWND_BROADCAST, WM_SETTINGCHANGE,
365 uiAction, (LPARAM) emptyW,
366 SMTO_ABORTIFHUNG, 2000, NULL );
368 else
370 /* FIXME notify other wine processes with internal message */
376 /***********************************************************************
377 * Loads system parameter from user profile.
379 static BOOL SYSPARAMS_Load( LPCSTR lpRegKey, LPCSTR lpValName, LPSTR lpBuf, DWORD count )
381 BOOL ret = FALSE;
382 DWORD type;
383 HKEY hKey;
385 if ((RegOpenKeyA( get_volatile_regkey(), lpRegKey, &hKey ) == ERROR_SUCCESS) ||
386 (RegOpenKeyA( HKEY_CURRENT_USER, lpRegKey, &hKey ) == ERROR_SUCCESS))
388 ret = !RegQueryValueExA( hKey, lpValName, NULL, &type, lpBuf, &count );
389 RegCloseKey( hKey );
391 return ret;
394 /***********************************************************************
395 * Saves system parameter to user profile.
397 static BOOL SYSPARAMS_Save( LPCSTR lpRegKey, LPCSTR lpValName, LPCSTR lpValue,
398 UINT fWinIni )
400 HKEY hKey;
401 HKEY hBaseKey;
402 DWORD dwOptions;
403 BOOL ret = FALSE;
405 if (fWinIni & SPIF_UPDATEINIFILE)
407 hBaseKey = HKEY_CURRENT_USER;
408 dwOptions = 0;
410 else
412 hBaseKey = get_volatile_regkey();
413 dwOptions = REG_OPTION_VOLATILE;
416 if (RegCreateKeyExA( hBaseKey, lpRegKey,
417 0, 0, dwOptions, KEY_ALL_ACCESS,
418 0, &hKey, 0 ) == ERROR_SUCCESS)
420 if (RegSetValueExA( hKey, lpValName, 0, REG_SZ,
421 lpValue, strlen(lpValue) + 1 ) == ERROR_SUCCESS)
423 ret = TRUE;
424 if (hBaseKey == HKEY_CURRENT_USER)
425 RegDeleteKeyA( get_volatile_regkey(), lpRegKey );
427 RegCloseKey( hKey );
429 return ret;
433 /***********************************************************************
434 * SYSPARAMS_GetDoubleClickSize
436 * There is no SPI_GETDOUBLECLK* so we export this function instead.
438 void SYSPARAMS_GetDoubleClickSize( INT *width, INT *height )
440 char buf[10];
442 if (!spi_loaded[SPI_SETDOUBLECLKWIDTH_IDX])
444 char buf[10];
446 if (SYSPARAMS_Load( SPI_SETDOUBLECLKWIDTH_REGKEY1,
447 SPI_SETDOUBLECLKWIDTH_VALNAME, buf, sizeof(buf) ))
449 SYSMETRICS_Set( SM_CXDOUBLECLK, atoi( buf ) );
451 spi_loaded[SPI_SETDOUBLECLKWIDTH_IDX] = TRUE;
453 if (!spi_loaded[SPI_SETDOUBLECLKHEIGHT_IDX])
455 if (SYSPARAMS_Load( SPI_SETDOUBLECLKHEIGHT_REGKEY1,
456 SPI_SETDOUBLECLKHEIGHT_VALNAME, buf, sizeof(buf) ))
458 SYSMETRICS_Set( SM_CYDOUBLECLK, atoi( buf ) );
460 spi_loaded[SPI_SETDOUBLECLKHEIGHT_IDX] = TRUE;
462 *width = GetSystemMetrics( SM_CXDOUBLECLK );
463 *height = GetSystemMetrics( SM_CYDOUBLECLK );
467 /***********************************************************************
468 * SYSPARAMS_GetMouseButtonSwap
470 * There is no SPI_GETMOUSEBUTTONSWAP so we export this function instead.
472 INT SYSPARAMS_GetMouseButtonSwap( void )
474 int spi_idx = SPI_SETMOUSEBUTTONSWAP_IDX;
476 if (!spi_loaded[spi_idx])
478 char buf[5];
480 if (SYSPARAMS_Load( SPI_SETMOUSEBUTTONSWAP_REGKEY,
481 SPI_SETMOUSEBUTTONSWAP_VALNAME, buf, sizeof(buf) ))
483 SYSMETRICS_Set( SM_SWAPBUTTON, atoi( buf ) );
485 spi_loaded[spi_idx] = TRUE;
488 return GetSystemMetrics( SM_SWAPBUTTON );
491 /***********************************************************************
493 * SYSPARAMS_GetGUIFont
495 * fills LOGFONT with 'default GUI font'.
498 static void SYSPARAMS_GetGUIFont( LOGFONTA* plf )
500 HFONT hf;
502 memset( plf, 0, sizeof(LOGFONTA) );
503 hf = (HFONT)GetStockObject( DEFAULT_GUI_FONT );
504 if ( GetObjectA( hf, sizeof(LOGFONTA), plf ) != sizeof(LOGFONTA) )
507 * GetObjectA() would be succeeded always
508 * since this is a stock object
510 ERR("GetObjectA() failed\n");
514 /* copied from GetSystemMetrics()'s RegistryTwips2Pixels() */
515 inline static int SYSPARAMS_Twips2Pixels(int x)
517 if (x < 0)
518 x = (-x+7)/15;
519 return x;
522 /***********************************************************************
523 * SystemParametersInfoA (USER32.@)
525 * Each system parameter has flag which shows whether the parameter
526 * is loaded or not. Parameters, stored directly in SysParametersInfo are
527 * loaded from registry only when they are requested and the flag is
528 * "false", after the loading the flag is set to "true". On interprocess
529 * notification of the parameter change the corresponding parameter flag is
530 * set to "false". The parameter value will be reloaded when it is requested
531 * the next time.
532 * Parameters, backed by or depend on GetSystemMetrics are processed
533 * differently. These parameters are always loaded. They are reloaded right
534 * away on interprocess change notification. We can't do lazy loading because
535 * we don't want to complicate GetSystemMetrics.
536 * Parameters, backed by X settings are read from corresponding setting.
537 * On the parameter change request the setting is changed. Interprocess change
538 * notifications are ignored.
539 * When parameter value is updated the changed value is stored in permanent
540 * registry branch if saving is requested. Otherwise it is stored
541 * in temporary branch
543 * Some SPI values can also be stored as Twips values in the registry,
544 * don't forget the conversion!
546 BOOL WINAPI SystemParametersInfoA( UINT uiAction, UINT uiParam,
547 PVOID pvParam, UINT fWinIni )
549 #define WINE_SPI_FIXME(x) \
550 case x: \
551 FIXME( "Unimplemented action: %u (%s)\n", x, #x ); \
552 SetLastError( ERROR_INVALID_SPI_VALUE ); \
553 ret = FALSE; \
554 break
555 #define WINE_SPI_WARN(x) \
556 case x: \
557 WARN( "Ignored action: %u (%s)\n", x, #x ); \
558 break
560 BOOL ret = TRUE;
561 unsigned spi_idx = 0;
563 TRACE("(%u, %u, %p, %u)\n", uiAction, uiParam, pvParam, fWinIni);
565 switch (uiAction)
567 case SPI_GETBEEP: /* 1 */
568 if (!pvParam) return FALSE;
570 spi_idx = SPI_SETBEEP_IDX;
571 if (!spi_loaded[spi_idx])
573 char buf[5];
575 if (SYSPARAMS_Load( SPI_SETBEEP_REGKEY, SPI_SETBEEP_VALNAME, buf, sizeof(buf) ))
576 beep_active = !strcasecmp( "Yes", buf );
577 spi_loaded[spi_idx] = TRUE;
580 *(BOOL *)pvParam = beep_active;
581 break;
583 case SPI_SETBEEP: /* 2 */
584 spi_idx = SPI_SETBEEP_IDX;
585 if (SYSPARAMS_Save( SPI_SETBEEP_REGKEY, SPI_SETBEEP_VALNAME,
586 (uiParam ? "Yes" : "No"), fWinIni ))
588 beep_active = uiParam;
589 spi_loaded[spi_idx] = TRUE;
591 else
592 ret = FALSE;
593 break;
595 case SPI_GETMOUSE: /* 3 */
596 if (!pvParam) return FALSE;
598 spi_idx = SPI_SETMOUSE_IDX;
599 if (!spi_loaded[spi_idx])
601 char buf[10];
603 if (SYSPARAMS_Load( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME1,
604 buf, sizeof(buf) ))
605 mouse_threshold1 = atoi( buf );
606 if (SYSPARAMS_Load( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME2,
607 buf, sizeof(buf) ))
608 mouse_threshold2 = atoi( buf );
609 if (SYSPARAMS_Load( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME3,
610 buf, sizeof(buf) ))
611 mouse_speed = atoi( buf );
612 spi_loaded[spi_idx] = TRUE;
614 ((INT *)pvParam)[0] = mouse_threshold1;
615 ((INT *)pvParam)[1] = mouse_threshold2;
616 ((INT *)pvParam)[2] = mouse_speed;
617 break;
619 case SPI_SETMOUSE: /* 4 */
621 char buf[10];
623 if (!pvParam) return FALSE;
625 spi_idx = SPI_SETMOUSE_IDX;
626 sprintf(buf, "%d", ((INT *)pvParam)[0]);
628 if (SYSPARAMS_Save( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME1,
629 buf, fWinIni ))
631 mouse_threshold1 = ((INT *)pvParam)[0];
632 spi_loaded[spi_idx] = TRUE;
634 sprintf(buf, "%d", ((INT *)pvParam)[1]);
635 SYSPARAMS_Save( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME2,
636 buf, fWinIni );
637 mouse_threshold2 = ((INT *)pvParam)[1];
639 sprintf(buf, "%d", ((INT *)pvParam)[2]);
640 SYSPARAMS_Save( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME3,
641 buf, fWinIni );
642 mouse_speed = ((INT *)pvParam)[2];
644 else
645 ret = FALSE;
646 break;
649 case SPI_GETBORDER: /* 5 */
650 if (!pvParam) return FALSE;
652 spi_idx = SPI_SETBORDER_IDX;
653 if (!spi_loaded[spi_idx])
655 char buf[10];
657 if (SYSPARAMS_Load( SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME, buf, sizeof(buf) ))
658 border = SYSPARAMS_Twips2Pixels( atoi(buf) );
660 spi_loaded[spi_idx] = TRUE;
661 if (TWEAK_WineLook > WIN31_LOOK)
663 SYSMETRICS_Set( SM_CXFRAME, border + GetSystemMetrics( SM_CXDLGFRAME ) );
664 SYSMETRICS_Set( SM_CYFRAME, border + GetSystemMetrics( SM_CXDLGFRAME ) );
667 *(INT *)pvParam = border;
668 break;
670 case SPI_SETBORDER: /* 6 */
672 char buf[10];
674 spi_idx = SPI_SETBORDER_IDX;
675 sprintf(buf, "%u", uiParam);
677 if (SYSPARAMS_Save( SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME,
678 buf, fWinIni ))
680 if (uiParam > 0)
682 border = uiParam;
683 spi_loaded[spi_idx] = TRUE;
684 if (TWEAK_WineLook > WIN31_LOOK)
686 SYSMETRICS_Set( SM_CXFRAME, uiParam + GetSystemMetrics( SM_CXDLGFRAME ) );
687 SYSMETRICS_Set( SM_CYFRAME, uiParam + GetSystemMetrics( SM_CXDLGFRAME ) );
691 else
692 ret = FALSE;
693 break;
696 case SPI_GETKEYBOARDSPEED: /* 10 */
697 if (!pvParam) return FALSE;
699 spi_idx = SPI_SETKEYBOARDSPEED_IDX;
700 if (!spi_loaded[spi_idx])
702 char buf[10];
704 if (SYSPARAMS_Load( SPI_SETKEYBOARDSPEED_REGKEY,
705 SPI_SETKEYBOARDSPEED_VALNAME,
706 buf, sizeof(buf) ))
707 keyboard_speed = atoi( buf );
708 spi_loaded[spi_idx] = TRUE;
710 *(INT *)pvParam = keyboard_speed;
711 break;
713 case SPI_SETKEYBOARDSPEED: /* 11 */
715 char buf[10];
717 spi_idx = SPI_SETKEYBOARDSPEED_IDX;
718 if (uiParam > 31)
719 uiParam = 31;
720 sprintf(buf, "%u", uiParam);
722 if (SYSPARAMS_Save( SPI_SETKEYBOARDSPEED_REGKEY,
723 SPI_SETKEYBOARDSPEED_VALNAME,
724 buf, fWinIni ))
726 keyboard_speed = uiParam;
727 spi_loaded[spi_idx] = TRUE;
729 else
730 ret = FALSE;
731 break;
734 /* not implemented in Windows */
735 WINE_SPI_WARN(SPI_LANGDRIVER); /* 12 */
737 case SPI_ICONHORIZONTALSPACING: /* 13 */
738 spi_idx = SPI_ICONHORIZONTALSPACING_IDX;
739 if (pvParam != NULL)
741 if (!spi_loaded[spi_idx])
743 char buf[10];
744 int val;
746 if (SYSPARAMS_Load( SPI_ICONHORIZONTALSPACING_REGKEY,
747 SPI_ICONHORIZONTALSPACING_VALNAME, buf, sizeof(buf) ))
749 val = SYSPARAMS_Twips2Pixels( atoi(buf) );
750 SYSMETRICS_Set( SM_CXICONSPACING, val );
752 spi_loaded[spi_idx] = TRUE;
755 *(INT *)pvParam = GetSystemMetrics( SM_CXICONSPACING );
757 else
759 char buf[10];
761 if (uiParam < 32) uiParam = 32;
763 sprintf(buf, "%u", uiParam);
764 if (SYSPARAMS_Save( SPI_ICONHORIZONTALSPACING_REGKEY,
765 SPI_ICONHORIZONTALSPACING_VALNAME,
766 buf, fWinIni ))
768 SYSMETRICS_Set( SM_CXICONSPACING, uiParam );
769 spi_loaded[spi_idx] = TRUE;
771 else
772 ret = FALSE;
774 break;
776 case SPI_GETSCREENSAVETIMEOUT: /* 14 */
777 if (!pvParam) return FALSE;
779 spi_idx = SPI_SETSCREENSAVETIMEOUT_IDX;
780 if (!spi_loaded[spi_idx])
782 char buf[10];
784 if (SYSPARAMS_Load( SPI_SETSCREENSAVETIMEOUT_REGKEY,
785 SPI_SETSCREENSAVETIMEOUT_VALNAME,
786 buf, sizeof(buf) ))
787 screensave_timeout = atoi( buf );
789 spi_loaded[spi_idx] = TRUE;
791 *(INT *)pvParam = screensave_timeout;
792 break;
794 case SPI_SETSCREENSAVETIMEOUT: /* 15 */
796 char buf[10];
798 spi_idx = SPI_SETSCREENSAVETIMEOUT_IDX;
799 sprintf(buf, "%u", uiParam);
801 if (SYSPARAMS_Save( SPI_SETSCREENSAVETIMEOUT_REGKEY,
802 SPI_SETSCREENSAVETIMEOUT_VALNAME,
803 buf, fWinIni ))
805 screensave_timeout = uiParam;
806 spi_loaded[spi_idx] = TRUE;
808 else
809 ret = FALSE;
810 break;
813 case SPI_GETSCREENSAVEACTIVE: /* 16 */
814 if (!pvParam) return FALSE;
815 *(BOOL *)pvParam = USER_Driver.pGetScreenSaveActive();
816 break;
818 case SPI_SETSCREENSAVEACTIVE: /* 17 */
820 char buf[5];
822 sprintf(buf, "%u", uiParam);
823 USER_Driver.pSetScreenSaveActive( uiParam );
824 /* saved value does not affect Wine */
825 SYSPARAMS_Save( SPI_SETSCREENSAVEACTIVE_REGKEY,
826 SPI_SETSCREENSAVEACTIVE_VALNAME,
827 buf, fWinIni );
828 break;
831 case SPI_GETGRIDGRANULARITY: /* 18 */
832 if (!pvParam) return FALSE;
834 spi_idx = SPI_SETGRIDGRANULARITY_IDX;
835 if (!spi_loaded[spi_idx])
837 char buf[10];
839 if (SYSPARAMS_Load( SPI_SETGRIDGRANULARITY_REGKEY,
840 SPI_SETGRIDGRANULARITY_VALNAME,
841 buf, sizeof(buf) ))
842 grid_granularity = atoi( buf );
844 spi_loaded[spi_idx] = TRUE;
846 *(INT *)pvParam = grid_granularity;
847 break;
849 case SPI_SETGRIDGRANULARITY: /* 19 */
851 char buf[10];
853 spi_idx = SPI_SETGRIDGRANULARITY_IDX;
854 sprintf(buf, "%u", uiParam);
856 if (SYSPARAMS_Save( SPI_SETGRIDGRANULARITY_REGKEY,
857 SPI_SETGRIDGRANULARITY_VALNAME,
858 buf, fWinIni ))
860 grid_granularity = uiParam;
861 spi_loaded[spi_idx] = TRUE;
863 else
864 ret = FALSE;
865 break;
868 case SPI_SETDESKWALLPAPER: /* 20 */
869 if (!pvParam || !SetDeskWallPaper( (LPSTR)pvParam )) return FALSE;
870 SYSPARAMS_Save(SPI_SETDESKWALLPAPER_REGKEY, SPI_SETDESKWALLPAPER_VALNAME, pvParam, fWinIni);
871 break;
872 case SPI_SETDESKPATTERN: /* 21 */
873 /* FIXME: the ability to specify a pattern in pvParam
874 doesn't seem to be documented for Win32 */
875 if ((INT16)uiParam == -1)
877 char buffer[256];
878 GetProfileStringA( "Desktop", "Pattern",
879 "170 85 170 85 170 85 170 85",
880 buffer, sizeof(buffer) );
881 ret = DESKTOP_SetPattern( (LPSTR)buffer );
882 } else
883 ret = DESKTOP_SetPattern( (LPSTR)pvParam );
884 break;
886 case SPI_GETKEYBOARDDELAY: /* 22 */
887 if (!pvParam) return FALSE;
889 spi_idx = SPI_SETKEYBOARDDELAY_IDX;
890 if (!spi_loaded[spi_idx])
892 char buf[10];
894 if (SYSPARAMS_Load( SPI_SETKEYBOARDDELAY_REGKEY,
895 SPI_SETKEYBOARDDELAY_VALNAME,
896 buf, sizeof(buf) ))
898 int i = atoi( buf );
899 if ( (i >= 0) && (i <= 3)) keyboard_delay = i;
902 spi_loaded[spi_idx] = TRUE;
904 *(INT *)pvParam = keyboard_delay;
905 break;
907 case SPI_SETKEYBOARDDELAY: /* 23 */
909 char buf[10];
911 spi_idx = SPI_SETKEYBOARDDELAY_IDX;
912 sprintf(buf, "%u", uiParam);
914 if (SYSPARAMS_Save( SPI_SETKEYBOARDDELAY_REGKEY,
915 SPI_SETKEYBOARDDELAY_VALNAME,
916 buf, fWinIni ))
918 if (uiParam <= 3)
919 keyboard_delay = uiParam;
920 spi_loaded[spi_idx] = TRUE;
922 else
923 ret = FALSE;
924 break;
927 case SPI_ICONVERTICALSPACING: /* 24 */
928 spi_idx = SPI_ICONVERTICALSPACING_IDX;
929 if (pvParam != NULL)
931 if (!spi_loaded[spi_idx])
933 char buf[10];
934 int val;
936 if (SYSPARAMS_Load( SPI_ICONVERTICALSPACING_REGKEY,
937 SPI_ICONVERTICALSPACING_VALNAME, buf, sizeof(buf) ))
939 val = SYSPARAMS_Twips2Pixels( atoi(buf) );
940 SYSMETRICS_Set( SM_CYICONSPACING, val );
942 spi_loaded[spi_idx] = TRUE;
945 *(INT *)pvParam = GetSystemMetrics( SM_CYICONSPACING );
947 else
949 char buf[10];
951 if (uiParam < 32) uiParam = 32;
953 sprintf(buf, "%u", uiParam);
954 if (SYSPARAMS_Save( SPI_ICONVERTICALSPACING_REGKEY,
955 SPI_ICONVERTICALSPACING_VALNAME,
956 buf, fWinIni ))
958 SYSMETRICS_Set( SM_CYICONSPACING, uiParam );
959 spi_loaded[spi_idx] = TRUE;
961 else
962 ret = FALSE;
965 break;
967 case SPI_GETICONTITLEWRAP: /* 25 */
968 if (!pvParam) return FALSE;
970 spi_idx = SPI_SETICONTITLEWRAP_IDX;
971 if (!spi_loaded[spi_idx])
973 char buf[5];
975 if (SYSPARAMS_Load( SPI_SETICONTITLEWRAP_REGKEY1,
976 SPI_SETICONTITLEWRAP_VALNAME, buf, sizeof(buf) ))
977 icon_title_wrap = atoi(buf);
978 spi_loaded[spi_idx] = TRUE;
981 *(BOOL *)pvParam = icon_title_wrap;
982 break;
984 case SPI_SETICONTITLEWRAP: /* 26 */
986 char buf[5];
988 spi_idx = SPI_SETICONTITLEWRAP_IDX;
989 sprintf(buf, "%u", uiParam);
990 if (SYSPARAMS_Save( SPI_SETICONTITLEWRAP_REGKEY1,
991 SPI_SETICONTITLEWRAP_VALNAME,
992 buf, fWinIni ))
994 SYSPARAMS_Save( SPI_SETICONTITLEWRAP_REGKEY2,
995 SPI_SETICONTITLEWRAP_VALNAME,
996 buf, fWinIni );
997 icon_title_wrap = uiParam;
998 spi_loaded[spi_idx] = TRUE;
1000 else
1001 ret = FALSE;
1002 break;
1005 case SPI_GETMENUDROPALIGNMENT: /* 27 */
1006 if (!pvParam) return FALSE;
1008 spi_idx = SPI_SETMENUDROPALIGNMENT_IDX;
1010 if (!spi_loaded[spi_idx])
1012 char buf[5];
1014 if (SYSPARAMS_Load( SPI_SETMENUDROPALIGNMENT_REGKEY1,
1015 SPI_SETMENUDROPALIGNMENT_VALNAME, buf, sizeof(buf) ))
1017 SYSMETRICS_Set( SM_MENUDROPALIGNMENT, atoi( buf ) );
1019 spi_loaded[spi_idx] = TRUE;
1022 *(BOOL *)pvParam = GetSystemMetrics( SM_MENUDROPALIGNMENT );
1023 break;
1025 case SPI_SETMENUDROPALIGNMENT: /* 28 */
1027 char buf[5];
1028 spi_idx = SPI_SETMENUDROPALIGNMENT_IDX;
1030 sprintf(buf, "%u", uiParam);
1031 if (SYSPARAMS_Save( SPI_SETMENUDROPALIGNMENT_REGKEY1,
1032 SPI_SETMENUDROPALIGNMENT_VALNAME,
1033 buf, fWinIni ))
1035 SYSPARAMS_Save( SPI_SETMENUDROPALIGNMENT_REGKEY2,
1036 SPI_SETMENUDROPALIGNMENT_VALNAME,
1037 buf, fWinIni );
1038 SYSMETRICS_Set( SM_MENUDROPALIGNMENT, uiParam );
1039 spi_loaded[spi_idx] = TRUE;
1041 else
1042 ret = FALSE;
1043 break;
1046 case SPI_SETDOUBLECLKWIDTH: /* 29 */
1048 char buf[10];
1049 spi_idx = SPI_SETDOUBLECLKWIDTH_IDX;
1051 sprintf(buf, "%u", uiParam);
1052 if (SYSPARAMS_Save( SPI_SETDOUBLECLKWIDTH_REGKEY1,
1053 SPI_SETDOUBLECLKWIDTH_VALNAME,
1054 buf, fWinIni ))
1056 SYSPARAMS_Save( SPI_SETDOUBLECLKWIDTH_REGKEY2,
1057 SPI_SETDOUBLECLKWIDTH_VALNAME,
1058 buf, fWinIni );
1059 SYSMETRICS_Set( SM_CXDOUBLECLK, uiParam );
1060 spi_loaded[spi_idx] = TRUE;
1062 else
1063 ret = FALSE;
1064 break;
1067 case SPI_SETDOUBLECLKHEIGHT: /* 30 */
1069 char buf[10];
1070 spi_idx = SPI_SETDOUBLECLKHEIGHT_IDX;
1072 sprintf(buf, "%u", uiParam);
1073 if (SYSPARAMS_Save( SPI_SETDOUBLECLKHEIGHT_REGKEY1,
1074 SPI_SETDOUBLECLKHEIGHT_VALNAME,
1075 buf, fWinIni ))
1077 SYSPARAMS_Save( SPI_SETDOUBLECLKHEIGHT_REGKEY2,
1078 SPI_SETDOUBLECLKHEIGHT_VALNAME,
1079 buf, fWinIni );
1080 SYSMETRICS_Set( SM_CYDOUBLECLK, uiParam );
1081 spi_loaded[spi_idx] = TRUE;
1083 else
1084 ret = FALSE;
1085 break;
1088 case SPI_GETICONTITLELOGFONT: /* 31 */
1090 LPLOGFONTA lpLogFont = (LPLOGFONTA)pvParam;
1091 LOGFONTA lfDefault;
1093 if (!pvParam) return FALSE;
1096 * The 'default GDI fonts' seems to be returned.
1097 * If a returned font is not a correct font in your environment,
1098 * please try to fix objects/gdiobj.c at first.
1100 SYSPARAMS_GetGUIFont( &lfDefault );
1102 GetProfileStringA( "Desktop", "IconTitleFaceName",
1103 lfDefault.lfFaceName,
1104 lpLogFont->lfFaceName, LF_FACESIZE );
1105 lpLogFont->lfHeight = -GetProfileIntA( "Desktop", "IconTitleSize", 11 );
1106 lpLogFont->lfWidth = 0;
1107 lpLogFont->lfEscapement = lpLogFont->lfOrientation = 0;
1108 lpLogFont->lfWeight = FW_NORMAL;
1109 lpLogFont->lfItalic = FALSE;
1110 lpLogFont->lfStrikeOut = FALSE;
1111 lpLogFont->lfUnderline = FALSE;
1112 lpLogFont->lfCharSet = lfDefault.lfCharSet; /* at least 'charset' should not be hard-coded */
1113 lpLogFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
1114 lpLogFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
1115 lpLogFont->lfPitchAndFamily = DEFAULT_PITCH;
1116 lpLogFont->lfQuality = DEFAULT_QUALITY;
1117 break;
1120 case SPI_SETDOUBLECLICKTIME: /* 32 */
1122 char buf[10];
1124 spi_idx = SPI_SETDOUBLECLICKTIME_IDX;
1125 sprintf(buf, "%u", uiParam);
1127 if (SYSPARAMS_Save( SPI_SETDOUBLECLICKTIME_REGKEY,
1128 SPI_SETDOUBLECLICKTIME_VALNAME,
1129 buf, fWinIni ))
1131 if (!uiParam)
1132 uiParam = 500;
1133 double_click_time = uiParam;
1134 spi_loaded[spi_idx] = TRUE;
1136 else
1137 ret = FALSE;
1138 break;
1141 case SPI_SETMOUSEBUTTONSWAP: /* 33 */
1143 char buf[5];
1144 spi_idx = SPI_SETMOUSEBUTTONSWAP_IDX;
1146 sprintf(buf, "%u", uiParam);
1147 if (SYSPARAMS_Save( SPI_SETMOUSEBUTTONSWAP_REGKEY,
1148 SPI_SETMOUSEBUTTONSWAP_VALNAME,
1149 buf, fWinIni ))
1151 SYSMETRICS_Set( SM_SWAPBUTTON, uiParam );
1152 spi_loaded[spi_idx] = TRUE;
1154 else
1155 ret = FALSE;
1156 break;
1159 WINE_SPI_FIXME(SPI_SETICONTITLELOGFONT); /* 34 */
1161 case SPI_GETFASTTASKSWITCH: /* 35 */
1162 if (!pvParam) return FALSE;
1163 *(BOOL *)pvParam = 1;
1164 break;
1166 case SPI_SETFASTTASKSWITCH: /* 36 */
1167 /* the action is disabled */
1168 ret = FALSE;
1169 break;
1171 case SPI_SETDRAGFULLWINDOWS: /* 37 WINVER >= 0x0400 */
1173 char buf[5];
1175 spi_idx = SPI_SETDRAGFULLWINDOWS_IDX;
1176 sprintf(buf, "%u", uiParam);
1177 if (SYSPARAMS_Save( SPI_SETDRAGFULLWINDOWS_REGKEY,
1178 SPI_SETDRAGFULLWINDOWS_VALNAME,
1179 buf, fWinIni ))
1181 drag_full_windows = uiParam;
1182 spi_loaded[spi_idx] = TRUE;
1184 else
1185 ret = FALSE;
1186 break;
1189 case SPI_GETDRAGFULLWINDOWS: /* 38 WINVER >= 0x0400 */
1190 if (!pvParam) return FALSE;
1192 spi_idx = SPI_SETDRAGFULLWINDOWS_IDX;
1193 if (!spi_loaded[spi_idx])
1195 char buf[5];
1197 if (SYSPARAMS_Load( SPI_SETDRAGFULLWINDOWS_REGKEY,
1198 SPI_SETDRAGFULLWINDOWS_VALNAME, buf, sizeof(buf) ))
1199 drag_full_windows = atoi(buf);
1200 spi_loaded[spi_idx] = TRUE;
1203 *(BOOL *)pvParam = drag_full_windows;
1204 break;
1206 case SPI_GETNONCLIENTMETRICS: /* 41 WINVER >= 0x400 */
1208 LPNONCLIENTMETRICSA lpnm = (LPNONCLIENTMETRICSA)pvParam;
1210 if (!pvParam) return FALSE;
1212 if (lpnm->cbSize == sizeof(NONCLIENTMETRICSA))
1214 /* clear the struct, so we have 'sane' members */
1215 memset(
1216 (char *)pvParam + sizeof(lpnm->cbSize),
1218 lpnm->cbSize - sizeof(lpnm->cbSize)
1221 /* initialize geometry entries */
1222 lpnm->iBorderWidth = 1;
1223 lpnm->iScrollWidth = GetSystemMetrics(SM_CXVSCROLL);
1224 lpnm->iScrollHeight = GetSystemMetrics(SM_CYHSCROLL);
1226 /* size of the normal caption buttons */
1227 lpnm->iCaptionWidth = GetSystemMetrics(SM_CXSIZE);
1228 lpnm->iCaptionHeight = GetSystemMetrics(SM_CYSIZE);
1230 /* caption font metrics */
1231 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0, (LPVOID)&(lpnm->lfCaptionFont), 0 );
1232 lpnm->lfCaptionFont.lfWeight = FW_BOLD;
1234 /* size of the small caption buttons */
1235 lpnm->iSmCaptionWidth = GetSystemMetrics(SM_CXSMSIZE);
1236 lpnm->iSmCaptionHeight = GetSystemMetrics(SM_CYSMSIZE);
1238 /* small caption font metrics */
1239 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0, (LPVOID)&(lpnm->lfSmCaptionFont), 0 );
1241 /* menus, FIXME: names of wine.conf entries are bogus */
1243 /* size of the menu (MDI) buttons */
1244 lpnm->iMenuWidth = GetSystemMetrics(SM_CXMENUSIZE);
1245 lpnm->iMenuHeight = GetSystemMetrics(SM_CYMENUSIZE);
1247 /* menu font metrics */
1248 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0, (LPVOID)&(lpnm->lfMenuFont), 0 );
1249 GetProfileStringA( "Desktop", "MenuFont",
1250 (TWEAK_WineLook > WIN31_LOOK) ? lpnm->lfCaptionFont.lfFaceName : "System",
1251 lpnm->lfMenuFont.lfFaceName, LF_FACESIZE );
1252 lpnm->lfMenuFont.lfHeight = -GetProfileIntA( "Desktop", "MenuFontSize", 11 );
1253 lpnm->lfMenuFont.lfWeight = (TWEAK_WineLook > WIN31_LOOK) ? FW_NORMAL : FW_BOLD;
1255 /* status bar font metrics */
1256 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0,
1257 (LPVOID)&(lpnm->lfStatusFont), 0 );
1258 /* message font metrics */
1259 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0,
1260 (LPVOID)&(lpnm->lfMessageFont), 0 );
1262 else
1264 WARN("size mismatch !! (is %d; should be %d)\n", lpnm->cbSize, sizeof(NONCLIENTMETRICSA));
1265 /* FIXME: SetLastError? */
1266 ret = FALSE;
1268 break;
1270 WINE_SPI_FIXME(SPI_SETNONCLIENTMETRICS); /* 42 WINVER >= 0x400 */
1272 case SPI_GETMINIMIZEDMETRICS: /* 43 WINVER >= 0x400 */
1274 MINIMIZEDMETRICS * lpMm = pvParam;
1275 if (lpMm && lpMm->cbSize == sizeof(*lpMm))
1277 /* these taken from Win2k SP3 */
1278 lpMm->iWidth = 154;
1279 lpMm->iHorzGap = 0;
1280 lpMm->iVertGap = 0;
1281 lpMm->iArrange = 8;
1283 else
1284 ret = FALSE;
1285 break;
1287 WINE_SPI_FIXME(SPI_SETMINIMIZEDMETRICS); /* 44 WINVER >= 0x400 */
1289 case SPI_GETICONMETRICS: /* 45 WINVER >= 0x400 */
1291 LPICONMETRICSA lpIcon = pvParam;
1292 if(lpIcon && lpIcon->cbSize == sizeof(*lpIcon))
1294 SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0,
1295 &lpIcon->iHorzSpacing, FALSE );
1296 SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0,
1297 &lpIcon->iVertSpacing, FALSE );
1298 SystemParametersInfoA( SPI_GETICONTITLEWRAP, 0,
1299 &lpIcon->iTitleWrap, FALSE );
1300 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0,
1301 &lpIcon->lfFont, FALSE );
1303 else
1305 ret = FALSE;
1307 break;
1309 WINE_SPI_FIXME(SPI_SETICONMETRICS); /* 46 WINVER >= 0x400 */
1311 case SPI_SETWORKAREA: /* 47 WINVER >= 0x400 */
1313 char buf[20];
1314 RECT *pr = (RECT *) pvParam;
1316 if (!pvParam) return FALSE;
1318 spi_idx = SPI_SETWORKAREA_IDX;
1319 sprintf(buf, "%ld %ld %ld %ld",
1320 pr->left, pr->top,
1321 pr->right, pr->bottom );
1323 if (SYSPARAMS_Save( SPI_SETWORKAREA_REGKEY,
1324 SPI_SETWORKAREA_VALNAME,
1325 buf, fWinIni ))
1327 CopyRect( &work_area, (RECT *)pvParam );
1328 spi_loaded[spi_idx] = TRUE;
1330 else
1331 ret = FALSE;
1332 break;
1335 case SPI_GETWORKAREA: /* 48 WINVER >= 0x400 */
1336 if (!pvParam) return FALSE;
1338 spi_idx = SPI_SETWORKAREA_IDX;
1339 if (!spi_loaded[spi_idx])
1341 char buf[20];
1343 SetRect( &work_area, 0, 0,
1344 GetSystemMetrics( SM_CXSCREEN ),
1345 GetSystemMetrics( SM_CYSCREEN ) );
1347 if (SYSPARAMS_Load( SPI_SETWORKAREA_REGKEY,
1348 SPI_SETWORKAREA_VALNAME,
1349 buf, sizeof(buf) ))
1351 sscanf( buf, "%ld %ld %ld %ld",
1352 &work_area.left, &work_area.top,
1353 &work_area.right, &work_area.bottom );
1355 spi_loaded[spi_idx] = TRUE;
1357 CopyRect( (RECT *)pvParam, &work_area );
1359 break;
1361 WINE_SPI_FIXME(SPI_SETPENWINDOWS); /* 49 WINVER >= 0x400 */
1363 case SPI_GETFILTERKEYS: /* 50 */
1365 LPFILTERKEYS lpFilterKeys = (LPFILTERKEYS)pvParam;
1366 WARN("SPI_GETFILTERKEYS not fully implemented\n");
1367 if (lpFilterKeys && lpFilterKeys->cbSize == sizeof(FILTERKEYS))
1369 /* Indicate that no FilterKeys feature available */
1370 lpFilterKeys->dwFlags = 0;
1371 lpFilterKeys->iWaitMSec = 0;
1372 lpFilterKeys->iDelayMSec = 0;
1373 lpFilterKeys->iRepeatMSec = 0;
1374 lpFilterKeys->iBounceMSec = 0;
1376 else
1378 ret = FALSE;
1380 break;
1382 WINE_SPI_FIXME(SPI_SETFILTERKEYS); /* 51 */
1384 case SPI_GETTOGGLEKEYS: /* 52 */
1386 LPTOGGLEKEYS lpToggleKeys = (LPTOGGLEKEYS)pvParam;
1387 WARN("SPI_GETTOGGLEKEYS not fully implemented\n");
1388 if (lpToggleKeys && lpToggleKeys->cbSize == sizeof(TOGGLEKEYS))
1390 /* Indicate that no ToggleKeys feature available */
1391 lpToggleKeys->dwFlags = 0;
1393 else
1395 ret = FALSE;
1397 break;
1399 WINE_SPI_FIXME(SPI_SETTOGGLEKEYS); /* 53 */
1401 case SPI_GETMOUSEKEYS: /* 54 */
1403 LPMOUSEKEYS lpMouseKeys = (LPMOUSEKEYS)pvParam;
1404 WARN("SPI_GETMOUSEKEYS not fully implemented\n");
1405 if (lpMouseKeys && lpMouseKeys->cbSize == sizeof(MOUSEKEYS))
1407 /* Indicate that no MouseKeys feature available */
1408 lpMouseKeys->dwFlags = 0;
1409 lpMouseKeys->iMaxSpeed = 360;
1410 lpMouseKeys->iTimeToMaxSpeed = 1000;
1411 lpMouseKeys->iCtrlSpeed = 0;
1412 lpMouseKeys->dwReserved1 = 0;
1413 lpMouseKeys->dwReserved2 = 0;
1415 else
1417 ret = FALSE;
1419 break;
1421 WINE_SPI_FIXME(SPI_SETMOUSEKEYS); /* 55 */
1423 case SPI_GETSHOWSOUNDS: /* 56 */
1424 if (!pvParam) return FALSE;
1426 spi_idx = SPI_SETSHOWSOUNDS_IDX;
1428 if (!spi_loaded[spi_idx])
1430 char buf[10];
1432 if (SYSPARAMS_Load( SPI_SETSHOWSOUNDS_REGKEY,
1433 SPI_SETSHOWSOUNDS_VALNAME, buf, sizeof(buf) ))
1435 SYSMETRICS_Set( SM_SHOWSOUNDS, atoi( buf ) );
1437 spi_loaded[spi_idx] = TRUE;
1440 *(INT *)pvParam = GetSystemMetrics( SM_SHOWSOUNDS );
1441 break;
1443 case SPI_SETSHOWSOUNDS: /* 57 */
1445 char buf[10];
1446 spi_idx = SPI_SETSHOWSOUNDS_IDX;
1448 sprintf(buf, "%u", uiParam);
1449 if (SYSPARAMS_Save( SPI_SETSHOWSOUNDS_REGKEY,
1450 SPI_SETSHOWSOUNDS_VALNAME,
1451 buf, fWinIni ))
1453 SYSMETRICS_Set( SM_SHOWSOUNDS, uiParam );
1454 spi_loaded[spi_idx] = TRUE;
1456 else
1457 ret = FALSE;
1458 break;
1461 case SPI_GETSTICKYKEYS: /* 58 */
1463 LPSTICKYKEYS lpStickyKeys = (LPSTICKYKEYS)pvParam;
1464 WARN("SPI_GETSTICKYKEYS not fully implemented\n");
1465 if (lpStickyKeys && lpStickyKeys->cbSize == sizeof(STICKYKEYS))
1467 /* Indicate that no StickyKeys feature available */
1468 lpStickyKeys->dwFlags = 0;
1470 else
1472 ret = FALSE;
1474 break;
1476 WINE_SPI_FIXME(SPI_SETSTICKYKEYS); /* 59 */
1478 case SPI_GETACCESSTIMEOUT: /* 60 */
1480 LPACCESSTIMEOUT lpAccessTimeout = (LPACCESSTIMEOUT)pvParam;
1481 WARN("SPI_GETACCESSTIMEOUT not fully implemented\n");
1482 if (lpAccessTimeout && lpAccessTimeout->cbSize == sizeof(ACCESSTIMEOUT))
1484 /* Indicate that no accessibility features timeout is available */
1485 lpAccessTimeout->dwFlags = 0;
1486 lpAccessTimeout->iTimeOutMSec = 0;
1488 else
1490 ret = FALSE;
1492 break;
1494 WINE_SPI_FIXME(SPI_SETACCESSTIMEOUT); /* 61 */
1496 case SPI_GETSERIALKEYS: /* 62 WINVER >= 0x400 */
1498 LPSERIALKEYSA lpSerialKeysA = (LPSERIALKEYSA)pvParam;
1499 WARN("SPI_GETSERIALKEYS not fully implemented\n");
1500 if (lpSerialKeysA && lpSerialKeysA->cbSize == sizeof(SERIALKEYSA))
1502 /* Indicate that no SerialKeys feature available */
1503 lpSerialKeysA->dwFlags = 0;
1504 lpSerialKeysA->lpszActivePort = NULL;
1505 lpSerialKeysA->lpszPort = NULL;
1506 lpSerialKeysA->iBaudRate = 0;
1507 lpSerialKeysA->iPortState = 0;
1509 else
1511 ret = FALSE;
1513 break;
1515 WINE_SPI_FIXME(SPI_SETSERIALKEYS); /* 63 WINVER >= 0x400 */
1517 case SPI_GETSOUNDSENTRY: /* 64 */
1519 LPSOUNDSENTRYA lpSoundSentryA = (LPSOUNDSENTRYA)pvParam;
1520 WARN("SPI_GETSOUNDSENTRY not fully implemented\n");
1521 if (lpSoundSentryA && lpSoundSentryA->cbSize == sizeof(SOUNDSENTRYA))
1523 /* Indicate that no SoundSentry feature available */
1524 lpSoundSentryA->dwFlags = 0;
1525 lpSoundSentryA->iFSTextEffect = 0;
1526 lpSoundSentryA->iFSTextEffectMSec = 0;
1527 lpSoundSentryA->iFSTextEffectColorBits = 0;
1528 lpSoundSentryA->iFSGrafEffect = 0;
1529 lpSoundSentryA->iFSGrafEffectMSec = 0;
1530 lpSoundSentryA->iFSGrafEffectColor = 0;
1531 lpSoundSentryA->iWindowsEffect = 0;
1532 lpSoundSentryA->iWindowsEffectMSec = 0;
1533 lpSoundSentryA->lpszWindowsEffectDLL = 0;
1534 lpSoundSentryA->iWindowsEffectOrdinal = 0;
1536 else
1538 ret = FALSE;
1540 break;
1542 WINE_SPI_FIXME(SPI_SETSOUNDSENTRY); /* 65 */
1544 case SPI_GETHIGHCONTRAST: /* 66 WINVER >= 0x400 */
1546 LPHIGHCONTRASTA lpHighContrastA = (LPHIGHCONTRASTA)pvParam;
1547 WARN("SPI_GETHIGHCONTRAST not fully implemented\n");
1548 if (lpHighContrastA && lpHighContrastA->cbSize == sizeof(HIGHCONTRASTA))
1550 /* Indicate that no high contrast feature available */
1551 lpHighContrastA->dwFlags = 0;
1552 lpHighContrastA->lpszDefaultScheme = NULL;
1554 else
1556 ret = FALSE;
1558 break;
1560 WINE_SPI_FIXME(SPI_SETHIGHCONTRAST); /* 67 WINVER >= 0x400 */
1562 case SPI_GETKEYBOARDPREF: /* 68 WINVER >= 0x400 */
1563 if (!pvParam) return FALSE;
1565 spi_idx = SPI_SETKEYBOARDPREF_IDX;
1566 if (!spi_loaded[spi_idx])
1568 char buf[5];
1570 if (SYSPARAMS_Load( SPI_SETKEYBOARDPREF_REGKEY,
1571 SPI_SETKEYBOARDPREF_VALNAME, buf, sizeof(buf) ))
1572 keyboard_pref = atoi(buf);
1573 spi_loaded[spi_idx] = TRUE;
1576 *(BOOL *)pvParam = keyboard_pref;
1577 break;
1579 case SPI_SETKEYBOARDPREF: /* 69 WINVER >= 0x400 */
1581 char buf[5];
1583 spi_idx = SPI_SETKEYBOARDPREF_IDX;
1584 sprintf(buf, "%u", uiParam);
1585 if (SYSPARAMS_Save( SPI_SETKEYBOARDPREF_REGKEY,
1586 SPI_SETKEYBOARDPREF_VALNAME,
1587 buf, fWinIni ))
1589 keyboard_pref = uiParam;
1590 spi_loaded[spi_idx] = TRUE;
1592 else
1593 ret = FALSE;
1594 break;
1597 case SPI_GETSCREENREADER: /* 70 WINVER >= 0x400 */
1598 if (!pvParam) return FALSE;
1600 spi_idx = SPI_SETSCREENREADER_IDX;
1601 if (!spi_loaded[spi_idx])
1603 char buf[5];
1605 if (SYSPARAMS_Load( SPI_SETSCREENREADER_REGKEY,
1606 SPI_SETSCREENREADER_VALNAME, buf, sizeof(buf) ))
1607 screen_reader = atoi(buf);
1608 spi_loaded[spi_idx] = TRUE;
1611 *(BOOL *)pvParam = screen_reader;
1612 break;
1614 case SPI_SETSCREENREADER: /* 71 WINVER >= 0x400 */
1616 char buf[5];
1618 spi_idx = SPI_SETSCREENREADER_IDX;
1619 sprintf(buf, "%u", uiParam);
1620 if (SYSPARAMS_Save( SPI_SETSCREENREADER_REGKEY,
1621 SPI_SETSCREENREADER_VALNAME,
1622 buf, fWinIni ))
1624 screen_reader = uiParam;
1625 spi_loaded[spi_idx] = TRUE;
1627 else
1628 ret = FALSE;
1629 break;
1632 case SPI_GETANIMATION: /* 72 WINVER >= 0x400 */
1634 LPANIMATIONINFO lpAnimInfo = (LPANIMATIONINFO)pvParam;
1636 /* Tell it "disabled" */
1637 if (lpAnimInfo && lpAnimInfo->cbSize == sizeof(ANIMATIONINFO))
1638 lpAnimInfo->iMinAnimate = 0; /* Minimise and restore animation is disabled (nonzero == enabled) */
1639 else
1640 ret = FALSE;
1641 break;
1643 WINE_SPI_WARN(SPI_SETANIMATION); /* 73 WINVER >= 0x400 */
1645 WINE_SPI_FIXME(SPI_GETFONTSMOOTHING); /* 74 WINVER >= 0x400 */
1646 WINE_SPI_FIXME(SPI_SETFONTSMOOTHING); /* 75 WINVER >= 0x400 */
1648 WINE_SPI_FIXME(SPI_SETDRAGWIDTH); /* 76 WINVER >= 0x400 */
1649 WINE_SPI_FIXME(SPI_SETDRAGHEIGHT); /* 77 WINVER >= 0x400 */
1651 WINE_SPI_FIXME(SPI_SETHANDHELD); /* 78 WINVER >= 0x400 */
1653 WINE_SPI_FIXME(SPI_GETLOWPOWERTIMEOUT); /* 79 WINVER >= 0x400 */
1654 WINE_SPI_FIXME(SPI_GETPOWEROFFTIMEOUT); /* 80 WINVER >= 0x400 */
1655 WINE_SPI_FIXME(SPI_SETLOWPOWERTIMEOUT); /* 81 WINVER >= 0x400 */
1656 WINE_SPI_FIXME(SPI_SETPOWEROFFTIMEOUT); /* 82 WINVER >= 0x400 */
1657 WINE_SPI_FIXME(SPI_GETLOWPOWERACTIVE); /* 83 WINVER >= 0x400 */
1658 WINE_SPI_FIXME(SPI_GETPOWEROFFACTIVE); /* 84 WINVER >= 0x400 */
1659 WINE_SPI_FIXME(SPI_SETLOWPOWERACTIVE); /* 85 WINVER >= 0x400 */
1660 WINE_SPI_FIXME(SPI_SETPOWEROFFACTIVE); /* 86 WINVER >= 0x400 */
1662 WINE_SPI_FIXME(SPI_SETCURSORS); /* 87 WINVER >= 0x400 */
1663 WINE_SPI_FIXME(SPI_SETICONS); /* 88 WINVER >= 0x400 */
1665 case SPI_GETDEFAULTINPUTLANG: /* 89 WINVER >= 0x400 */
1666 ret = GetKeyboardLayout(0) ? TRUE : FALSE;
1667 break;
1669 WINE_SPI_FIXME(SPI_SETDEFAULTINPUTLANG); /* 90 WINVER >= 0x400 */
1671 WINE_SPI_FIXME(SPI_SETLANGTOGGLE); /* 91 WINVER >= 0x400 */
1673 case SPI_GETWINDOWSEXTENSION: /* 92 WINVER >= 0x400 */
1674 WARN("pretend no support for Win9x Plus! for now.\n");
1675 ret = FALSE; /* yes, this is the result value */
1676 break;
1678 WINE_SPI_FIXME(SPI_SETMOUSETRAILS); /* 93 WINVER >= 0x400 */
1679 WINE_SPI_FIXME(SPI_GETMOUSETRAILS); /* 94 WINVER >= 0x400 */
1681 case SPI_SETSCREENSAVERRUNNING: /* 97 WINVER >= 0x400 */
1683 /* SPI_SCREENSAVERRUNNING is an alias for SPI_SETSCREENSAVERRUNNING */
1684 char buf[5];
1686 spi_idx = SPI_SETSCREENSAVERRUNNING_IDX;
1687 sprintf(buf, "%u", uiParam);
1689 /* save only temporarily */
1690 if (SYSPARAMS_Save( SPI_SETSCREENSAVERRUNNING_REGKEY,
1691 SPI_SETSCREENSAVERRUNNING_VALNAME,
1692 buf, 0 ))
1694 screensaver_running = uiParam;
1695 spi_loaded[spi_idx] = TRUE;
1697 else
1698 ret = FALSE;
1699 break;
1702 case SPI_GETMOUSEHOVERWIDTH: /* 98 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1703 if (!pvParam) return FALSE;
1704 *(UINT *)pvParam = 4;
1705 break;
1706 WINE_SPI_FIXME(SPI_SETMOUSEHOVERWIDTH); /* 99 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1708 case SPI_GETMOUSEHOVERHEIGHT: /* 100 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1709 if (!pvParam) return FALSE;
1710 *(UINT *)pvParam = 4;
1711 break;
1712 WINE_SPI_FIXME(SPI_SETMOUSEHOVERHEIGHT); /* 101 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1714 case SPI_GETMOUSEHOVERTIME: /* 102 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1715 if (!pvParam) return FALSE;
1716 *(UINT *)pvParam = 400; /* default for menu dropdowns */
1717 break;
1718 WINE_SPI_FIXME(SPI_SETMOUSEHOVERTIME); /* 103 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1720 case SPI_GETWHEELSCROLLLINES: /* 104 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1721 if (!pvParam) return FALSE;
1722 *(UINT *)pvParam = 3; /* default for num scroll lines */
1723 break;
1725 WINE_SPI_FIXME(SPI_SETWHEELSCROLLLINES); /* 105 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1727 case SPI_GETMENUSHOWDELAY: /* 106 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1728 if (!pvParam) return FALSE;
1729 *(UINT *)pvParam = 400; /* Tested against Windows NT 4.0 and Windows 2000 */
1730 break;
1732 WINE_SPI_FIXME(SPI_GETSHOWIMEUI); /* 110 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1733 WINE_SPI_FIXME(SPI_SETSHOWIMEUI); /* 111 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1735 case SPI_GETSCREENSAVERRUNNING: /* 114 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1736 if (!pvParam) return FALSE;
1738 spi_idx = SPI_SETSCREENSAVERRUNNING_IDX;
1739 if (!spi_loaded[spi_idx])
1741 char buf[5];
1743 if (SYSPARAMS_Load( SPI_SETSCREENSAVERRUNNING_REGKEY,
1744 SPI_SETSCREENSAVERRUNNING_VALNAME, buf, sizeof(buf) ))
1745 screensaver_running = atoi( buf );
1746 spi_loaded[spi_idx] = TRUE;
1749 *(BOOL *)pvParam = screensaver_running;
1750 break;
1752 case SPI_GETDESKWALLPAPER: /* 115 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1754 char buf[MAX_PATH];
1756 if (!pvParam) return FALSE;
1758 if (uiParam > MAX_PATH)
1760 uiParam = MAX_PATH;
1763 if (SYSPARAMS_Load(SPI_SETDESKWALLPAPER_REGKEY, SPI_SETDESKWALLPAPER_VALNAME, buf, sizeof(buf)))
1765 strncpy((char*)pvParam, buf, uiParam);
1767 else
1769 /* Return an empty string */
1770 memset((char*)pvParam, 0, uiParam);
1773 break;
1776 WINE_SPI_FIXME(SPI_GETACTIVEWINDOWTRACKING);/* 0x1000 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1777 WINE_SPI_FIXME(SPI_SETACTIVEWINDOWTRACKING);/* 0x1001 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1778 WINE_SPI_FIXME(SPI_GETMENUANIMATION); /* 0x1002 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1779 WINE_SPI_FIXME(SPI_SETMENUANIMATION); /* 0x1003 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1780 WINE_SPI_FIXME(SPI_GETCOMBOBOXANIMATION); /* 0x1004 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1781 WINE_SPI_FIXME(SPI_SETCOMBOBOXANIMATION); /* 0x1005 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1782 WINE_SPI_FIXME(SPI_GETLISTBOXSMOOTHSCROLLING);/* 0x1006 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1783 WINE_SPI_FIXME(SPI_SETLISTBOXSMOOTHSCROLLING);/* 0x1007 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1785 case SPI_GETGRADIENTCAPTIONS: /* 0x1008 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1786 if (!pvParam) return FALSE;
1787 FIXME("case SPI_GETGRADIENTCAPTIONS always return false\n");
1788 *(BOOL *)pvParam = FALSE;
1789 break;
1791 WINE_SPI_FIXME(SPI_SETGRADIENTCAPTIONS); /* 0x1009 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1792 WINE_SPI_FIXME(SPI_GETKEYBOARDCUES); /* 0x100A _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1793 WINE_SPI_FIXME(SPI_SETKEYBOARDCUES); /* 0x100B _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1794 WINE_SPI_FIXME(SPI_GETACTIVEWNDTRKZORDER); /* 0x100C _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1795 WINE_SPI_FIXME(SPI_SETACTIVEWNDTRKZORDER); /* 0x100D _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1796 WINE_SPI_FIXME(SPI_GETHOTTRACKING); /* 0x100E _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1797 WINE_SPI_FIXME(SPI_SETHOTTRACKING); /* 0x100F _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1798 WINE_SPI_FIXME(SPI_GETSELECTIONFADE); /* 0x1014 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1799 WINE_SPI_FIXME(SPI_SETSELECTIONFADE); /* 0x1015 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1800 WINE_SPI_FIXME(SPI_GETDROPSHADOW); /* 0x1024 _WIN32_WINNT >= 0x510 */
1801 WINE_SPI_FIXME(SPI_SETDROPSHADOW); /* 0x1025 _WIN32_WINNT >= 0x510 */
1802 WINE_SPI_FIXME(SPI_GETFOREGROUNDLOCKTIMEOUT);/* 0x2000 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1803 WINE_SPI_FIXME(SPI_SETFOREGROUNDLOCKTIMEOUT);/* 0x2001 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1804 WINE_SPI_FIXME(SPI_GETACTIVEWNDTRKTIMEOUT); /* 0x2002 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1805 WINE_SPI_FIXME(SPI_SETACTIVEWNDTRKTIMEOUT); /* 0x2003 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1806 WINE_SPI_FIXME(SPI_GETFOREGROUNDFLASHCOUNT);/* 0x2004 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1807 WINE_SPI_FIXME(SPI_SETFOREGROUNDFLASHCOUNT);/* 0x2005 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1809 default:
1810 FIXME( "Unknown action: %u\n", uiAction );
1811 SetLastError( ERROR_INVALID_SPI_VALUE );
1812 ret = FALSE;
1813 break;
1816 if (ret)
1817 SYSPARAMS_NotifyChange( uiAction, fWinIni );
1818 return ret;
1820 #undef WINE_SPI_FIXME
1821 #undef WINE_SPI_WARN
1825 /***********************************************************************
1826 * SystemParametersInfo (USER.483)
1828 BOOL16 WINAPI SystemParametersInfo16( UINT16 uAction, UINT16 uParam,
1829 LPVOID lpvParam, UINT16 fuWinIni )
1831 BOOL16 ret;
1833 TRACE("(%u, %u, %p, %u)\n", uAction, uParam, lpvParam, fuWinIni);
1835 switch (uAction)
1837 case SPI_GETBEEP: /* 1 */
1838 case SPI_GETSCREENSAVEACTIVE: /* 16 */
1839 case SPI_GETICONTITLEWRAP: /* 25 */
1840 case SPI_GETMENUDROPALIGNMENT: /* 27 */
1841 case SPI_GETFASTTASKSWITCH: /* 35 */
1842 case SPI_GETDRAGFULLWINDOWS: /* 38 WINVER >= 0x0400 */
1844 BOOL tmp;
1845 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1846 if (ret && lpvParam)
1847 *(BOOL16 *)lpvParam = tmp;
1848 break;
1851 case SPI_GETBORDER: /* 5 */
1852 case SPI_ICONHORIZONTALSPACING: /* 13 */
1853 case SPI_GETSCREENSAVETIMEOUT: /* 14 */
1854 case SPI_GETGRIDGRANULARITY: /* 18 */
1855 case SPI_GETKEYBOARDDELAY: /* 22 */
1856 case SPI_ICONVERTICALSPACING: /* 24 */
1858 INT tmp;
1859 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1860 if (ret && lpvParam)
1861 *(INT16 *)lpvParam = tmp;
1862 break;
1865 case SPI_GETKEYBOARDSPEED: /* 10 */
1867 DWORD tmp;
1868 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1869 if (ret && lpvParam)
1870 *(WORD *)lpvParam = tmp;
1871 break;
1874 case SPI_GETICONTITLELOGFONT: /* 31 */
1876 LOGFONTA tmp;
1877 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1878 if (ret && lpvParam)
1879 SYSPARAMS_LogFont32ATo16( &tmp, (LPLOGFONT16)lpvParam );
1880 break;
1883 case SPI_GETNONCLIENTMETRICS: /* 41 WINVER >= 0x400 */
1885 NONCLIENTMETRICSA tmp;
1886 LPNONCLIENTMETRICS16 lpnm16 = (LPNONCLIENTMETRICS16)lpvParam;
1887 if (lpnm16 && lpnm16->cbSize == sizeof(NONCLIENTMETRICS16))
1889 tmp.cbSize = sizeof(NONCLIENTMETRICSA);
1890 ret = SystemParametersInfoA( uAction, uParam, &tmp, fuWinIni );
1891 if (ret)
1892 SYSPARAMS_NonClientMetrics32ATo16( &tmp, lpnm16 );
1894 else /* winfile 95 sets cbSize to 340 */
1895 ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
1896 break;
1899 case SPI_GETWORKAREA: /* 48 WINVER >= 0x400 */
1901 RECT tmp;
1902 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1903 if (ret && lpvParam)
1904 CONV_RECT32TO16( &tmp, (RECT16 *)lpvParam );
1905 break;
1908 case SPI_GETMOUSEHOVERWIDTH: /* 98 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1909 case SPI_GETMOUSEHOVERHEIGHT: /* 100 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1910 case SPI_GETMOUSEHOVERTIME: /* 102 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1912 UINT tmp;
1913 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1914 if (ret && lpvParam)
1915 *(UINT16 *)lpvParam = tmp;
1916 break;
1919 default:
1920 ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
1923 return ret;
1926 /***********************************************************************
1927 * SystemParametersInfoW (USER32.@)
1929 BOOL WINAPI SystemParametersInfoW( UINT uiAction, UINT uiParam,
1930 PVOID pvParam, UINT fuWinIni )
1932 BOOL ret;
1934 TRACE("(%u, %u, %p, %u)\n", uiAction, uiParam, pvParam, fuWinIni);
1936 switch (uiAction)
1938 case SPI_SETDESKWALLPAPER: /* 20 */
1939 case SPI_SETDESKPATTERN: /* 21 */
1941 char buffer[256];
1942 if (pvParam)
1943 if (!WideCharToMultiByte( CP_ACP, 0, (LPWSTR)pvParam, -1,
1944 buffer, sizeof(buffer), NULL, NULL ))
1945 buffer[sizeof(buffer)-1] = 0;
1946 ret = SystemParametersInfoA( uiAction, uiParam, pvParam ? buffer : NULL, fuWinIni );
1947 break;
1950 case SPI_GETICONTITLELOGFONT: /* 31 */
1952 LOGFONTA tmp;
1953 ret = SystemParametersInfoA( uiAction, uiParam, pvParam ? &tmp : NULL, fuWinIni );
1954 if (ret && pvParam)
1955 SYSPARAMS_LogFont32ATo32W( &tmp, (LPLOGFONTW)pvParam );
1956 break;
1959 case SPI_GETNONCLIENTMETRICS: /* 41 WINVER >= 0x400 */
1961 NONCLIENTMETRICSA tmp;
1962 LPNONCLIENTMETRICSW lpnmW = (LPNONCLIENTMETRICSW)pvParam;
1963 if (lpnmW && lpnmW->cbSize == sizeof(NONCLIENTMETRICSW))
1965 tmp.cbSize = sizeof(NONCLIENTMETRICSA);
1966 ret = SystemParametersInfoA( uiAction, uiParam, &tmp, fuWinIni );
1967 if (ret)
1968 SYSPARAMS_NonClientMetrics32ATo32W( &tmp, lpnmW );
1970 else
1971 ret = FALSE;
1972 break;
1975 case SPI_GETICONMETRICS: /* 45 WINVER >= 0x400 */
1977 ICONMETRICSA tmp;
1978 LPICONMETRICSW lpimW = (LPICONMETRICSW)pvParam;
1979 if (lpimW && lpimW->cbSize == sizeof(ICONMETRICSW))
1981 tmp.cbSize = sizeof(ICONMETRICSA);
1982 ret = SystemParametersInfoA( uiAction, uiParam, &tmp, fuWinIni );
1983 if (ret)
1985 lpimW->iHorzSpacing = tmp.iHorzSpacing;
1986 lpimW->iVertSpacing = tmp.iVertSpacing;
1987 lpimW->iTitleWrap = tmp.iTitleWrap;
1988 SYSPARAMS_LogFont32ATo32W( &tmp.lfFont, &lpimW->lfFont );
1991 else
1992 ret = FALSE;
1993 break;
1996 case SPI_GETHIGHCONTRAST: /* 66 WINVER >= 0x400 */
1998 HIGHCONTRASTA tmp;
1999 LPHIGHCONTRASTW lphcW = (LPHIGHCONTRASTW)pvParam;
2000 if (lphcW && lphcW->cbSize == sizeof(HIGHCONTRASTW))
2002 tmp.cbSize = sizeof(HIGHCONTRASTA);
2003 ret = SystemParametersInfoA( uiAction, uiParam, &tmp, fuWinIni );
2004 if (ret)
2006 lphcW->dwFlags = tmp.dwFlags;
2007 lphcW->lpszDefaultScheme = NULL; /* FIXME? */
2010 else
2011 ret = FALSE;
2012 break;
2015 default:
2016 ret = SystemParametersInfoA( uiAction, uiParam, pvParam, fuWinIni );
2017 break;
2019 return ret;
2023 /**********************************************************************
2024 * SetDoubleClickTime (USER32.@)
2026 BOOL WINAPI SetDoubleClickTime( UINT interval )
2028 return SystemParametersInfoA(SPI_SETDOUBLECLICKTIME, interval, 0, 0);
2032 /**********************************************************************
2033 * GetDoubleClickTime (USER32.@)
2035 UINT WINAPI GetDoubleClickTime(void)
2037 char buf[10];
2039 if (!spi_loaded[SPI_SETDOUBLECLICKTIME_IDX])
2041 if (SYSPARAMS_Load( SPI_SETDOUBLECLICKTIME_REGKEY,
2042 SPI_SETDOUBLECLICKTIME_VALNAME,
2043 buf, sizeof(buf) ))
2045 double_click_time = atoi( buf );
2046 if (!double_click_time) double_click_time = 500;
2048 spi_loaded[SPI_SETDOUBLECLICKTIME_IDX] = TRUE;
2050 return double_click_time;