Set DirectX version to 8.1.
[wine/dibdrv.git] / windows / sysparams.c
blobd1397be4acc722f40e641871358b84483a5346ce
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"
37 #include "sysmetrics.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"
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"
93 #define SPI_ICONVERTICALSPACING_VALNAME "IconVerticalSpacing"
94 #define SPI_SETICONTITLEWRAP_REGKEY "Control Panel\\Desktop"
95 #define SPI_SETICONTITLEWRAP_VALNAME "IconTitleWrap"
96 #define SPI_SETMENUDROPALIGNMENT_REGKEY "Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows"
97 #define SPI_SETMENUDROPALIGNMENT_VALNAME "MenuDropAlignment"
98 #define SPI_SETDOUBLECLKWIDTH_REGKEY "Control Panel\\Mouse"
99 #define SPI_SETDOUBLECLKWIDTH_VALNAME "DoubleClickWidth"
100 #define SPI_SETDOUBLECLKHEIGHT_REGKEY "Control Panel\\Mouse"
101 #define SPI_SETDOUBLECLKHEIGHT_VALNAME "DoubleClickHeight"
102 #define SPI_SETDOUBLECLICKTIME_REGKEY "Control Panel\\Mouse"
103 #define SPI_SETDOUBLECLICKTIME_VALNAME "DoubleClickSpeed"
104 #define SPI_SETMOUSEBUTTONSWAP_REGKEY "Control Panel\\Mouse"
105 #define SPI_SETMOUSEBUTTONSWAP_VALNAME "SwapMouseButtons"
106 #define SPI_SETDRAGFULLWINDOWS_REGKEY "Control Panel\\Desktop"
107 #define SPI_SETDRAGFULLWINDOWS_VALNAME "DragFullWindows"
108 #define SPI_SETWORKAREA_REGKEY "Control Panel\\Desktop"
109 #define SPI_SETWORKAREA_VALNAME "WINE_WorkArea"
110 #define SPI_SETSHOWSOUNDS_REGKEY "Control Panel\\Accessibility\\ShowSounds"
111 #define SPI_SETSHOWSOUNDS_VALNAME "On"
112 #define SPI_SETDESKWALLPAPER_REGKEY "Control Panel\\Desktop"
113 #define SPI_SETDESKWALLPAPER_VALNAME "Wallpaper"
114 /* FIXME - real values */
115 #define SPI_SETKEYBOARDPREF_REGKEY "Control Panel\\Desktop"
116 #define SPI_SETKEYBOARDPREF_VALNAME "WINE_KeyboardPref"
117 #define SPI_SETSCREENREADER_REGKEY "Control Panel\\Desktop"
118 #define SPI_SETSCREENREADER_VALNAME "WINE_ScreenReader"
119 #define SPI_SETSCREENSAVERRUNNING_REGKEY "Control Panel\\Desktop"
120 #define SPI_SETSCREENSAVERRUNNING_VALNAME "WINE_ScreenSaverRunning"
122 /* volatile registry branch under CURRENT_USER_REGKEY for temporary values storage */
123 #define WINE_CURRENT_USER_REGKEY "Wine"
125 /* Indicators whether system parameter value is loaded */
126 static char spi_loaded[SPI_WINE_IDX + 1];
128 static BOOL notify_change = TRUE;
130 /* System parameters storage */
131 static BOOL beep_active = TRUE;
132 static int mouse_threshold1 = 6;
133 static int mouse_threshold2 = 10;
134 static int mouse_speed = 1;
135 static int border = 1;
136 static int keyboard_speed = 31;
137 static int screensave_timeout = 300;
138 static int grid_granularity = 0;
139 static int keyboard_delay = 1;
140 static BOOL icon_title_wrap = TRUE;
141 static int double_click_time = 500;
142 static BOOL drag_full_windows = FALSE;
143 static RECT work_area;
144 static BOOL keyboard_pref = TRUE;
145 static BOOL screen_reader = FALSE;
146 static BOOL screensaver_running = FALSE;
148 /***********************************************************************
149 * GetTimerResolution (USER.14)
151 LONG WINAPI GetTimerResolution16(void)
153 return (1000);
156 /***********************************************************************
157 * ControlPanelInfo (USER.273)
159 void WINAPI ControlPanelInfo16( INT16 nInfoType, WORD wData, LPSTR lpBuffer )
161 FIXME("(%d, %04x, %p): stub.\n", nInfoType, wData, lpBuffer);
164 /* This function is a copy of the one in objects/font.c */
165 static void SYSPARAMS_LogFont32ATo16( const LOGFONTA* font32, LPLOGFONT16 font16 )
167 font16->lfHeight = font32->lfHeight;
168 font16->lfWidth = font32->lfWidth;
169 font16->lfEscapement = font32->lfEscapement;
170 font16->lfOrientation = font32->lfOrientation;
171 font16->lfWeight = font32->lfWeight;
172 font16->lfItalic = font32->lfItalic;
173 font16->lfUnderline = font32->lfUnderline;
174 font16->lfStrikeOut = font32->lfStrikeOut;
175 font16->lfCharSet = font32->lfCharSet;
176 font16->lfOutPrecision = font32->lfOutPrecision;
177 font16->lfClipPrecision = font32->lfClipPrecision;
178 font16->lfQuality = font32->lfQuality;
179 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
180 lstrcpynA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
183 static void SYSPARAMS_LogFont32ATo32W( const LOGFONTA* font32A, LPLOGFONTW font32W )
185 font32W->lfHeight = font32A->lfHeight;
186 font32W->lfWidth = font32A->lfWidth;
187 font32W->lfEscapement = font32A->lfEscapement;
188 font32W->lfOrientation = font32A->lfOrientation;
189 font32W->lfWeight = font32A->lfWeight;
190 font32W->lfItalic = font32A->lfItalic;
191 font32W->lfUnderline = font32A->lfUnderline;
192 font32W->lfStrikeOut = font32A->lfStrikeOut;
193 font32W->lfCharSet = font32A->lfCharSet;
194 font32W->lfOutPrecision = font32A->lfOutPrecision;
195 font32W->lfClipPrecision = font32A->lfClipPrecision;
196 font32W->lfQuality = font32A->lfQuality;
197 font32W->lfPitchAndFamily = font32A->lfPitchAndFamily;
198 MultiByteToWideChar( CP_ACP, 0, font32A->lfFaceName, -1, font32W->lfFaceName, LF_FACESIZE );
199 font32W->lfFaceName[LF_FACESIZE-1] = 0;
202 static void SYSPARAMS_NonClientMetrics32ATo16( const NONCLIENTMETRICSA* lpnm32, LPNONCLIENTMETRICS16 lpnm16 )
204 lpnm16->iBorderWidth = lpnm32->iBorderWidth;
205 lpnm16->iScrollWidth = lpnm32->iScrollWidth;
206 lpnm16->iScrollHeight = lpnm32->iScrollHeight;
207 lpnm16->iCaptionWidth = lpnm32->iCaptionWidth;
208 lpnm16->iCaptionHeight = lpnm32->iCaptionHeight;
209 SYSPARAMS_LogFont32ATo16( &lpnm32->lfCaptionFont, &lpnm16->lfCaptionFont );
210 lpnm16->iSmCaptionWidth = lpnm32->iSmCaptionWidth;
211 lpnm16->iSmCaptionHeight = lpnm32->iSmCaptionHeight;
212 SYSPARAMS_LogFont32ATo16( &lpnm32->lfSmCaptionFont, &lpnm16->lfSmCaptionFont );
213 lpnm16->iMenuWidth = lpnm32->iMenuWidth;
214 lpnm16->iMenuHeight = lpnm32->iMenuHeight;
215 SYSPARAMS_LogFont32ATo16( &lpnm32->lfMenuFont, &lpnm16->lfMenuFont );
216 SYSPARAMS_LogFont32ATo16( &lpnm32->lfStatusFont, &lpnm16->lfStatusFont );
217 SYSPARAMS_LogFont32ATo16( &lpnm32->lfMessageFont, &lpnm16->lfMessageFont );
220 static void SYSPARAMS_NonClientMetrics32ATo32W( const NONCLIENTMETRICSA* lpnm32A, LPNONCLIENTMETRICSW lpnm32W )
222 lpnm32W->iBorderWidth = lpnm32A->iBorderWidth;
223 lpnm32W->iScrollWidth = lpnm32A->iScrollWidth;
224 lpnm32W->iScrollHeight = lpnm32A->iScrollHeight;
225 lpnm32W->iCaptionWidth = lpnm32A->iCaptionWidth;
226 lpnm32W->iCaptionHeight = lpnm32A->iCaptionHeight;
227 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfCaptionFont, &lpnm32W->lfCaptionFont );
228 lpnm32W->iSmCaptionWidth = lpnm32A->iSmCaptionWidth;
229 lpnm32W->iSmCaptionHeight = lpnm32A->iSmCaptionHeight;
230 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfSmCaptionFont, &lpnm32W->lfSmCaptionFont );
231 lpnm32W->iMenuWidth = lpnm32A->iMenuWidth;
232 lpnm32W->iMenuHeight = lpnm32A->iMenuHeight;
233 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfMenuFont, &lpnm32W->lfMenuFont );
234 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfStatusFont, &lpnm32W->lfStatusFont );
235 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfMessageFont, &lpnm32W->lfMessageFont );
238 /***********************************************************************
239 * SYSPARAMS_Reset
241 * Sets the system parameter which should be always loaded to
242 * current value stored in registry.
243 * Invalidates lazy loaded parameter, so it will be loaded the next time
244 * it is requested.
246 * Parameters:
247 * uiAction - system parameter to reload value for.
248 * Note, only "SET" values can be used for this parameter.
249 * If uiAction is 0 all system parameters are reset.
251 void SYSPARAMS_Reset( UINT uiAction )
253 #define WINE_RELOAD_SPI(x) \
254 case x: \
255 spi_loaded[x##_IDX] = FALSE; \
256 SystemParametersInfoA( x, 0, dummy_buf, 0 );\
257 if (uiAction) \
258 break
260 #define WINE_IGNORE_SPI(x) \
261 case x: \
262 if (uiAction) \
263 break
265 #define WINE_INVALIDATE_SPI(x) \
266 case x: \
267 spi_loaded[x##_IDX] = FALSE; \
268 break
270 BOOL not_all_processed = TRUE;
271 char dummy_buf[10];
273 /* Execution falls through all the branches for uiAction == 0 */
274 switch (uiAction)
276 case 0:
277 memset( spi_loaded, 0, sizeof(spi_loaded) );
279 WINE_RELOAD_SPI(SPI_SETBORDER);
280 WINE_RELOAD_SPI(SPI_ICONHORIZONTALSPACING);
281 WINE_RELOAD_SPI(SPI_ICONVERTICALSPACING);
282 WINE_IGNORE_SPI(SPI_SETSCREENSAVEACTIVE);
283 WINE_RELOAD_SPI(SPI_SETDOUBLECLKWIDTH);
284 WINE_RELOAD_SPI(SPI_SETDOUBLECLKHEIGHT);
285 WINE_RELOAD_SPI(SPI_SETMOUSEBUTTONSWAP);
286 WINE_RELOAD_SPI(SPI_SETSHOWSOUNDS);
287 WINE_RELOAD_SPI(SPI_SETMENUDROPALIGNMENT);
289 default:
290 if (uiAction)
292 /* lazy loaded parameters */
293 switch (uiAction)
295 WINE_INVALIDATE_SPI(SPI_SETBEEP);
296 WINE_INVALIDATE_SPI(SPI_SETMOUSE);
297 WINE_INVALIDATE_SPI(SPI_SETKEYBOARDSPEED);
298 WINE_INVALIDATE_SPI(SPI_SETSCREENSAVETIMEOUT);
299 WINE_INVALIDATE_SPI(SPI_SETGRIDGRANULARITY);
300 WINE_INVALIDATE_SPI(SPI_SETKEYBOARDDELAY);
301 WINE_INVALIDATE_SPI(SPI_SETICONTITLEWRAP);
302 WINE_INVALIDATE_SPI(SPI_SETDOUBLECLICKTIME);
303 WINE_INVALIDATE_SPI(SPI_SETDRAGFULLWINDOWS);
304 WINE_INVALIDATE_SPI(SPI_SETWORKAREA);
305 WINE_INVALIDATE_SPI(SPI_SETKEYBOARDPREF);
306 WINE_INVALIDATE_SPI(SPI_SETSCREENREADER);
307 WINE_INVALIDATE_SPI(SPI_SETSCREENSAVERRUNNING);
308 default:
309 FIXME( "Unknown action reset: %u\n", uiAction );
310 break;
313 else
314 not_all_processed = FALSE;
315 break;
318 if (!uiAction && not_all_processed)
319 ERR( "Incorrect implementation of SYSPARAMS_Reset. "
320 "Not all params are reloaded.\n" );
321 #undef WINE_INVALIDATE_SPI
322 #undef WINE_IGNORE_SPI
323 #undef WINE_RELOAD_SPI
326 /***********************************************************************
327 * get_volatile_regkey
329 * Return a handle to the volatile registry key used to store
330 * non-permanently modified parameters.
332 static HKEY get_volatile_regkey(void)
334 static HKEY volatile_key;
336 if (!volatile_key)
338 if (RegCreateKeyExA( HKEY_CURRENT_USER, WINE_CURRENT_USER_REGKEY,
339 0, 0, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, 0,
340 &volatile_key, 0 ) != ERROR_SUCCESS)
341 ERR("Can't create wine configuration registry branch\n");
343 return volatile_key;
346 /***********************************************************************
347 * SYSPARAMS_NotifyChange
349 * Sends notification about system parameter update.
351 void SYSPARAMS_NotifyChange( UINT uiAction, UINT fWinIni )
353 if (notify_change)
355 if (fWinIni & SPIF_UPDATEINIFILE)
357 if (fWinIni & (SPIF_SENDWININICHANGE | SPIF_SENDCHANGE))
358 SendMessageA(HWND_BROADCAST, WM_SETTINGCHANGE,
359 uiAction, (LPARAM) "");
361 else
363 /* FIXME notify other wine processes with internal message */
369 /***********************************************************************
370 * Loads system parameter from user profile.
372 BOOL SYSPARAMS_Load( LPSTR lpRegKey, LPSTR lpValName, LPSTR lpBuf )
374 BOOL ret = FALSE;
375 DWORD type;
376 HKEY hKey;
377 DWORD count;
379 if ((RegOpenKeyA( get_volatile_regkey(), lpRegKey,
380 &hKey ) == ERROR_SUCCESS) ||
381 (RegOpenKeyA( HKEY_CURRENT_USER, lpRegKey,
382 &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_REGKEY,
443 SPI_SETDOUBLECLKWIDTH_VALNAME, 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_REGKEY,
452 SPI_SETDOUBLECLKHEIGHT_VALNAME, 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 ))
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 /***********************************************************************
511 * SystemParametersInfoA (USER32.@)
513 * Each system parameter has flag which shows whether the parameter
514 * is loaded or not. Parameters, stored directly in SysParametersInfo are
515 * loaded from registry only when they are requested and the flag is
516 * "false", after the loading the flag is set to "true". On interprocess
517 * notification of the parameter change the corresponding parameter flag is
518 * set to "false". The parameter value will be reloaded when it is requested
519 * the next time.
520 * Parameters, backed by or depend on GetSystemMetrics are processed
521 * differently. These parameters are always loaded. They are reloaded right
522 * away on interprocess change notification. We can't do lazy loading because
523 * we don't want to complicate GetSystemMetrics.
524 * Parameters, backed by X settings are read from corresponding setting.
525 * On the parameter change request the setting is changed. Interprocess change
526 * notifications are ignored.
527 * When parameter value is updated the changed value is stored in permanent
528 * registry branch if saving is requested. Otherwise it is stored
529 * in temporary branch
532 BOOL WINAPI SystemParametersInfoA( UINT uiAction, UINT uiParam,
533 PVOID pvParam, UINT fWinIni )
535 #define WINE_SPI_FIXME(x) \
536 case x: \
537 FIXME( "Unimplemented action: %u (%s)\n", x, #x ); \
538 SetLastError( ERROR_INVALID_SPI_VALUE ); \
539 ret = FALSE; \
540 break
541 #define WINE_SPI_WARN(x) \
542 case x: \
543 WARN( "Ignored action: %u (%s)\n", x, #x ); \
544 break
546 BOOL ret = TRUE;
547 unsigned spi_idx = 0;
549 TRACE("(%u, %u, %p, %u)\n", uiAction, uiParam, pvParam, fWinIni);
551 switch (uiAction)
553 case SPI_GETBEEP: /* 1 */
554 spi_idx = SPI_SETBEEP_IDX;
555 if (!spi_loaded[spi_idx])
557 char buf[5];
559 if (SYSPARAMS_Load( SPI_SETBEEP_REGKEY, SPI_SETBEEP_VALNAME, buf ))
560 beep_active = !strcasecmp( "Yes", buf );
561 spi_loaded[spi_idx] = TRUE;
564 *(BOOL *)pvParam = beep_active;
565 break;
567 case SPI_SETBEEP: /* 2 */
568 spi_idx = SPI_SETBEEP_IDX;
569 if (SYSPARAMS_Save( SPI_SETBEEP_REGKEY, SPI_SETBEEP_VALNAME,
570 (uiParam ? "Yes" : "No"), fWinIni ))
572 beep_active = uiParam;
573 spi_loaded[spi_idx] = TRUE;
575 else
576 ret = FALSE;
577 break;
579 case SPI_GETMOUSE: /* 3 */
580 spi_idx = SPI_SETMOUSE_IDX;
581 if (!spi_loaded[spi_idx])
583 char buf[10];
585 if (SYSPARAMS_Load( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME1,
586 buf ))
587 mouse_threshold1 = atoi( buf );
588 if (SYSPARAMS_Load( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME2,
589 buf ))
590 mouse_threshold2 = atoi( buf );
591 if (SYSPARAMS_Load( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME3,
592 buf ))
593 mouse_speed = atoi( buf );
594 spi_loaded[spi_idx] = TRUE;
596 ((INT *)pvParam)[0] = mouse_threshold1;
597 ((INT *)pvParam)[1] = mouse_threshold2;
598 ((INT *)pvParam)[2] = mouse_speed;
599 break;
601 case SPI_SETMOUSE: /* 4 */
603 char buf[10];
605 spi_idx = SPI_SETMOUSE_IDX;
606 sprintf(buf, "%d", ((INT *)pvParam)[0]);
608 if (SYSPARAMS_Save( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME1,
609 buf, fWinIni ))
611 mouse_threshold1 = ((INT *)pvParam)[0];
612 spi_loaded[spi_idx] = TRUE;
614 sprintf(buf, "%d", ((INT *)pvParam)[1]);
615 SYSPARAMS_Save( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME2,
616 buf, fWinIni );
617 mouse_threshold2 = ((INT *)pvParam)[1];
619 sprintf(buf, "%d", ((INT *)pvParam)[2]);
620 SYSPARAMS_Save( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME3,
621 buf, fWinIni );
622 mouse_speed = ((INT *)pvParam)[2];
624 else
625 ret = FALSE;
626 break;
629 case SPI_GETBORDER: /* 5 */
630 spi_idx = SPI_SETBORDER_IDX;
631 if (!spi_loaded[spi_idx])
633 char buf[10];
635 if (SYSPARAMS_Load( SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME,
636 buf ))
638 int i = atoi( buf );
639 if (i > 0) border = i;
641 spi_loaded[spi_idx] = TRUE;
642 if (TWEAK_WineLook > WIN31_LOOK)
644 SYSMETRICS_Set( SM_CXFRAME, border + GetSystemMetrics( SM_CXDLGFRAME ) );
645 SYSMETRICS_Set( SM_CYFRAME, border + GetSystemMetrics( SM_CXDLGFRAME ) );
648 *(INT *)pvParam = border;
649 break;
651 case SPI_SETBORDER: /* 6 */
653 char buf[10];
655 spi_idx = SPI_SETBORDER_IDX;
656 sprintf(buf, "%u", uiParam);
658 if (SYSPARAMS_Save( SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME,
659 buf, fWinIni ))
661 if (uiParam > 0)
663 border = uiParam;
664 spi_loaded[spi_idx] = TRUE;
665 if (TWEAK_WineLook > WIN31_LOOK)
667 SYSMETRICS_Set( SM_CXFRAME, uiParam + GetSystemMetrics( SM_CXDLGFRAME ) );
668 SYSMETRICS_Set( SM_CYFRAME, uiParam + GetSystemMetrics( SM_CXDLGFRAME ) );
672 else
673 ret = FALSE;
674 break;
677 case SPI_GETKEYBOARDSPEED: /* 10 */
678 spi_idx = SPI_SETKEYBOARDSPEED_IDX;
679 if (!spi_loaded[spi_idx])
681 char buf[10];
683 if (SYSPARAMS_Load( SPI_SETKEYBOARDSPEED_REGKEY,
684 SPI_SETKEYBOARDSPEED_VALNAME,
685 buf ))
686 keyboard_speed = atoi( buf );
687 spi_loaded[spi_idx] = TRUE;
689 *(INT *)pvParam = keyboard_speed;
690 break;
692 case SPI_SETKEYBOARDSPEED: /* 11 */
694 char buf[10];
696 spi_idx = SPI_SETKEYBOARDSPEED_IDX;
697 if (uiParam > 31)
698 uiParam = 31;
699 sprintf(buf, "%u", uiParam);
701 if (SYSPARAMS_Save( SPI_SETKEYBOARDSPEED_REGKEY,
702 SPI_SETKEYBOARDSPEED_VALNAME,
703 buf, fWinIni ))
705 keyboard_speed = uiParam;
706 spi_loaded[spi_idx] = TRUE;
708 else
709 ret = FALSE;
710 break;
713 /* not implemented in Windows */
714 WINE_SPI_WARN(SPI_LANGDRIVER); /* 12 */
716 case SPI_ICONHORIZONTALSPACING: /* 13 */
717 spi_idx = SPI_ICONHORIZONTALSPACING_IDX;
718 if (pvParam != NULL)
720 if (!spi_loaded[spi_idx])
722 char buf[10];
724 if (SYSPARAMS_Load( SPI_ICONHORIZONTALSPACING_REGKEY,
725 SPI_ICONHORIZONTALSPACING_VALNAME, buf ))
727 SYSMETRICS_Set( SM_CXICONSPACING, atoi( buf ) );
729 spi_loaded[spi_idx] = TRUE;
732 *(INT *)pvParam = GetSystemMetrics( SM_CXICONSPACING );
734 else
736 char buf[10];
738 if (uiParam < 32) uiParam = 32;
740 sprintf(buf, "%u", uiParam);
741 if (SYSPARAMS_Save( SPI_ICONHORIZONTALSPACING_REGKEY,
742 SPI_ICONHORIZONTALSPACING_VALNAME,
743 buf, fWinIni ))
745 SYSMETRICS_Set( SM_CXICONSPACING, uiParam );
746 spi_loaded[spi_idx] = TRUE;
748 else
749 ret = FALSE;
751 break;
753 case SPI_GETSCREENSAVETIMEOUT: /* 14 */
754 spi_idx = SPI_SETSCREENSAVETIMEOUT_IDX;
755 if (!spi_loaded[spi_idx])
757 char buf[10];
759 if (SYSPARAMS_Load( SPI_SETSCREENSAVETIMEOUT_REGKEY,
760 SPI_SETSCREENSAVETIMEOUT_VALNAME,
761 buf ))
762 screensave_timeout = atoi( buf );
764 spi_loaded[spi_idx] = TRUE;
766 *(INT *)pvParam = screensave_timeout;
767 break;
769 case SPI_SETSCREENSAVETIMEOUT: /* 15 */
771 char buf[10];
773 spi_idx = SPI_SETSCREENSAVETIMEOUT_IDX;
774 sprintf(buf, "%u", uiParam);
776 if (SYSPARAMS_Save( SPI_SETSCREENSAVETIMEOUT_REGKEY,
777 SPI_SETSCREENSAVETIMEOUT_VALNAME,
778 buf, fWinIni ))
780 screensave_timeout = uiParam;
781 spi_loaded[spi_idx] = TRUE;
783 else
784 ret = FALSE;
785 break;
788 case SPI_GETSCREENSAVEACTIVE: /* 16 */
789 *(BOOL *)pvParam = USER_Driver.pGetScreenSaveActive();
790 break;
792 case SPI_SETSCREENSAVEACTIVE: /* 17 */
794 char buf[5];
796 sprintf(buf, "%u", uiParam);
797 USER_Driver.pSetScreenSaveActive( uiParam );
798 /* saved value does not affect Wine */
799 SYSPARAMS_Save( SPI_SETSCREENSAVEACTIVE_REGKEY,
800 SPI_SETSCREENSAVEACTIVE_VALNAME,
801 buf, fWinIni );
802 break;
805 case SPI_GETGRIDGRANULARITY: /* 18 */
806 spi_idx = SPI_SETGRIDGRANULARITY_IDX;
807 if (!spi_loaded[spi_idx])
809 char buf[10];
811 if (SYSPARAMS_Load( SPI_SETGRIDGRANULARITY_REGKEY,
812 SPI_SETGRIDGRANULARITY_VALNAME,
813 buf ))
814 grid_granularity = atoi( buf );
816 spi_loaded[spi_idx] = TRUE;
818 *(INT *)pvParam = grid_granularity;
819 break;
821 case SPI_SETGRIDGRANULARITY: /* 19 */
823 char buf[10];
825 spi_idx = SPI_SETGRIDGRANULARITY_IDX;
826 sprintf(buf, "%u", uiParam);
828 if (SYSPARAMS_Save( SPI_SETGRIDGRANULARITY_REGKEY,
829 SPI_SETGRIDGRANULARITY_VALNAME,
830 buf, fWinIni ))
832 grid_granularity = uiParam;
833 spi_loaded[spi_idx] = TRUE;
835 else
836 ret = FALSE;
837 break;
840 case SPI_SETDESKWALLPAPER: /* 20 */
841 SYSPARAMS_Save(SPI_SETDESKWALLPAPER_REGKEY, SPI_SETDESKWALLPAPER_VALNAME, pvParam, fWinIni);
842 ret = SetDeskWallPaper( (LPSTR)pvParam );
843 break;
844 case SPI_SETDESKPATTERN: /* 21 */
845 /* FIXME: the ability to specify a pattern in pvParam
846 doesn't seem to be documented for Win32 */
847 if ((INT16)uiParam == -1)
849 char buffer[256];
850 GetProfileStringA( "Desktop", "Pattern",
851 "170 85 170 85 170 85 170 85",
852 buffer, sizeof(buffer) );
853 ret = DESKTOP_SetPattern( (LPSTR)buffer );
854 } else
855 ret = DESKTOP_SetPattern( (LPSTR)pvParam );
856 break;
858 case SPI_GETKEYBOARDDELAY: /* 22 */
859 spi_idx = SPI_SETKEYBOARDDELAY_IDX;
860 if (!spi_loaded[spi_idx])
862 char buf[10];
864 if (SYSPARAMS_Load( SPI_SETKEYBOARDDELAY_REGKEY,
865 SPI_SETKEYBOARDDELAY_VALNAME,
866 buf ))
868 int i = atoi( buf );
869 if ( (i >= 0) && (i <= 3)) keyboard_delay = i;
872 spi_loaded[spi_idx] = TRUE;
874 *(INT *)pvParam = keyboard_delay;
875 break;
877 case SPI_SETKEYBOARDDELAY: /* 23 */
879 char buf[10];
881 spi_idx = SPI_SETKEYBOARDDELAY_IDX;
882 sprintf(buf, "%u", uiParam);
884 if (SYSPARAMS_Save( SPI_SETKEYBOARDDELAY_REGKEY,
885 SPI_SETKEYBOARDDELAY_VALNAME,
886 buf, fWinIni ))
888 if (uiParam <= 3)
889 keyboard_delay = uiParam;
890 spi_loaded[spi_idx] = TRUE;
892 else
893 ret = FALSE;
894 break;
897 case SPI_ICONVERTICALSPACING: /* 24 */
898 spi_idx = SPI_ICONVERTICALSPACING_IDX;
899 if (pvParam != NULL)
901 if (!spi_loaded[spi_idx])
903 char buf[10];
905 if (SYSPARAMS_Load( SPI_ICONVERTICALSPACING_REGKEY,
906 SPI_ICONVERTICALSPACING_VALNAME, buf ))
908 SYSMETRICS_Set( SM_CYICONSPACING, atoi( buf ) );
910 spi_loaded[spi_idx] = TRUE;
913 *(INT *)pvParam = GetSystemMetrics( SM_CYICONSPACING );
915 else
917 char buf[10];
919 if (uiParam < 32) uiParam = 32;
921 sprintf(buf, "%u", uiParam);
922 if (SYSPARAMS_Save( SPI_ICONVERTICALSPACING_REGKEY,
923 SPI_ICONVERTICALSPACING_VALNAME,
924 buf, fWinIni ))
926 SYSMETRICS_Set( SM_CYICONSPACING, uiParam );
927 spi_loaded[spi_idx] = TRUE;
929 else
930 ret = FALSE;
933 break;
935 case SPI_GETICONTITLEWRAP: /* 25 */
936 spi_idx = SPI_SETICONTITLEWRAP_IDX;
937 if (!spi_loaded[spi_idx])
939 char buf[5];
941 if (SYSPARAMS_Load( SPI_SETICONTITLEWRAP_REGKEY,
942 SPI_SETICONTITLEWRAP_VALNAME, buf ))
943 icon_title_wrap = atoi(buf);
944 spi_loaded[spi_idx] = TRUE;
947 *(BOOL *)pvParam = icon_title_wrap;
948 break;
950 case SPI_SETICONTITLEWRAP: /* 26 */
952 char buf[5];
954 spi_idx = SPI_SETICONTITLEWRAP_IDX;
955 sprintf(buf, "%u", uiParam);
956 if (SYSPARAMS_Save( SPI_SETICONTITLEWRAP_REGKEY,
957 SPI_SETICONTITLEWRAP_VALNAME,
958 buf, fWinIni ))
960 icon_title_wrap = uiParam;
961 spi_loaded[spi_idx] = TRUE;
963 else
964 ret = FALSE;
965 break;
968 case SPI_GETMENUDROPALIGNMENT: /* 27 */
969 spi_idx = SPI_SETMENUDROPALIGNMENT_IDX;
971 if (!spi_loaded[spi_idx])
973 char buf[5];
975 if (SYSPARAMS_Load( SPI_SETMENUDROPALIGNMENT_REGKEY,
976 SPI_SETMENUDROPALIGNMENT_VALNAME, buf ))
978 SYSMETRICS_Set( SM_MENUDROPALIGNMENT, atoi( buf ) );
980 spi_loaded[spi_idx] = TRUE;
984 *(BOOL *)pvParam = GetSystemMetrics( SM_MENUDROPALIGNMENT );
985 break;
987 case SPI_SETMENUDROPALIGNMENT: /* 28 */
989 char buf[5];
990 spi_idx = SPI_SETMENUDROPALIGNMENT_IDX;
992 sprintf(buf, "%u", uiParam);
993 if (SYSPARAMS_Save( SPI_SETMENUDROPALIGNMENT_REGKEY,
994 SPI_SETMENUDROPALIGNMENT_VALNAME,
995 buf, fWinIni ))
997 SYSMETRICS_Set( SM_MENUDROPALIGNMENT, uiParam );
998 spi_loaded[spi_idx] = TRUE;
1000 else
1001 ret = FALSE;
1002 break;
1005 case SPI_SETDOUBLECLKWIDTH: /* 29 */
1007 char buf[10];
1008 spi_idx = SPI_SETDOUBLECLKWIDTH_IDX;
1010 sprintf(buf, "%u", uiParam);
1011 if (SYSPARAMS_Save( SPI_SETDOUBLECLKWIDTH_REGKEY,
1012 SPI_SETDOUBLECLKWIDTH_VALNAME,
1013 buf, fWinIni ))
1015 SYSMETRICS_Set( SM_CXDOUBLECLK, uiParam );
1016 spi_loaded[spi_idx] = TRUE;
1018 else
1019 ret = FALSE;
1020 break;
1023 case SPI_SETDOUBLECLKHEIGHT: /* 30 */
1025 char buf[10];
1026 spi_idx = SPI_SETDOUBLECLKHEIGHT_IDX;
1028 sprintf(buf, "%u", uiParam);
1029 if (SYSPARAMS_Save( SPI_SETDOUBLECLKHEIGHT_REGKEY,
1030 SPI_SETDOUBLECLKHEIGHT_VALNAME,
1031 buf, fWinIni ))
1033 SYSMETRICS_Set( SM_CYDOUBLECLK, uiParam );
1034 spi_loaded[spi_idx] = TRUE;
1036 else
1037 ret = FALSE;
1038 break;
1041 case SPI_GETICONTITLELOGFONT: /* 31 */
1043 LPLOGFONTA lpLogFont = (LPLOGFONTA)pvParam;
1044 LOGFONTA lfDefault;
1047 * The 'default GDI fonts' seems to be returned.
1048 * If a returned font is not a correct font in your environment,
1049 * please try to fix objects/gdiobj.c at first.
1051 SYSPARAMS_GetGUIFont( &lfDefault );
1053 GetProfileStringA( "Desktop", "IconTitleFaceName",
1054 lfDefault.lfFaceName,
1055 lpLogFont->lfFaceName, LF_FACESIZE );
1056 lpLogFont->lfHeight = -GetProfileIntA( "Desktop", "IconTitleSize", 11 );
1057 lpLogFont->lfWidth = 0;
1058 lpLogFont->lfEscapement = lpLogFont->lfOrientation = 0;
1059 lpLogFont->lfWeight = FW_NORMAL;
1060 lpLogFont->lfItalic = FALSE;
1061 lpLogFont->lfStrikeOut = FALSE;
1062 lpLogFont->lfUnderline = FALSE;
1063 lpLogFont->lfCharSet = lfDefault.lfCharSet; /* at least 'charset' should not be hard-coded */
1064 lpLogFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
1065 lpLogFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
1066 lpLogFont->lfPitchAndFamily = DEFAULT_PITCH;
1067 break;
1070 case SPI_SETDOUBLECLICKTIME: /* 32 */
1072 char buf[10];
1074 spi_idx = SPI_SETDOUBLECLICKTIME_IDX;
1075 sprintf(buf, "%u", uiParam);
1077 if (SYSPARAMS_Save( SPI_SETDOUBLECLICKTIME_REGKEY,
1078 SPI_SETDOUBLECLICKTIME_VALNAME,
1079 buf, fWinIni ))
1081 if (!uiParam)
1082 uiParam = 500;
1083 double_click_time = uiParam;
1084 spi_loaded[spi_idx] = TRUE;
1086 else
1087 ret = FALSE;
1088 break;
1091 case SPI_SETMOUSEBUTTONSWAP: /* 33 */
1093 char buf[5];
1094 spi_idx = SPI_SETMOUSEBUTTONSWAP_IDX;
1096 sprintf(buf, "%u", uiParam);
1097 if (SYSPARAMS_Save( SPI_SETMOUSEBUTTONSWAP_REGKEY,
1098 SPI_SETMOUSEBUTTONSWAP_VALNAME,
1099 buf, fWinIni ))
1101 SYSMETRICS_Set( SM_SWAPBUTTON, uiParam );
1102 spi_loaded[spi_idx] = TRUE;
1104 else
1105 ret = FALSE;
1106 break;
1109 WINE_SPI_FIXME(SPI_SETICONTITLELOGFONT); /* 34 */
1111 case SPI_GETFASTTASKSWITCH: /* 35 */
1112 *(BOOL *)pvParam = 1;
1113 break;
1115 case SPI_SETFASTTASKSWITCH: /* 36 */
1116 /* the action is disabled */
1117 ret = FALSE;
1118 break;
1120 case SPI_SETDRAGFULLWINDOWS: /* 37 WINVER >= 0x0400 */
1122 char buf[5];
1124 spi_idx = SPI_SETDRAGFULLWINDOWS_IDX;
1125 sprintf(buf, "%u", uiParam);
1126 if (SYSPARAMS_Save( SPI_SETDRAGFULLWINDOWS_REGKEY,
1127 SPI_SETDRAGFULLWINDOWS_VALNAME,
1128 buf, fWinIni ))
1130 drag_full_windows = uiParam;
1131 spi_loaded[spi_idx] = TRUE;
1133 else
1134 ret = FALSE;
1135 break;
1138 case SPI_GETDRAGFULLWINDOWS: /* 38 WINVER >= 0x0400 */
1139 spi_idx = SPI_SETDRAGFULLWINDOWS_IDX;
1140 if (!spi_loaded[spi_idx])
1142 char buf[5];
1144 if (SYSPARAMS_Load( SPI_SETDRAGFULLWINDOWS_REGKEY,
1145 SPI_SETDRAGFULLWINDOWS_VALNAME, buf ))
1146 drag_full_windows = atoi(buf);
1147 spi_loaded[spi_idx] = TRUE;
1150 *(BOOL *)pvParam = drag_full_windows;
1151 break;
1153 case SPI_GETNONCLIENTMETRICS: /* 41 WINVER >= 0x400 */
1155 LPNONCLIENTMETRICSA lpnm = (LPNONCLIENTMETRICSA)pvParam;
1157 if (lpnm->cbSize == sizeof(NONCLIENTMETRICSA))
1159 /* clear the struct, so we have 'sane' members */
1160 memset(
1161 (char *)pvParam + sizeof(lpnm->cbSize),
1163 lpnm->cbSize - sizeof(lpnm->cbSize)
1166 /* initialize geometry entries */
1167 lpnm->iBorderWidth = 1;
1168 lpnm->iScrollWidth = GetSystemMetrics(SM_CXVSCROLL);
1169 lpnm->iScrollHeight = GetSystemMetrics(SM_CYHSCROLL);
1171 /* size of the normal caption buttons */
1172 lpnm->iCaptionWidth = GetSystemMetrics(SM_CXSIZE);
1173 lpnm->iCaptionHeight = GetSystemMetrics(SM_CYSIZE);
1175 /* caption font metrics */
1176 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0, (LPVOID)&(lpnm->lfCaptionFont), 0 );
1177 lpnm->lfCaptionFont.lfWeight = FW_BOLD;
1179 /* size of the small caption buttons */
1180 lpnm->iSmCaptionWidth = GetSystemMetrics(SM_CXSMSIZE);
1181 lpnm->iSmCaptionHeight = GetSystemMetrics(SM_CYSMSIZE);
1183 /* small caption font metrics */
1184 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0, (LPVOID)&(lpnm->lfSmCaptionFont), 0 );
1186 /* menus, FIXME: names of wine.conf entries are bogus */
1188 /* size of the menu (MDI) buttons */
1189 lpnm->iMenuWidth = GetSystemMetrics(SM_CXMENUSIZE);
1190 lpnm->iMenuHeight = GetSystemMetrics(SM_CYMENUSIZE);
1192 /* menu font metrics */
1193 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0, (LPVOID)&(lpnm->lfMenuFont), 0 );
1194 GetProfileStringA( "Desktop", "MenuFont",
1195 (TWEAK_WineLook > WIN31_LOOK) ? lpnm->lfCaptionFont.lfFaceName : "System",
1196 lpnm->lfMenuFont.lfFaceName, LF_FACESIZE );
1197 lpnm->lfMenuFont.lfHeight = -GetProfileIntA( "Desktop", "MenuFontSize", 11 );
1198 lpnm->lfMenuFont.lfWeight = (TWEAK_WineLook > WIN31_LOOK) ? FW_NORMAL : FW_BOLD;
1200 /* status bar font metrics */
1201 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0,
1202 (LPVOID)&(lpnm->lfStatusFont), 0 );
1203 /* message font metrics */
1204 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0,
1205 (LPVOID)&(lpnm->lfMessageFont), 0 );
1207 else
1209 WARN("size mismatch !! (is %d; should be %d)\n", lpnm->cbSize, sizeof(NONCLIENTMETRICSA));
1210 /* FIXME: SetLastError? */
1211 ret = FALSE;
1213 break;
1215 WINE_SPI_FIXME(SPI_SETNONCLIENTMETRICS); /* 42 WINVER >= 0x400 */
1217 WINE_SPI_FIXME(SPI_GETMINIMIZEDMETRICS); /* 43 WINVER >= 0x400 */
1218 WINE_SPI_FIXME(SPI_SETMINIMIZEDMETRICS); /* 44 WINVER >= 0x400 */
1220 case SPI_GETICONMETRICS: /* 45 WINVER >= 0x400 */
1222 LPICONMETRICSA lpIcon = pvParam;
1223 if(lpIcon && lpIcon->cbSize == sizeof(*lpIcon))
1225 SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0,
1226 &lpIcon->iHorzSpacing, FALSE );
1227 SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0,
1228 &lpIcon->iVertSpacing, FALSE );
1229 SystemParametersInfoA( SPI_GETICONTITLEWRAP, 0,
1230 &lpIcon->iTitleWrap, FALSE );
1231 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0,
1232 &lpIcon->lfFont, FALSE );
1234 else
1236 ret = FALSE;
1238 break;
1240 WINE_SPI_FIXME(SPI_SETICONMETRICS); /* 46 WINVER >= 0x400 */
1242 case SPI_SETWORKAREA: /* 47 WINVER >= 0x400 */
1244 char buf[20];
1245 RECT *pr = (RECT *) pvParam;
1247 spi_idx = SPI_SETWORKAREA_IDX;
1248 sprintf(buf, "%d %d %d %d",
1249 pr->left, pr->top,
1250 pr->right, pr->bottom );
1252 if (SYSPARAMS_Save( SPI_SETWORKAREA_REGKEY,
1253 SPI_SETWORKAREA_VALNAME,
1254 buf, fWinIni ))
1256 CopyRect( &work_area, (RECT *)pvParam );
1257 spi_loaded[spi_idx] = TRUE;
1259 else
1260 ret = FALSE;
1261 break;
1264 case SPI_GETWORKAREA: /* 48 WINVER >= 0x400 */
1265 spi_idx = SPI_SETWORKAREA_IDX;
1266 if (!spi_loaded[spi_idx])
1268 char buf[20];
1270 SetRect( &work_area, 0, 0,
1271 GetSystemMetrics( SM_CXSCREEN ),
1272 GetSystemMetrics( SM_CYSCREEN ) );
1274 if (SYSPARAMS_Load( SPI_SETWORKAREA_REGKEY,
1275 SPI_SETWORKAREA_VALNAME,
1276 buf ))
1278 sscanf( buf, "%d %d %d %d",
1279 &work_area.left, &work_area.top,
1280 &work_area.right, &work_area.bottom );
1282 spi_loaded[spi_idx] = TRUE;
1284 CopyRect( (RECT *)pvParam, &work_area );
1286 break;
1288 WINE_SPI_FIXME(SPI_SETPENWINDOWS); /* 49 WINVER >= 0x400 */
1290 case SPI_GETFILTERKEYS: /* 50 */
1292 LPFILTERKEYS lpFilterKeys = (LPFILTERKEYS)pvParam;
1293 WARN("SPI_GETFILTERKEYS not fully implemented\n");
1294 if (lpFilterKeys->cbSize == sizeof(FILTERKEYS))
1296 /* Indicate that no FilterKeys feature available */
1297 lpFilterKeys->dwFlags = 0;
1298 lpFilterKeys->iWaitMSec = 0;
1299 lpFilterKeys->iDelayMSec = 0;
1300 lpFilterKeys->iRepeatMSec = 0;
1301 lpFilterKeys->iBounceMSec = 0;
1303 else
1305 ret = FALSE;
1307 break;
1309 WINE_SPI_FIXME(SPI_SETFILTERKEYS); /* 51 */
1311 case SPI_GETTOGGLEKEYS: /* 52 */
1313 LPTOGGLEKEYS lpToggleKeys = (LPTOGGLEKEYS)pvParam;
1314 WARN("SPI_GETTOGGLEKEYS not fully implemented\n");
1315 if (lpToggleKeys->cbSize == sizeof(TOGGLEKEYS))
1317 /* Indicate that no ToggleKeys feature available */
1318 lpToggleKeys->dwFlags = 0;
1320 else
1322 ret = FALSE;
1324 break;
1326 WINE_SPI_FIXME(SPI_SETTOGGLEKEYS); /* 53 */
1328 case SPI_GETMOUSEKEYS: /* 54 */
1330 LPMOUSEKEYS lpMouseKeys = (LPMOUSEKEYS)pvParam;
1331 WARN("SPI_GETMOUSEKEYS not fully implemented\n");
1332 if (lpMouseKeys->cbSize == sizeof(MOUSEKEYS))
1334 /* Indicate that no MouseKeys feature available */
1335 lpMouseKeys->dwFlags = 0;
1336 lpMouseKeys->iMaxSpeed = 360;
1337 lpMouseKeys->iTimeToMaxSpeed = 1000;
1338 lpMouseKeys->iCtrlSpeed = 0;
1339 lpMouseKeys->dwReserved1 = 0;
1340 lpMouseKeys->dwReserved2 = 0;
1342 else
1344 ret = FALSE;
1346 break;
1348 WINE_SPI_FIXME(SPI_SETMOUSEKEYS); /* 55 */
1350 case SPI_GETSHOWSOUNDS: /* 56 */
1351 spi_idx = SPI_SETSHOWSOUNDS_IDX;
1353 if (!spi_loaded[spi_idx])
1355 char buf[10];
1357 if (SYSPARAMS_Load( SPI_SETSHOWSOUNDS_REGKEY,
1358 SPI_SETSHOWSOUNDS_VALNAME, buf ))
1360 SYSMETRICS_Set( SM_SHOWSOUNDS, atoi( buf ) );
1362 spi_loaded[spi_idx] = TRUE;
1366 *(INT *)pvParam = GetSystemMetrics( SM_SHOWSOUNDS );
1367 break;
1369 case SPI_SETSHOWSOUNDS: /* 57 */
1371 char buf[10];
1372 spi_idx = SPI_SETSHOWSOUNDS_IDX;
1374 sprintf(buf, "%u", uiParam);
1375 if (SYSPARAMS_Save( SPI_SETSHOWSOUNDS_REGKEY,
1376 SPI_SETSHOWSOUNDS_VALNAME,
1377 buf, fWinIni ))
1379 SYSMETRICS_Set( SM_SHOWSOUNDS, uiParam );
1380 spi_loaded[spi_idx] = TRUE;
1382 else
1383 ret = FALSE;
1384 break;
1387 case SPI_GETSTICKYKEYS: /* 58 */
1389 LPSTICKYKEYS lpStickyKeys = (LPSTICKYKEYS)pvParam;
1390 WARN("SPI_GETSTICKYKEYS not fully implemented\n");
1391 if (lpStickyKeys->cbSize == sizeof(STICKYKEYS))
1393 /* Indicate that no StickyKeys feature available */
1394 lpStickyKeys->dwFlags = 0;
1396 else
1398 ret = FALSE;
1400 break;
1402 WINE_SPI_FIXME(SPI_SETSTICKYKEYS); /* 59 */
1404 case SPI_GETACCESSTIMEOUT: /* 60 */
1406 LPACCESSTIMEOUT lpAccessTimeout = (LPACCESSTIMEOUT)pvParam;
1407 WARN("SPI_GETACCESSTIMEOUT not fully implemented\n");
1408 if (lpAccessTimeout->cbSize == sizeof(ACCESSTIMEOUT))
1410 /* Indicate that no accessibility features timeout is available */
1411 lpAccessTimeout->dwFlags = 0;
1412 lpAccessTimeout->iTimeOutMSec = 0;
1414 else
1416 ret = FALSE;
1418 break;
1420 WINE_SPI_FIXME(SPI_SETACCESSTIMEOUT); /* 61 */
1422 case SPI_GETSERIALKEYS: /* 62 WINVER >= 0x400 */
1424 LPSERIALKEYSA lpSerialKeysA = (LPSERIALKEYSA)pvParam;
1425 WARN("SPI_GETSERIALKEYS not fully implemented\n");
1426 if (lpSerialKeysA->cbSize == sizeof(SERIALKEYSA))
1428 /* Indicate that no SerialKeys feature available */
1429 lpSerialKeysA->dwFlags = 0;
1430 lpSerialKeysA->lpszActivePort = NULL;
1431 lpSerialKeysA->lpszPort = NULL;
1432 lpSerialKeysA->iBaudRate = 0;
1433 lpSerialKeysA->iPortState = 0;
1435 else
1437 ret = FALSE;
1439 break;
1441 WINE_SPI_FIXME(SPI_SETSERIALKEYS); /* 63 WINVER >= 0x400 */
1443 case SPI_GETSOUNDSENTRY: /* 64 */
1445 LPSOUNDSENTRYA lpSoundSentryA = (LPSOUNDSENTRYA)pvParam;
1446 WARN("SPI_GETSOUNDSENTRY not fully implemented\n");
1447 if (lpSoundSentryA->cbSize == sizeof(SOUNDSENTRYA))
1449 /* Indicate that no SoundSentry feature available */
1450 lpSoundSentryA->dwFlags = 0;
1451 lpSoundSentryA->iFSTextEffect = 0;
1452 lpSoundSentryA->iFSTextEffectMSec = 0;
1453 lpSoundSentryA->iFSTextEffectColorBits = 0;
1454 lpSoundSentryA->iFSGrafEffect = 0;
1455 lpSoundSentryA->iFSGrafEffectMSec = 0;
1456 lpSoundSentryA->iFSGrafEffectColor = 0;
1457 lpSoundSentryA->iWindowsEffect = 0;
1458 lpSoundSentryA->iWindowsEffectMSec = 0;
1459 lpSoundSentryA->lpszWindowsEffectDLL = 0;
1460 lpSoundSentryA->iWindowsEffectOrdinal = 0;
1462 else
1464 ret = FALSE;
1466 break;
1468 WINE_SPI_FIXME(SPI_SETSOUNDSENTRY); /* 65 */
1470 case SPI_GETHIGHCONTRAST: /* 66 WINVER >= 0x400 */
1472 LPHIGHCONTRASTA lpHighContrastA = (LPHIGHCONTRASTA)pvParam;
1473 WARN("SPI_GETHIGHCONTRAST not fully implemented\n");
1474 if (lpHighContrastA->cbSize == sizeof(HIGHCONTRASTA))
1476 /* Indicate that no high contrast feature available */
1477 lpHighContrastA->dwFlags = 0;
1478 lpHighContrastA->lpszDefaultScheme = NULL;
1480 else
1482 ret = FALSE;
1484 break;
1486 WINE_SPI_FIXME(SPI_SETHIGHCONTRAST); /* 67 WINVER >= 0x400 */
1488 case SPI_GETKEYBOARDPREF: /* 68 WINVER >= 0x400 */
1489 spi_idx = SPI_SETKEYBOARDPREF_IDX;
1490 if (!spi_loaded[spi_idx])
1492 char buf[5];
1494 if (SYSPARAMS_Load( SPI_SETKEYBOARDPREF_REGKEY,
1495 SPI_SETKEYBOARDPREF_VALNAME, buf ))
1496 keyboard_pref = atoi(buf);
1497 spi_loaded[spi_idx] = TRUE;
1500 *(BOOL *)pvParam = keyboard_pref;
1501 break;
1503 case SPI_SETKEYBOARDPREF: /* 69 WINVER >= 0x400 */
1505 char buf[5];
1507 spi_idx = SPI_SETKEYBOARDPREF_IDX;
1508 sprintf(buf, "%u", uiParam);
1509 if (SYSPARAMS_Save( SPI_SETKEYBOARDPREF_REGKEY,
1510 SPI_SETKEYBOARDPREF_VALNAME,
1511 buf, fWinIni ))
1513 keyboard_pref = uiParam;
1514 spi_loaded[spi_idx] = TRUE;
1516 else
1517 ret = FALSE;
1518 break;
1521 case SPI_GETSCREENREADER: /* 70 WINVER >= 0x400 */
1522 spi_idx = SPI_SETSCREENREADER_IDX;
1523 if (!spi_loaded[spi_idx])
1525 char buf[5];
1527 if (SYSPARAMS_Load( SPI_SETSCREENREADER_REGKEY,
1528 SPI_SETSCREENREADER_VALNAME, buf ))
1529 screen_reader = atoi(buf);
1530 spi_loaded[spi_idx] = TRUE;
1533 *(BOOL *)pvParam = screen_reader;
1534 break;
1536 case SPI_SETSCREENREADER: /* 71 WINVER >= 0x400 */
1538 char buf[5];
1540 spi_idx = SPI_SETSCREENREADER_IDX;
1541 sprintf(buf, "%u", uiParam);
1542 if (SYSPARAMS_Save( SPI_SETSCREENREADER_REGKEY,
1543 SPI_SETSCREENREADER_VALNAME,
1544 buf, fWinIni ))
1546 screen_reader = uiParam;
1547 spi_loaded[spi_idx] = TRUE;
1549 else
1550 ret = FALSE;
1551 break;
1554 case SPI_GETANIMATION: /* 72 WINVER >= 0x400 */
1556 LPANIMATIONINFO lpAnimInfo = (LPANIMATIONINFO)pvParam;
1558 /* Tell it "disabled" */
1559 if (lpAnimInfo->cbSize == sizeof(ANIMATIONINFO))
1560 lpAnimInfo->iMinAnimate = 0; /* Minimise and restore animation is disabled (nonzero == enabled) */
1561 else
1562 ret = FALSE;
1563 break;
1565 WINE_SPI_WARN(SPI_SETANIMATION); /* 73 WINVER >= 0x400 */
1567 WINE_SPI_FIXME(SPI_GETFONTSMOOTHING); /* 74 WINVER >= 0x400 */
1568 WINE_SPI_FIXME(SPI_SETFONTSMOOTHING); /* 75 WINVER >= 0x400 */
1570 WINE_SPI_FIXME(SPI_SETDRAGWIDTH); /* 76 WINVER >= 0x400 */
1571 WINE_SPI_FIXME(SPI_SETDRAGHEIGHT); /* 77 WINVER >= 0x400 */
1573 WINE_SPI_FIXME(SPI_SETHANDHELD); /* 78 WINVER >= 0x400 */
1575 WINE_SPI_FIXME(SPI_GETLOWPOWERTIMEOUT); /* 79 WINVER >= 0x400 */
1576 WINE_SPI_FIXME(SPI_GETPOWEROFFTIMEOUT); /* 80 WINVER >= 0x400 */
1577 WINE_SPI_FIXME(SPI_SETLOWPOWERTIMEOUT); /* 81 WINVER >= 0x400 */
1578 WINE_SPI_FIXME(SPI_SETPOWEROFFTIMEOUT); /* 82 WINVER >= 0x400 */
1579 WINE_SPI_FIXME(SPI_GETLOWPOWERACTIVE); /* 83 WINVER >= 0x400 */
1580 WINE_SPI_FIXME(SPI_GETPOWEROFFACTIVE); /* 84 WINVER >= 0x400 */
1581 WINE_SPI_FIXME(SPI_SETLOWPOWERACTIVE); /* 85 WINVER >= 0x400 */
1582 WINE_SPI_FIXME(SPI_SETPOWEROFFACTIVE); /* 86 WINVER >= 0x400 */
1584 WINE_SPI_FIXME(SPI_SETCURSORS); /* 87 WINVER >= 0x400 */
1585 WINE_SPI_FIXME(SPI_SETICONS); /* 88 WINVER >= 0x400 */
1587 case SPI_GETDEFAULTINPUTLANG: /* 89 WINVER >= 0x400 */
1588 ret = GetKeyboardLayout(0);
1589 break;
1591 WINE_SPI_FIXME(SPI_SETDEFAULTINPUTLANG); /* 90 WINVER >= 0x400 */
1593 WINE_SPI_FIXME(SPI_SETLANGTOGGLE); /* 91 WINVER >= 0x400 */
1595 case SPI_GETWINDOWSEXTENSION: /* 92 WINVER >= 0x400 */
1596 WARN("pretend no support for Win9x Plus! for now.\n");
1597 ret = FALSE; /* yes, this is the result value */
1598 break;
1600 WINE_SPI_FIXME(SPI_SETMOUSETRAILS); /* 93 WINVER >= 0x400 */
1601 WINE_SPI_FIXME(SPI_GETMOUSETRAILS); /* 94 WINVER >= 0x400 */
1603 case SPI_SETSCREENSAVERRUNNING: /* 97 WINVER >= 0x400 */
1605 /* SPI_SCREENSAVERRUNNING is an alias for SPI_SETSCREENSAVERRUNNING */
1606 char buf[5];
1608 spi_idx = SPI_SETSCREENSAVERRUNNING_IDX;
1609 sprintf(buf, "%u", uiParam);
1611 /* save only temporarily */
1612 if (SYSPARAMS_Save( SPI_SETSCREENSAVERRUNNING_REGKEY,
1613 SPI_SETSCREENSAVERRUNNING_VALNAME,
1614 buf, 0 ))
1616 screensaver_running = uiParam;
1617 spi_loaded[spi_idx] = TRUE;
1619 else
1620 ret = FALSE;
1621 break;
1624 case SPI_GETMOUSEHOVERWIDTH: /* 98 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1625 *(UINT *)pvParam = 4;
1626 break;
1627 WINE_SPI_FIXME(SPI_SETMOUSEHOVERWIDTH); /* 99 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1629 case SPI_GETMOUSEHOVERHEIGHT: /* 100 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1630 *(UINT *)pvParam = 4;
1631 break;
1632 WINE_SPI_FIXME(SPI_SETMOUSEHOVERHEIGHT); /* 101 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1634 case SPI_GETMOUSEHOVERTIME: /* 102 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1635 *(UINT *)pvParam = 400; /* default for menu dropdowns */
1636 break;
1637 WINE_SPI_FIXME(SPI_SETMOUSEHOVERTIME); /* 103 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1639 case SPI_GETWHEELSCROLLLINES: /* 104 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1640 *(UINT *)pvParam = 3; /* default for num scroll lines */
1641 break;
1643 WINE_SPI_FIXME(SPI_SETWHEELSCROLLLINES); /* 105 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1645 case SPI_GETMENUSHOWDELAY: /* 106 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1646 *(UINT *)pvParam = 400; /* Tested against Windows NT 4.0 and Windows 2000 */
1647 break;
1649 WINE_SPI_FIXME(SPI_GETSHOWIMEUI); /* 110 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1650 WINE_SPI_FIXME(SPI_SETSHOWIMEUI); /* 111 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1652 case SPI_GETSCREENSAVERRUNNING: /* 114 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1653 spi_idx = SPI_SETSCREENSAVERRUNNING_IDX;
1654 if (!spi_loaded[spi_idx])
1656 char buf[5];
1658 if (SYSPARAMS_Load( SPI_SETSCREENSAVERRUNNING_REGKEY,
1659 SPI_SETSCREENSAVERRUNNING_VALNAME, buf ))
1660 screensaver_running = atoi( buf );
1661 spi_loaded[spi_idx] = TRUE;
1664 *(BOOL *)pvParam = screensaver_running;
1665 break;
1667 case SPI_GETDESKWALLPAPER: /* 115 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1669 char buf[MAX_PATH];
1671 if (uiParam > MAX_PATH)
1673 uiParam = MAX_PATH;
1676 if (SYSPARAMS_Load(SPI_SETDESKWALLPAPER_REGKEY, SPI_SETDESKWALLPAPER_VALNAME, buf))
1678 strncpy((char*)pvParam, buf, uiParam);
1680 else
1682 /* Return an empty string */
1683 memset((char*)pvParam, 0, uiParam);
1686 break;
1689 WINE_SPI_FIXME(SPI_GETACTIVEWINDOWTRACKING);/* 0x1000 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1690 WINE_SPI_FIXME(SPI_SETACTIVEWINDOWTRACKING);/* 0x1001 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1691 WINE_SPI_FIXME(SPI_GETMENUANIMATION); /* 0x1002 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1692 WINE_SPI_FIXME(SPI_SETMENUANIMATION); /* 0x1003 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1693 WINE_SPI_FIXME(SPI_GETCOMBOBOXANIMATION); /* 0x1004 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1694 WINE_SPI_FIXME(SPI_SETCOMBOBOXANIMATION); /* 0x1005 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1695 WINE_SPI_FIXME(SPI_GETLISTBOXSMOOTHSCROLLING);/* 0x1006 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1696 WINE_SPI_FIXME(SPI_SETLISTBOXSMOOTHSCROLLING);/* 0x1007 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1697 WINE_SPI_FIXME(SPI_GETGRADIENTCAPTIONS); /* 0x1008 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1698 WINE_SPI_FIXME(SPI_SETGRADIENTCAPTIONS); /* 0x1009 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1699 WINE_SPI_FIXME(SPI_GETMENUUNDERLINES); /* 0x100A _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1700 WINE_SPI_FIXME(SPI_SETMENUUNDERLINES); /* 0x100B _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1701 WINE_SPI_FIXME(SPI_GETACTIVEWNDTRKZORDER); /* 0x100C _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1702 WINE_SPI_FIXME(SPI_SETACTIVEWNDTRKZORDER); /* 0x100D _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1703 WINE_SPI_FIXME(SPI_GETHOTTRACKING); /* 0x100E _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1704 WINE_SPI_FIXME(SPI_SETHOTTRACKING); /* 0x100F _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1705 WINE_SPI_FIXME(SPI_GETFOREGROUNDLOCKTIMEOUT);/* 0x2000 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1706 WINE_SPI_FIXME(SPI_SETFOREGROUNDLOCKTIMEOUT);/* 0x2001 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1707 WINE_SPI_FIXME(SPI_GETACTIVEWNDTRKTIMEOUT); /* 0x2002 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1708 WINE_SPI_FIXME(SPI_SETACTIVEWNDTRKTIMEOUT); /* 0x2003 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1709 WINE_SPI_FIXME(SPI_GETFOREGROUNDFLASHCOUNT);/* 0x2004 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1710 WINE_SPI_FIXME(SPI_SETFOREGROUNDFLASHCOUNT);/* 0x2005 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1712 default:
1713 FIXME( "Unknown action: %u\n", uiAction );
1714 SetLastError( ERROR_INVALID_SPI_VALUE );
1715 ret = FALSE;
1716 break;
1719 if (ret)
1720 SYSPARAMS_NotifyChange( uiAction, fWinIni );
1721 return ret;
1723 #undef WINE_SPI_FIXME
1724 #undef WINE_SPI_WARN
1728 /***********************************************************************
1729 * SystemParametersInfo (USER.483)
1731 BOOL16 WINAPI SystemParametersInfo16( UINT16 uAction, UINT16 uParam,
1732 LPVOID lpvParam, UINT16 fuWinIni )
1734 BOOL16 ret;
1736 TRACE("(%u, %u, %p, %u)\n", uAction, uParam, lpvParam, fuWinIni);
1738 switch (uAction)
1740 case SPI_GETBEEP: /* 1 */
1741 case SPI_GETSCREENSAVEACTIVE: /* 16 */
1742 case SPI_GETICONTITLEWRAP: /* 25 */
1743 case SPI_GETMENUDROPALIGNMENT: /* 27 */
1744 case SPI_GETFASTTASKSWITCH: /* 35 */
1745 case SPI_GETDRAGFULLWINDOWS: /* 38 WINVER >= 0x0400 */
1747 BOOL tmp;
1748 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1749 if (ret && lpvParam)
1750 *(BOOL16 *)lpvParam = tmp;
1751 break;
1754 case SPI_GETBORDER: /* 5 */
1755 case SPI_ICONHORIZONTALSPACING: /* 13 */
1756 case SPI_GETSCREENSAVETIMEOUT: /* 14 */
1757 case SPI_GETGRIDGRANULARITY: /* 18 */
1758 case SPI_GETKEYBOARDDELAY: /* 22 */
1759 case SPI_ICONVERTICALSPACING: /* 24 */
1761 INT tmp;
1762 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1763 if (ret && lpvParam)
1764 *(INT16 *)lpvParam = tmp;
1765 break;
1768 case SPI_GETKEYBOARDSPEED: /* 10 */
1770 DWORD tmp;
1771 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1772 if (ret && lpvParam)
1773 *(WORD *)lpvParam = tmp;
1774 break;
1777 case SPI_GETICONTITLELOGFONT: /* 31 */
1779 LOGFONTA tmp;
1780 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1781 if (ret && lpvParam)
1782 SYSPARAMS_LogFont32ATo16( &tmp, (LPLOGFONT16)lpvParam );
1783 break;
1786 case SPI_GETNONCLIENTMETRICS: /* 41 WINVER >= 0x400 */
1788 NONCLIENTMETRICSA tmp;
1789 LPNONCLIENTMETRICS16 lpnm16 = (LPNONCLIENTMETRICS16)lpvParam;
1790 if (lpnm16 && lpnm16->cbSize == sizeof(NONCLIENTMETRICS16))
1792 tmp.cbSize = sizeof(NONCLIENTMETRICSA);
1793 ret = SystemParametersInfoA( uAction, uParam, &tmp, fuWinIni );
1794 if (ret)
1795 SYSPARAMS_NonClientMetrics32ATo16( &tmp, lpnm16 );
1797 else /* winfile 95 sets cbSize to 340 */
1798 ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
1799 break;
1802 case SPI_GETWORKAREA: /* 48 WINVER >= 0x400 */
1804 RECT tmp;
1805 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1806 if (ret && lpvParam)
1807 CONV_RECT32TO16( &tmp, (RECT16 *)lpvParam );
1808 break;
1811 case SPI_GETMOUSEHOVERWIDTH: /* 98 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1812 case SPI_GETMOUSEHOVERHEIGHT: /* 100 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1813 case SPI_GETMOUSEHOVERTIME: /* 102 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1815 UINT tmp;
1816 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1817 if (ret && lpvParam)
1818 *(UINT16 *)lpvParam = tmp;
1819 break;
1822 default:
1823 ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
1826 return ret;
1829 /***********************************************************************
1830 * SystemParametersInfoW (USER32.@)
1832 BOOL WINAPI SystemParametersInfoW( UINT uiAction, UINT uiParam,
1833 PVOID pvParam, UINT fuWinIni )
1835 BOOL ret;
1837 TRACE("(%u, %u, %p, %u)\n", uiAction, uiParam, pvParam, fuWinIni);
1839 switch (uiAction)
1841 case SPI_SETDESKWALLPAPER: /* 20 */
1842 case SPI_SETDESKPATTERN: /* 21 */
1844 char buffer[256];
1845 if (pvParam)
1846 if (!WideCharToMultiByte( CP_ACP, 0, (LPWSTR)pvParam, -1,
1847 buffer, sizeof(buffer), NULL, NULL ))
1848 buffer[sizeof(buffer)-1] = 0;
1849 ret = SystemParametersInfoA( uiAction, uiParam, pvParam ? buffer : NULL, fuWinIni );
1850 break;
1853 case SPI_GETICONTITLELOGFONT: /* 31 */
1855 LOGFONTA tmp;
1856 ret = SystemParametersInfoA( uiAction, uiParam, pvParam ? &tmp : NULL, fuWinIni );
1857 if (ret && pvParam)
1858 SYSPARAMS_LogFont32ATo32W( &tmp, (LPLOGFONTW)pvParam );
1859 break;
1862 case SPI_GETNONCLIENTMETRICS: /* 41 WINVER >= 0x400 */
1864 NONCLIENTMETRICSA tmp;
1865 LPNONCLIENTMETRICSW lpnmW = (LPNONCLIENTMETRICSW)pvParam;
1866 if (lpnmW && lpnmW->cbSize == sizeof(NONCLIENTMETRICSW))
1868 tmp.cbSize = sizeof(NONCLIENTMETRICSA);
1869 ret = SystemParametersInfoA( uiAction, uiParam, &tmp, fuWinIni );
1870 if (ret)
1871 SYSPARAMS_NonClientMetrics32ATo32W( &tmp, lpnmW );
1873 else
1874 ret = FALSE;
1875 break;
1878 case SPI_GETICONMETRICS: /* 45 WINVER >= 0x400 */
1880 ICONMETRICSA tmp;
1881 LPICONMETRICSW lpimW = (LPICONMETRICSW)pvParam;
1882 if (lpimW && lpimW->cbSize == sizeof(ICONMETRICSW))
1884 tmp.cbSize = sizeof(ICONMETRICSA);
1885 ret = SystemParametersInfoA( uiAction, uiParam, &tmp, fuWinIni );
1886 if (ret)
1888 lpimW->iHorzSpacing = tmp.iHorzSpacing;
1889 lpimW->iVertSpacing = tmp.iVertSpacing;
1890 lpimW->iTitleWrap = tmp.iTitleWrap;
1891 SYSPARAMS_LogFont32ATo32W( &tmp.lfFont, &lpimW->lfFont );
1894 else
1895 ret = FALSE;
1896 break;
1899 case SPI_GETHIGHCONTRAST: /* 66 WINVER >= 0x400 */
1901 HIGHCONTRASTA tmp;
1902 LPHIGHCONTRASTW lphcW = (LPHIGHCONTRASTW)pvParam;
1903 if (lphcW && lphcW->cbSize == sizeof(HIGHCONTRASTW))
1905 tmp.cbSize = sizeof(HIGHCONTRASTA);
1906 ret = SystemParametersInfoA( uiAction, uiParam, &tmp, fuWinIni );
1907 if (ret)
1909 lphcW->dwFlags = tmp.dwFlags;
1910 lphcW->lpszDefaultScheme = NULL; /* FIXME? */
1913 else
1914 ret = FALSE;
1915 break;
1918 default:
1919 ret = SystemParametersInfoA( uiAction, uiParam, pvParam, fuWinIni );
1920 break;
1922 return ret;
1926 /**********************************************************************
1927 * SetDoubleClickTime (USER32.@)
1929 BOOL WINAPI SetDoubleClickTime( UINT interval )
1931 return SystemParametersInfoA(SPI_SETDOUBLECLICKTIME, interval, 0, 0);
1935 /**********************************************************************
1936 * GetDoubleClickTime (USER32.@)
1938 UINT WINAPI GetDoubleClickTime(void)
1940 char buf[10];
1942 if (!spi_loaded[SPI_SETDOUBLECLICKTIME_IDX])
1944 if (SYSPARAMS_Load( SPI_SETDOUBLECLICKTIME_REGKEY,
1945 SPI_SETDOUBLECLICKTIME_VALNAME,
1946 buf ))
1948 double_click_time = atoi( buf );
1949 if (!double_click_time) double_click_time = 500;
1951 spi_loaded[SPI_SETDOUBLECLICKTIME_IDX] = TRUE;
1953 return double_click_time;