Added some stubs.
[wine/multimedia.git] / windows / sysparams.c
blob7f3a4582338d5962ae0e337ce8442377a35f9389
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_SETFONTSMOOTHING_IDX 21
64 #define SPI_SETKEYBOARDCUES_IDX 22
65 #define SPI_SETGRADIENTCAPTIONS_IDX 23
66 #define SPI_SETHOTTRACKING_IDX 24
67 #define SPI_SETLISTBOXSMOOTHSCROLLING_IDX 25
69 #define SPI_WINE_IDX SPI_SETSCREENSAVERRUNNING_IDX
71 /**
72 * Names of the registry subkeys of HKEY_CURRENT_USER key and value names
73 * for the system parameters.
74 * Names of the keys are created by adding string "_REGKEY" to
75 * "SET" action names, value names are created by adding "_REG_NAME"
76 * to the "SET" action name.
78 #define SPI_SETBEEP_REGKEY "Control Panel\\Sound"
79 #define SPI_SETBEEP_VALNAME "Beep"
80 #define SPI_SETMOUSE_REGKEY "Control Panel\\Mouse"
81 #define SPI_SETMOUSE_VALNAME1 "MouseThreshold1"
82 #define SPI_SETMOUSE_VALNAME2 "MouseThreshold2"
83 #define SPI_SETMOUSE_VALNAME3 "MouseSpeed"
84 #define SPI_SETBORDER_REGKEY "Control Panel\\Desktop"
85 #define SPI_SETBORDER_VALNAME "BorderWidth"
86 #define SPI_SETKEYBOARDSPEED_REGKEY "Control Panel\\Keyboard"
87 #define SPI_SETKEYBOARDSPEED_VALNAME "KeyboardSpeed"
88 #define SPI_ICONHORIZONTALSPACING_REGKEY "Control Panel\\Desktop\\WindowMetrics"
89 #define SPI_ICONHORIZONTALSPACING_VALNAME "IconSpacing"
90 #define SPI_SETSCREENSAVETIMEOUT_REGKEY "Control Panel\\Desktop"
91 #define SPI_SETSCREENSAVETIMEOUT_VALNAME "ScreenSaveTimeOut"
92 #define SPI_SETSCREENSAVEACTIVE_REGKEY "Control Panel\\Desktop"
93 #define SPI_SETSCREENSAVEACTIVE_VALNAME "ScreenSaveActive"
94 #define SPI_SETGRIDGRANULARITY_REGKEY "Control Panel\\Desktop"
95 #define SPI_SETGRIDGRANULARITY_VALNAME "GridGranularity"
96 #define SPI_SETKEYBOARDDELAY_REGKEY "Control Panel\\Keyboard"
97 #define SPI_SETKEYBOARDDELAY_VALNAME "KeyboardDelay"
98 #define SPI_ICONVERTICALSPACING_REGKEY "Control Panel\\Desktop\\WindowMetrics"
99 #define SPI_ICONVERTICALSPACING_VALNAME "IconVerticalSpacing"
100 #define SPI_SETICONTITLEWRAP_REGKEY1 "Control Panel\\Desktop\\WindowMetrics"
101 #define SPI_SETICONTITLEWRAP_REGKEY2 "Control Panel\\Desktop"
102 #define SPI_SETICONTITLEWRAP_VALNAME "IconTitleWrap"
103 #define SPI_SETMENUDROPALIGNMENT_REGKEY1 "Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows"
104 #define SPI_SETMENUDROPALIGNMENT_REGKEY2 "Control Panel\\Desktop"
105 #define SPI_SETMENUDROPALIGNMENT_VALNAME "MenuDropAlignment"
106 #define SPI_SETDOUBLECLKWIDTH_REGKEY1 "Control Panel\\Mouse"
107 #define SPI_SETDOUBLECLKWIDTH_REGKEY2 "Control Panel\\Desktop"
108 #define SPI_SETDOUBLECLKWIDTH_VALNAME "DoubleClickWidth"
109 #define SPI_SETDOUBLECLKHEIGHT_REGKEY1 "Control Panel\\Mouse"
110 #define SPI_SETDOUBLECLKHEIGHT_REGKEY2 "Control Panel\\Desktop"
111 #define SPI_SETDOUBLECLKHEIGHT_VALNAME "DoubleClickHeight"
112 #define SPI_SETDOUBLECLICKTIME_REGKEY "Control Panel\\Mouse"
113 #define SPI_SETDOUBLECLICKTIME_VALNAME "DoubleClickSpeed"
114 #define SPI_SETMOUSEBUTTONSWAP_REGKEY "Control Panel\\Mouse"
115 #define SPI_SETMOUSEBUTTONSWAP_VALNAME "SwapMouseButtons"
116 #define SPI_SETDRAGFULLWINDOWS_REGKEY "Control Panel\\Desktop"
117 #define SPI_SETDRAGFULLWINDOWS_VALNAME "DragFullWindows"
118 #define SPI_SETWORKAREA_REGKEY "Control Panel\\Desktop"
119 #define SPI_SETWORKAREA_VALNAME "WINE_WorkArea"
120 #define SPI_SETSHOWSOUNDS_REGKEY "Control Panel\\Accessibility\\ShowSounds"
121 #define SPI_SETSHOWSOUNDS_VALNAME "On"
122 #define SPI_SETDESKWALLPAPER_REGKEY "Control Panel\\Desktop"
123 #define SPI_SETDESKWALLPAPER_VALNAME "Wallpaper"
124 #define SPI_SETFONTSMOOTHING_REGKEY "Control Panel\\Desktop"
125 #define SPI_SETFONTSMOOTHING_VALNAME "FontSmoothing"
126 #define SPI_USERPREFERENCEMASK_REGKEY "Control Panel\\Desktop"
127 #define SPI_USERPREFERENCEMASK_VALNAME "UserPreferencemask"
128 #define SPI_SETLISTBOXSMOOTHSCROLLING_REGKEY "Control Panel\\Desktop"
129 #define SPI_SETLISTBOXSMOOTHSCROLLING_VALNAME "SmoothScroll"
131 /* FIXME - real values */
132 #define SPI_SETKEYBOARDPREF_REGKEY "Control Panel\\Desktop"
133 #define SPI_SETKEYBOARDPREF_VALNAME "WINE_KeyboardPref"
134 #define SPI_SETSCREENREADER_REGKEY "Control Panel\\Desktop"
135 #define SPI_SETSCREENREADER_VALNAME "WINE_ScreenReader"
136 #define SPI_SETSCREENSAVERRUNNING_REGKEY "Control Panel\\Desktop"
137 #define SPI_SETSCREENSAVERRUNNING_VALNAME "WINE_ScreenSaverRunning"
139 /* volatile registry branch under CURRENT_USER_REGKEY for temporary values storage */
140 #define WINE_CURRENT_USER_REGKEY "Wine"
142 /* Indicators whether system parameter value is loaded */
143 static char spi_loaded[SPI_WINE_IDX + 1];
145 static BOOL notify_change = TRUE;
147 /* System parameters storage */
148 static BOOL beep_active = TRUE;
149 static int mouse_threshold1 = 6;
150 static int mouse_threshold2 = 10;
151 static int mouse_speed = 1;
152 static int border = 1;
153 static int keyboard_speed = 31;
154 static int screensave_timeout = 300;
155 static int grid_granularity = 0;
156 static int keyboard_delay = 1;
157 static BOOL icon_title_wrap = TRUE;
158 static int double_click_time = 500;
159 static BOOL drag_full_windows = FALSE;
160 static RECT work_area;
161 static BOOL keyboard_pref = TRUE;
162 static BOOL screen_reader = FALSE;
163 static BOOL screensaver_running = FALSE;
164 static BOOL font_smoothing = FALSE;
165 static BOOL keyboard_cues = FALSE;
166 static BOOL gradient_captions = FALSE;
167 static BOOL listbox_smoothscrolling = FALSE;
168 static BOOL hot_tracking = FALSE;
170 /***********************************************************************
171 * GetTimerResolution (USER.14)
173 LONG WINAPI GetTimerResolution16(void)
175 return (1000);
178 /***********************************************************************
179 * ControlPanelInfo (USER.273)
181 void WINAPI ControlPanelInfo16( INT16 nInfoType, WORD wData, LPSTR lpBuffer )
183 FIXME("(%d, %04x, %p): stub.\n", nInfoType, wData, lpBuffer);
186 /* This function is a copy of the one in objects/font.c */
187 static void SYSPARAMS_LogFont32ATo16( const LOGFONTA* font32, LPLOGFONT16 font16 )
189 font16->lfHeight = font32->lfHeight;
190 font16->lfWidth = font32->lfWidth;
191 font16->lfEscapement = font32->lfEscapement;
192 font16->lfOrientation = font32->lfOrientation;
193 font16->lfWeight = font32->lfWeight;
194 font16->lfItalic = font32->lfItalic;
195 font16->lfUnderline = font32->lfUnderline;
196 font16->lfStrikeOut = font32->lfStrikeOut;
197 font16->lfCharSet = font32->lfCharSet;
198 font16->lfOutPrecision = font32->lfOutPrecision;
199 font16->lfClipPrecision = font32->lfClipPrecision;
200 font16->lfQuality = font32->lfQuality;
201 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
202 lstrcpynA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
205 static void SYSPARAMS_LogFont32ATo32W( const LOGFONTA* font32A, LPLOGFONTW font32W )
207 font32W->lfHeight = font32A->lfHeight;
208 font32W->lfWidth = font32A->lfWidth;
209 font32W->lfEscapement = font32A->lfEscapement;
210 font32W->lfOrientation = font32A->lfOrientation;
211 font32W->lfWeight = font32A->lfWeight;
212 font32W->lfItalic = font32A->lfItalic;
213 font32W->lfUnderline = font32A->lfUnderline;
214 font32W->lfStrikeOut = font32A->lfStrikeOut;
215 font32W->lfCharSet = font32A->lfCharSet;
216 font32W->lfOutPrecision = font32A->lfOutPrecision;
217 font32W->lfClipPrecision = font32A->lfClipPrecision;
218 font32W->lfQuality = font32A->lfQuality;
219 font32W->lfPitchAndFamily = font32A->lfPitchAndFamily;
220 MultiByteToWideChar( CP_ACP, 0, font32A->lfFaceName, -1, font32W->lfFaceName, LF_FACESIZE );
221 font32W->lfFaceName[LF_FACESIZE-1] = 0;
224 static void SYSPARAMS_NonClientMetrics32ATo16( const NONCLIENTMETRICSA* lpnm32, LPNONCLIENTMETRICS16 lpnm16 )
226 lpnm16->iBorderWidth = lpnm32->iBorderWidth;
227 lpnm16->iScrollWidth = lpnm32->iScrollWidth;
228 lpnm16->iScrollHeight = lpnm32->iScrollHeight;
229 lpnm16->iCaptionWidth = lpnm32->iCaptionWidth;
230 lpnm16->iCaptionHeight = lpnm32->iCaptionHeight;
231 SYSPARAMS_LogFont32ATo16( &lpnm32->lfCaptionFont, &lpnm16->lfCaptionFont );
232 lpnm16->iSmCaptionWidth = lpnm32->iSmCaptionWidth;
233 lpnm16->iSmCaptionHeight = lpnm32->iSmCaptionHeight;
234 SYSPARAMS_LogFont32ATo16( &lpnm32->lfSmCaptionFont, &lpnm16->lfSmCaptionFont );
235 lpnm16->iMenuWidth = lpnm32->iMenuWidth;
236 lpnm16->iMenuHeight = lpnm32->iMenuHeight;
237 SYSPARAMS_LogFont32ATo16( &lpnm32->lfMenuFont, &lpnm16->lfMenuFont );
238 SYSPARAMS_LogFont32ATo16( &lpnm32->lfStatusFont, &lpnm16->lfStatusFont );
239 SYSPARAMS_LogFont32ATo16( &lpnm32->lfMessageFont, &lpnm16->lfMessageFont );
242 static void SYSPARAMS_NonClientMetrics32ATo32W( const NONCLIENTMETRICSA* lpnm32A, LPNONCLIENTMETRICSW lpnm32W )
244 lpnm32W->iBorderWidth = lpnm32A->iBorderWidth;
245 lpnm32W->iScrollWidth = lpnm32A->iScrollWidth;
246 lpnm32W->iScrollHeight = lpnm32A->iScrollHeight;
247 lpnm32W->iCaptionWidth = lpnm32A->iCaptionWidth;
248 lpnm32W->iCaptionHeight = lpnm32A->iCaptionHeight;
249 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfCaptionFont, &lpnm32W->lfCaptionFont );
250 lpnm32W->iSmCaptionWidth = lpnm32A->iSmCaptionWidth;
251 lpnm32W->iSmCaptionHeight = lpnm32A->iSmCaptionHeight;
252 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfSmCaptionFont, &lpnm32W->lfSmCaptionFont );
253 lpnm32W->iMenuWidth = lpnm32A->iMenuWidth;
254 lpnm32W->iMenuHeight = lpnm32A->iMenuHeight;
255 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfMenuFont, &lpnm32W->lfMenuFont );
256 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfStatusFont, &lpnm32W->lfStatusFont );
257 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfMessageFont, &lpnm32W->lfMessageFont );
260 /***********************************************************************
261 * SYSPARAMS_Reset
263 * Sets the system parameter which should be always loaded to
264 * current value stored in registry.
265 * Invalidates lazy loaded parameter, so it will be loaded the next time
266 * it is requested.
268 * Parameters:
269 * uiAction - system parameter to reload value for.
270 * Note, only "SET" values can be used for this parameter.
271 * If uiAction is 0 all system parameters are reset.
273 void SYSPARAMS_Reset( UINT uiAction )
275 #define WINE_RELOAD_SPI(x) \
276 case x: \
277 spi_loaded[x##_IDX] = FALSE; \
278 SystemParametersInfoA( x, 0, dummy_buf, 0 );\
279 if (uiAction) \
280 break
282 #define WINE_IGNORE_SPI(x) \
283 case x: \
284 if (uiAction) \
285 break
287 #define WINE_INVALIDATE_SPI(x) \
288 case x: \
289 spi_loaded[x##_IDX] = FALSE; \
290 break
292 BOOL not_all_processed = TRUE;
293 char dummy_buf[10];
295 /* Execution falls through all the branches for uiAction == 0 */
296 switch (uiAction)
298 case 0:
299 memset( spi_loaded, 0, sizeof(spi_loaded) );
301 WINE_RELOAD_SPI(SPI_SETBORDER);
302 WINE_RELOAD_SPI(SPI_ICONHORIZONTALSPACING);
303 WINE_RELOAD_SPI(SPI_ICONVERTICALSPACING);
304 WINE_IGNORE_SPI(SPI_SETSCREENSAVEACTIVE);
305 WINE_RELOAD_SPI(SPI_SETDOUBLECLKWIDTH);
306 WINE_RELOAD_SPI(SPI_SETDOUBLECLKHEIGHT);
307 WINE_RELOAD_SPI(SPI_SETMOUSEBUTTONSWAP);
308 WINE_RELOAD_SPI(SPI_SETSHOWSOUNDS);
309 WINE_RELOAD_SPI(SPI_SETMENUDROPALIGNMENT);
311 default:
312 if (uiAction)
314 /* lazy loaded parameters */
315 switch (uiAction)
317 WINE_INVALIDATE_SPI(SPI_SETBEEP);
318 WINE_INVALIDATE_SPI(SPI_SETMOUSE);
319 WINE_INVALIDATE_SPI(SPI_SETKEYBOARDSPEED);
320 WINE_INVALIDATE_SPI(SPI_SETSCREENSAVETIMEOUT);
321 WINE_INVALIDATE_SPI(SPI_SETGRIDGRANULARITY);
322 WINE_INVALIDATE_SPI(SPI_SETKEYBOARDDELAY);
323 WINE_INVALIDATE_SPI(SPI_SETICONTITLEWRAP);
324 WINE_INVALIDATE_SPI(SPI_SETDOUBLECLICKTIME);
325 WINE_INVALIDATE_SPI(SPI_SETDRAGFULLWINDOWS);
326 WINE_INVALIDATE_SPI(SPI_SETWORKAREA);
327 WINE_INVALIDATE_SPI(SPI_SETKEYBOARDPREF);
328 WINE_INVALIDATE_SPI(SPI_SETSCREENREADER);
329 WINE_INVALIDATE_SPI(SPI_SETSCREENSAVERRUNNING);
330 default:
331 FIXME( "Unknown action reset: %u\n", uiAction );
332 break;
335 else
336 not_all_processed = FALSE;
337 break;
340 if (!uiAction && not_all_processed)
341 ERR( "Incorrect implementation of SYSPARAMS_Reset. "
342 "Not all params are reloaded.\n" );
343 #undef WINE_INVALIDATE_SPI
344 #undef WINE_IGNORE_SPI
345 #undef WINE_RELOAD_SPI
348 /***********************************************************************
349 * get_volatile_regkey
351 * Return a handle to the volatile registry key used to store
352 * non-permanently modified parameters.
354 static HKEY get_volatile_regkey(void)
356 static HKEY volatile_key;
358 if (!volatile_key)
360 if (RegCreateKeyExA( HKEY_CURRENT_USER, WINE_CURRENT_USER_REGKEY,
361 0, 0, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, 0,
362 &volatile_key, 0 ) != ERROR_SUCCESS)
363 ERR("Can't create wine configuration registry branch\n");
365 return volatile_key;
368 /***********************************************************************
369 * SYSPARAMS_NotifyChange
371 * Sends notification about system parameter update.
373 void SYSPARAMS_NotifyChange( UINT uiAction, UINT fWinIni )
375 static const WCHAR emptyW[1];
377 if (notify_change)
379 if (fWinIni & SPIF_UPDATEINIFILE)
381 if (fWinIni & (SPIF_SENDWININICHANGE | SPIF_SENDCHANGE))
382 SendMessageTimeoutW(HWND_BROADCAST, WM_SETTINGCHANGE,
383 uiAction, (LPARAM) emptyW,
384 SMTO_ABORTIFHUNG, 2000, NULL );
386 else
388 /* FIXME notify other wine processes with internal message */
394 /***********************************************************************
395 * Loads system parameter from user profile.
397 static BOOL SYSPARAMS_Load( LPCSTR lpRegKey, LPCSTR lpValName, LPSTR lpBuf, DWORD count )
399 BOOL ret = FALSE;
400 DWORD type;
401 HKEY hKey;
403 if ((RegOpenKeyA( get_volatile_regkey(), lpRegKey, &hKey ) == ERROR_SUCCESS) ||
404 (RegOpenKeyA( HKEY_CURRENT_USER, lpRegKey, &hKey ) == ERROR_SUCCESS))
406 ret = !RegQueryValueExA( hKey, lpValName, NULL, &type, lpBuf, &count );
407 RegCloseKey( hKey );
409 return ret;
412 /***********************************************************************
413 * Saves system parameter to user profile.
415 static BOOL SYSPARAMS_Save( LPCSTR lpRegKey, LPCSTR lpValName, LPCSTR lpValue,
416 UINT fWinIni )
418 HKEY hKey;
419 HKEY hBaseKey;
420 DWORD dwOptions;
421 BOOL ret = FALSE;
423 if (fWinIni & SPIF_UPDATEINIFILE)
425 hBaseKey = HKEY_CURRENT_USER;
426 dwOptions = 0;
428 else
430 hBaseKey = get_volatile_regkey();
431 dwOptions = REG_OPTION_VOLATILE;
434 if (RegCreateKeyExA( hBaseKey, lpRegKey,
435 0, 0, dwOptions, KEY_ALL_ACCESS,
436 0, &hKey, 0 ) == ERROR_SUCCESS)
438 if (RegSetValueExA( hKey, lpValName, 0, REG_SZ,
439 lpValue, strlen(lpValue) + 1 ) == ERROR_SUCCESS)
441 ret = TRUE;
442 if (hBaseKey == HKEY_CURRENT_USER)
443 RegDeleteKeyA( get_volatile_regkey(), lpRegKey );
445 RegCloseKey( hKey );
447 return ret;
451 /***********************************************************************
452 * SYSPARAMS_GetDoubleClickSize
454 * There is no SPI_GETDOUBLECLK* so we export this function instead.
456 void SYSPARAMS_GetDoubleClickSize( INT *width, INT *height )
458 char buf[10];
460 if (!spi_loaded[SPI_SETDOUBLECLKWIDTH_IDX])
462 char buf[10];
464 if (SYSPARAMS_Load( SPI_SETDOUBLECLKWIDTH_REGKEY1,
465 SPI_SETDOUBLECLKWIDTH_VALNAME, buf, sizeof(buf) ))
467 SYSMETRICS_Set( SM_CXDOUBLECLK, atoi( buf ) );
469 spi_loaded[SPI_SETDOUBLECLKWIDTH_IDX] = TRUE;
471 if (!spi_loaded[SPI_SETDOUBLECLKHEIGHT_IDX])
473 if (SYSPARAMS_Load( SPI_SETDOUBLECLKHEIGHT_REGKEY1,
474 SPI_SETDOUBLECLKHEIGHT_VALNAME, buf, sizeof(buf) ))
476 SYSMETRICS_Set( SM_CYDOUBLECLK, atoi( buf ) );
478 spi_loaded[SPI_SETDOUBLECLKHEIGHT_IDX] = TRUE;
480 *width = GetSystemMetrics( SM_CXDOUBLECLK );
481 *height = GetSystemMetrics( SM_CYDOUBLECLK );
485 /***********************************************************************
486 * SYSPARAMS_GetMouseButtonSwap
488 * There is no SPI_GETMOUSEBUTTONSWAP so we export this function instead.
490 INT SYSPARAMS_GetMouseButtonSwap( void )
492 int spi_idx = SPI_SETMOUSEBUTTONSWAP_IDX;
494 if (!spi_loaded[spi_idx])
496 char buf[5];
498 if (SYSPARAMS_Load( SPI_SETMOUSEBUTTONSWAP_REGKEY,
499 SPI_SETMOUSEBUTTONSWAP_VALNAME, buf, sizeof(buf) ))
501 SYSMETRICS_Set( SM_SWAPBUTTON, atoi( buf ) );
503 spi_loaded[spi_idx] = TRUE;
506 return GetSystemMetrics( SM_SWAPBUTTON );
509 /***********************************************************************
511 * SYSPARAMS_GetGUIFont
513 * fills LOGFONT with 'default GUI font'.
516 static void SYSPARAMS_GetGUIFont( LOGFONTA* plf )
518 HFONT hf;
520 memset( plf, 0, sizeof(LOGFONTA) );
521 hf = (HFONT)GetStockObject( DEFAULT_GUI_FONT );
522 if ( GetObjectA( hf, sizeof(LOGFONTA), plf ) != sizeof(LOGFONTA) )
525 * GetObjectA() would be succeeded always
526 * since this is a stock object
528 ERR("GetObjectA() failed\n");
532 /* copied from GetSystemMetrics()'s RegistryTwips2Pixels() */
533 inline static int SYSPARAMS_Twips2Pixels(int x)
535 if (x < 0)
536 x = (-x+7)/15;
537 return x;
540 /***********************************************************************
541 * SystemParametersInfoA (USER32.@)
543 * Each system parameter has flag which shows whether the parameter
544 * is loaded or not. Parameters, stored directly in SysParametersInfo are
545 * loaded from registry only when they are requested and the flag is
546 * "false", after the loading the flag is set to "true". On interprocess
547 * notification of the parameter change the corresponding parameter flag is
548 * set to "false". The parameter value will be reloaded when it is requested
549 * the next time.
550 * Parameters, backed by or depend on GetSystemMetrics are processed
551 * differently. These parameters are always loaded. They are reloaded right
552 * away on interprocess change notification. We can't do lazy loading because
553 * we don't want to complicate GetSystemMetrics.
554 * Parameters, backed by X settings are read from corresponding setting.
555 * On the parameter change request the setting is changed. Interprocess change
556 * notifications are ignored.
557 * When parameter value is updated the changed value is stored in permanent
558 * registry branch if saving is requested. Otherwise it is stored
559 * in temporary branch
561 * Some SPI values can also be stored as Twips values in the registry,
562 * don't forget the conversion!
564 BOOL WINAPI SystemParametersInfoA( UINT uiAction, UINT uiParam,
565 PVOID pvParam, UINT fWinIni )
567 #define WINE_SPI_FIXME(x) \
568 case x: \
569 FIXME( "Unimplemented action: %u (%s)\n", x, #x ); \
570 SetLastError( ERROR_INVALID_SPI_VALUE ); \
571 ret = FALSE; \
572 break
573 #define WINE_SPI_WARN(x) \
574 case x: \
575 WARN( "Ignored action: %u (%s)\n", x, #x ); \
576 break
578 BOOL ret = TRUE;
579 unsigned spi_idx = 0;
581 TRACE("(%u, %u, %p, %u)\n", uiAction, uiParam, pvParam, fWinIni);
583 switch (uiAction)
585 case SPI_GETBEEP: /* 1 */
586 if (!pvParam) return FALSE;
588 spi_idx = SPI_SETBEEP_IDX;
589 if (!spi_loaded[spi_idx])
591 char buf[5];
593 if (SYSPARAMS_Load( SPI_SETBEEP_REGKEY, SPI_SETBEEP_VALNAME, buf, sizeof(buf) ))
594 beep_active = !strcasecmp( "Yes", buf );
595 spi_loaded[spi_idx] = TRUE;
598 *(BOOL *)pvParam = beep_active;
599 break;
601 case SPI_SETBEEP: /* 2 */
602 spi_idx = SPI_SETBEEP_IDX;
603 if (SYSPARAMS_Save( SPI_SETBEEP_REGKEY, SPI_SETBEEP_VALNAME,
604 (uiParam ? "Yes" : "No"), fWinIni ))
606 beep_active = uiParam;
607 spi_loaded[spi_idx] = TRUE;
609 else
610 ret = FALSE;
611 break;
613 case SPI_GETMOUSE: /* 3 */
614 if (!pvParam) return FALSE;
616 spi_idx = SPI_SETMOUSE_IDX;
617 if (!spi_loaded[spi_idx])
619 char buf[10];
621 if (SYSPARAMS_Load( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME1,
622 buf, sizeof(buf) ))
623 mouse_threshold1 = atoi( buf );
624 if (SYSPARAMS_Load( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME2,
625 buf, sizeof(buf) ))
626 mouse_threshold2 = atoi( buf );
627 if (SYSPARAMS_Load( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME3,
628 buf, sizeof(buf) ))
629 mouse_speed = atoi( buf );
630 spi_loaded[spi_idx] = TRUE;
632 ((INT *)pvParam)[0] = mouse_threshold1;
633 ((INT *)pvParam)[1] = mouse_threshold2;
634 ((INT *)pvParam)[2] = mouse_speed;
635 break;
637 case SPI_SETMOUSE: /* 4 */
639 char buf[10];
641 if (!pvParam) return FALSE;
643 spi_idx = SPI_SETMOUSE_IDX;
644 sprintf(buf, "%d", ((INT *)pvParam)[0]);
646 if (SYSPARAMS_Save( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME1,
647 buf, fWinIni ))
649 mouse_threshold1 = ((INT *)pvParam)[0];
650 spi_loaded[spi_idx] = TRUE;
652 sprintf(buf, "%d", ((INT *)pvParam)[1]);
653 SYSPARAMS_Save( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME2,
654 buf, fWinIni );
655 mouse_threshold2 = ((INT *)pvParam)[1];
657 sprintf(buf, "%d", ((INT *)pvParam)[2]);
658 SYSPARAMS_Save( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME3,
659 buf, fWinIni );
660 mouse_speed = ((INT *)pvParam)[2];
662 else
663 ret = FALSE;
664 break;
667 case SPI_GETBORDER: /* 5 */
668 if (!pvParam) return FALSE;
670 spi_idx = SPI_SETBORDER_IDX;
671 if (!spi_loaded[spi_idx])
673 char buf[10];
675 if (SYSPARAMS_Load( SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME, buf, sizeof(buf) ))
676 border = SYSPARAMS_Twips2Pixels( atoi(buf) );
678 spi_loaded[spi_idx] = TRUE;
679 if (TWEAK_WineLook > WIN31_LOOK)
681 SYSMETRICS_Set( SM_CXFRAME, border + GetSystemMetrics( SM_CXDLGFRAME ) );
682 SYSMETRICS_Set( SM_CYFRAME, border + GetSystemMetrics( SM_CXDLGFRAME ) );
685 *(INT *)pvParam = border;
686 break;
688 case SPI_SETBORDER: /* 6 */
690 char buf[10];
692 spi_idx = SPI_SETBORDER_IDX;
693 sprintf(buf, "%u", uiParam);
695 if (SYSPARAMS_Save( SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME,
696 buf, fWinIni ))
698 if (uiParam > 0)
700 border = uiParam;
701 spi_loaded[spi_idx] = TRUE;
702 if (TWEAK_WineLook > WIN31_LOOK)
704 SYSMETRICS_Set( SM_CXFRAME, uiParam + GetSystemMetrics( SM_CXDLGFRAME ) );
705 SYSMETRICS_Set( SM_CYFRAME, uiParam + GetSystemMetrics( SM_CXDLGFRAME ) );
709 else
710 ret = FALSE;
711 break;
714 case SPI_GETKEYBOARDSPEED: /* 10 */
715 if (!pvParam) return FALSE;
717 spi_idx = SPI_SETKEYBOARDSPEED_IDX;
718 if (!spi_loaded[spi_idx])
720 char buf[10];
722 if (SYSPARAMS_Load( SPI_SETKEYBOARDSPEED_REGKEY,
723 SPI_SETKEYBOARDSPEED_VALNAME,
724 buf, sizeof(buf) ))
725 keyboard_speed = atoi( buf );
726 spi_loaded[spi_idx] = TRUE;
728 *(INT *)pvParam = keyboard_speed;
729 break;
731 case SPI_SETKEYBOARDSPEED: /* 11 */
733 char buf[10];
735 spi_idx = SPI_SETKEYBOARDSPEED_IDX;
736 if (uiParam > 31)
737 uiParam = 31;
738 sprintf(buf, "%u", uiParam);
740 if (SYSPARAMS_Save( SPI_SETKEYBOARDSPEED_REGKEY,
741 SPI_SETKEYBOARDSPEED_VALNAME,
742 buf, fWinIni ))
744 keyboard_speed = uiParam;
745 spi_loaded[spi_idx] = TRUE;
747 else
748 ret = FALSE;
749 break;
752 /* not implemented in Windows */
753 WINE_SPI_WARN(SPI_LANGDRIVER); /* 12 */
755 case SPI_ICONHORIZONTALSPACING: /* 13 */
756 spi_idx = SPI_ICONHORIZONTALSPACING_IDX;
757 if (pvParam != NULL)
759 if (!spi_loaded[spi_idx])
761 char buf[10];
762 int val;
764 if (SYSPARAMS_Load( SPI_ICONHORIZONTALSPACING_REGKEY,
765 SPI_ICONHORIZONTALSPACING_VALNAME, buf, sizeof(buf) ))
767 val = SYSPARAMS_Twips2Pixels( atoi(buf) );
768 SYSMETRICS_Set( SM_CXICONSPACING, val );
770 spi_loaded[spi_idx] = TRUE;
773 *(INT *)pvParam = GetSystemMetrics( SM_CXICONSPACING );
775 else
777 char buf[10];
779 if (uiParam < 32) uiParam = 32;
781 sprintf(buf, "%u", uiParam);
782 if (SYSPARAMS_Save( SPI_ICONHORIZONTALSPACING_REGKEY,
783 SPI_ICONHORIZONTALSPACING_VALNAME,
784 buf, fWinIni ))
786 SYSMETRICS_Set( SM_CXICONSPACING, uiParam );
787 spi_loaded[spi_idx] = TRUE;
789 else
790 ret = FALSE;
792 break;
794 case SPI_GETSCREENSAVETIMEOUT: /* 14 */
795 if (!pvParam) return FALSE;
797 spi_idx = SPI_SETSCREENSAVETIMEOUT_IDX;
798 if (!spi_loaded[spi_idx])
800 char buf[10];
802 if (SYSPARAMS_Load( SPI_SETSCREENSAVETIMEOUT_REGKEY,
803 SPI_SETSCREENSAVETIMEOUT_VALNAME,
804 buf, sizeof(buf) ))
805 screensave_timeout = atoi( buf );
807 spi_loaded[spi_idx] = TRUE;
809 *(INT *)pvParam = screensave_timeout;
810 break;
812 case SPI_SETSCREENSAVETIMEOUT: /* 15 */
814 char buf[10];
816 spi_idx = SPI_SETSCREENSAVETIMEOUT_IDX;
817 sprintf(buf, "%u", uiParam);
819 if (SYSPARAMS_Save( SPI_SETSCREENSAVETIMEOUT_REGKEY,
820 SPI_SETSCREENSAVETIMEOUT_VALNAME,
821 buf, fWinIni ))
823 screensave_timeout = uiParam;
824 spi_loaded[spi_idx] = TRUE;
826 else
827 ret = FALSE;
828 break;
831 case SPI_GETSCREENSAVEACTIVE: /* 16 */
832 if (!pvParam) return FALSE;
833 *(BOOL *)pvParam = USER_Driver.pGetScreenSaveActive();
834 break;
836 case SPI_SETSCREENSAVEACTIVE: /* 17 */
838 char buf[5];
840 sprintf(buf, "%u", uiParam);
841 USER_Driver.pSetScreenSaveActive( uiParam );
842 /* saved value does not affect Wine */
843 SYSPARAMS_Save( SPI_SETSCREENSAVEACTIVE_REGKEY,
844 SPI_SETSCREENSAVEACTIVE_VALNAME,
845 buf, fWinIni );
846 break;
849 case SPI_GETGRIDGRANULARITY: /* 18 */
850 if (!pvParam) return FALSE;
852 spi_idx = SPI_SETGRIDGRANULARITY_IDX;
853 if (!spi_loaded[spi_idx])
855 char buf[10];
857 if (SYSPARAMS_Load( SPI_SETGRIDGRANULARITY_REGKEY,
858 SPI_SETGRIDGRANULARITY_VALNAME,
859 buf, sizeof(buf) ))
860 grid_granularity = atoi( buf );
862 spi_loaded[spi_idx] = TRUE;
864 *(INT *)pvParam = grid_granularity;
865 break;
867 case SPI_SETGRIDGRANULARITY: /* 19 */
869 char buf[10];
871 spi_idx = SPI_SETGRIDGRANULARITY_IDX;
872 sprintf(buf, "%u", uiParam);
874 if (SYSPARAMS_Save( SPI_SETGRIDGRANULARITY_REGKEY,
875 SPI_SETGRIDGRANULARITY_VALNAME,
876 buf, fWinIni ))
878 grid_granularity = uiParam;
879 spi_loaded[spi_idx] = TRUE;
881 else
882 ret = FALSE;
883 break;
886 case SPI_SETDESKWALLPAPER: /* 20 */
887 if (!pvParam || !SetDeskWallPaper( (LPSTR)pvParam )) return FALSE;
888 SYSPARAMS_Save(SPI_SETDESKWALLPAPER_REGKEY, SPI_SETDESKWALLPAPER_VALNAME, pvParam, fWinIni);
889 break;
890 case SPI_SETDESKPATTERN: /* 21 */
891 /* FIXME: the ability to specify a pattern in pvParam
892 doesn't seem to be documented for Win32 */
893 if ((INT16)uiParam == -1)
895 char buffer[256];
896 GetProfileStringA( "Desktop", "Pattern",
897 "170 85 170 85 170 85 170 85",
898 buffer, sizeof(buffer) );
899 ret = DESKTOP_SetPattern( (LPSTR)buffer );
900 } else
901 ret = DESKTOP_SetPattern( (LPSTR)pvParam );
902 break;
904 case SPI_GETKEYBOARDDELAY: /* 22 */
905 if (!pvParam) return FALSE;
907 spi_idx = SPI_SETKEYBOARDDELAY_IDX;
908 if (!spi_loaded[spi_idx])
910 char buf[10];
912 if (SYSPARAMS_Load( SPI_SETKEYBOARDDELAY_REGKEY,
913 SPI_SETKEYBOARDDELAY_VALNAME,
914 buf, sizeof(buf) ))
916 int i = atoi( buf );
917 if ( (i >= 0) && (i <= 3)) keyboard_delay = i;
920 spi_loaded[spi_idx] = TRUE;
922 *(INT *)pvParam = keyboard_delay;
923 break;
925 case SPI_SETKEYBOARDDELAY: /* 23 */
927 char buf[10];
929 spi_idx = SPI_SETKEYBOARDDELAY_IDX;
930 sprintf(buf, "%u", uiParam);
932 if (SYSPARAMS_Save( SPI_SETKEYBOARDDELAY_REGKEY,
933 SPI_SETKEYBOARDDELAY_VALNAME,
934 buf, fWinIni ))
936 if (uiParam <= 3)
937 keyboard_delay = uiParam;
938 spi_loaded[spi_idx] = TRUE;
940 else
941 ret = FALSE;
942 break;
945 case SPI_ICONVERTICALSPACING: /* 24 */
946 spi_idx = SPI_ICONVERTICALSPACING_IDX;
947 if (pvParam != NULL)
949 if (!spi_loaded[spi_idx])
951 char buf[10];
952 int val;
954 if (SYSPARAMS_Load( SPI_ICONVERTICALSPACING_REGKEY,
955 SPI_ICONVERTICALSPACING_VALNAME, buf, sizeof(buf) ))
957 val = SYSPARAMS_Twips2Pixels( atoi(buf) );
958 SYSMETRICS_Set( SM_CYICONSPACING, val );
960 spi_loaded[spi_idx] = TRUE;
963 *(INT *)pvParam = GetSystemMetrics( SM_CYICONSPACING );
965 else
967 char buf[10];
969 if (uiParam < 32) uiParam = 32;
971 sprintf(buf, "%u", uiParam);
972 if (SYSPARAMS_Save( SPI_ICONVERTICALSPACING_REGKEY,
973 SPI_ICONVERTICALSPACING_VALNAME,
974 buf, fWinIni ))
976 SYSMETRICS_Set( SM_CYICONSPACING, uiParam );
977 spi_loaded[spi_idx] = TRUE;
979 else
980 ret = FALSE;
983 break;
985 case SPI_GETICONTITLEWRAP: /* 25 */
986 if (!pvParam) return FALSE;
988 spi_idx = SPI_SETICONTITLEWRAP_IDX;
989 if (!spi_loaded[spi_idx])
991 char buf[5];
993 if (SYSPARAMS_Load( SPI_SETICONTITLEWRAP_REGKEY1,
994 SPI_SETICONTITLEWRAP_VALNAME, buf, sizeof(buf) ))
995 icon_title_wrap = atoi(buf);
996 spi_loaded[spi_idx] = TRUE;
999 *(BOOL *)pvParam = icon_title_wrap;
1000 break;
1002 case SPI_SETICONTITLEWRAP: /* 26 */
1004 char buf[5];
1006 spi_idx = SPI_SETICONTITLEWRAP_IDX;
1007 sprintf(buf, "%u", uiParam);
1008 if (SYSPARAMS_Save( SPI_SETICONTITLEWRAP_REGKEY1,
1009 SPI_SETICONTITLEWRAP_VALNAME,
1010 buf, fWinIni ))
1012 SYSPARAMS_Save( SPI_SETICONTITLEWRAP_REGKEY2,
1013 SPI_SETICONTITLEWRAP_VALNAME,
1014 buf, fWinIni );
1015 icon_title_wrap = uiParam;
1016 spi_loaded[spi_idx] = TRUE;
1018 else
1019 ret = FALSE;
1020 break;
1023 case SPI_GETMENUDROPALIGNMENT: /* 27 */
1024 if (!pvParam) return FALSE;
1026 spi_idx = SPI_SETMENUDROPALIGNMENT_IDX;
1028 if (!spi_loaded[spi_idx])
1030 char buf[5];
1032 if (SYSPARAMS_Load( SPI_SETMENUDROPALIGNMENT_REGKEY1,
1033 SPI_SETMENUDROPALIGNMENT_VALNAME, buf, sizeof(buf) ))
1035 SYSMETRICS_Set( SM_MENUDROPALIGNMENT, atoi( buf ) );
1037 spi_loaded[spi_idx] = TRUE;
1040 *(BOOL *)pvParam = GetSystemMetrics( SM_MENUDROPALIGNMENT );
1041 break;
1043 case SPI_SETMENUDROPALIGNMENT: /* 28 */
1045 char buf[5];
1046 spi_idx = SPI_SETMENUDROPALIGNMENT_IDX;
1048 sprintf(buf, "%u", uiParam);
1049 if (SYSPARAMS_Save( SPI_SETMENUDROPALIGNMENT_REGKEY1,
1050 SPI_SETMENUDROPALIGNMENT_VALNAME,
1051 buf, fWinIni ))
1053 SYSPARAMS_Save( SPI_SETMENUDROPALIGNMENT_REGKEY2,
1054 SPI_SETMENUDROPALIGNMENT_VALNAME,
1055 buf, fWinIni );
1056 SYSMETRICS_Set( SM_MENUDROPALIGNMENT, uiParam );
1057 spi_loaded[spi_idx] = TRUE;
1059 else
1060 ret = FALSE;
1061 break;
1064 case SPI_SETDOUBLECLKWIDTH: /* 29 */
1066 char buf[10];
1067 spi_idx = SPI_SETDOUBLECLKWIDTH_IDX;
1069 sprintf(buf, "%u", uiParam);
1070 if (SYSPARAMS_Save( SPI_SETDOUBLECLKWIDTH_REGKEY1,
1071 SPI_SETDOUBLECLKWIDTH_VALNAME,
1072 buf, fWinIni ))
1074 SYSPARAMS_Save( SPI_SETDOUBLECLKWIDTH_REGKEY2,
1075 SPI_SETDOUBLECLKWIDTH_VALNAME,
1076 buf, fWinIni );
1077 SYSMETRICS_Set( SM_CXDOUBLECLK, uiParam );
1078 spi_loaded[spi_idx] = TRUE;
1080 else
1081 ret = FALSE;
1082 break;
1085 case SPI_SETDOUBLECLKHEIGHT: /* 30 */
1087 char buf[10];
1088 spi_idx = SPI_SETDOUBLECLKHEIGHT_IDX;
1090 sprintf(buf, "%u", uiParam);
1091 if (SYSPARAMS_Save( SPI_SETDOUBLECLKHEIGHT_REGKEY1,
1092 SPI_SETDOUBLECLKHEIGHT_VALNAME,
1093 buf, fWinIni ))
1095 SYSPARAMS_Save( SPI_SETDOUBLECLKHEIGHT_REGKEY2,
1096 SPI_SETDOUBLECLKHEIGHT_VALNAME,
1097 buf, fWinIni );
1098 SYSMETRICS_Set( SM_CYDOUBLECLK, uiParam );
1099 spi_loaded[spi_idx] = TRUE;
1101 else
1102 ret = FALSE;
1103 break;
1106 case SPI_GETICONTITLELOGFONT: /* 31 */
1108 LPLOGFONTA lpLogFont = (LPLOGFONTA)pvParam;
1109 LOGFONTA lfDefault;
1111 if (!pvParam) return FALSE;
1114 * The 'default GDI fonts' seems to be returned.
1115 * If a returned font is not a correct font in your environment,
1116 * please try to fix objects/gdiobj.c at first.
1118 SYSPARAMS_GetGUIFont( &lfDefault );
1120 GetProfileStringA( "Desktop", "IconTitleFaceName",
1121 lfDefault.lfFaceName,
1122 lpLogFont->lfFaceName, LF_FACESIZE );
1123 lpLogFont->lfHeight = -GetProfileIntA( "Desktop", "IconTitleSize", 11 );
1124 lpLogFont->lfWidth = 0;
1125 lpLogFont->lfEscapement = lpLogFont->lfOrientation = 0;
1126 lpLogFont->lfWeight = FW_NORMAL;
1127 lpLogFont->lfItalic = FALSE;
1128 lpLogFont->lfStrikeOut = FALSE;
1129 lpLogFont->lfUnderline = FALSE;
1130 lpLogFont->lfCharSet = lfDefault.lfCharSet; /* at least 'charset' should not be hard-coded */
1131 lpLogFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
1132 lpLogFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
1133 lpLogFont->lfPitchAndFamily = DEFAULT_PITCH;
1134 lpLogFont->lfQuality = DEFAULT_QUALITY;
1135 break;
1138 case SPI_SETDOUBLECLICKTIME: /* 32 */
1140 char buf[10];
1142 spi_idx = SPI_SETDOUBLECLICKTIME_IDX;
1143 sprintf(buf, "%u", uiParam);
1145 if (SYSPARAMS_Save( SPI_SETDOUBLECLICKTIME_REGKEY,
1146 SPI_SETDOUBLECLICKTIME_VALNAME,
1147 buf, fWinIni ))
1149 if (!uiParam)
1150 uiParam = 500;
1151 double_click_time = uiParam;
1152 spi_loaded[spi_idx] = TRUE;
1154 else
1155 ret = FALSE;
1156 break;
1159 case SPI_SETMOUSEBUTTONSWAP: /* 33 */
1161 char buf[5];
1162 spi_idx = SPI_SETMOUSEBUTTONSWAP_IDX;
1164 sprintf(buf, "%u", uiParam);
1165 if (SYSPARAMS_Save( SPI_SETMOUSEBUTTONSWAP_REGKEY,
1166 SPI_SETMOUSEBUTTONSWAP_VALNAME,
1167 buf, fWinIni ))
1169 SYSMETRICS_Set( SM_SWAPBUTTON, uiParam );
1170 spi_loaded[spi_idx] = TRUE;
1172 else
1173 ret = FALSE;
1174 break;
1177 WINE_SPI_FIXME(SPI_SETICONTITLELOGFONT); /* 34 */
1179 case SPI_GETFASTTASKSWITCH: /* 35 */
1180 if (!pvParam) return FALSE;
1181 *(BOOL *)pvParam = 1;
1182 break;
1184 case SPI_SETFASTTASKSWITCH: /* 36 */
1185 /* the action is disabled */
1186 ret = FALSE;
1187 break;
1189 case SPI_SETDRAGFULLWINDOWS: /* 37 WINVER >= 0x0400 */
1191 char buf[5];
1193 spi_idx = SPI_SETDRAGFULLWINDOWS_IDX;
1194 sprintf(buf, "%u", uiParam);
1195 if (SYSPARAMS_Save( SPI_SETDRAGFULLWINDOWS_REGKEY,
1196 SPI_SETDRAGFULLWINDOWS_VALNAME,
1197 buf, fWinIni ))
1199 drag_full_windows = uiParam;
1200 spi_loaded[spi_idx] = TRUE;
1202 else
1203 ret = FALSE;
1204 break;
1207 case SPI_GETDRAGFULLWINDOWS: /* 38 WINVER >= 0x0400 */
1208 if (!pvParam) return FALSE;
1210 spi_idx = SPI_SETDRAGFULLWINDOWS_IDX;
1211 if (!spi_loaded[spi_idx])
1213 char buf[5];
1215 if (SYSPARAMS_Load( SPI_SETDRAGFULLWINDOWS_REGKEY,
1216 SPI_SETDRAGFULLWINDOWS_VALNAME, buf, sizeof(buf) ))
1217 drag_full_windows = atoi(buf);
1218 spi_loaded[spi_idx] = TRUE;
1221 *(BOOL *)pvParam = drag_full_windows;
1222 break;
1224 case SPI_GETNONCLIENTMETRICS: /* 41 WINVER >= 0x400 */
1226 LPNONCLIENTMETRICSA lpnm = (LPNONCLIENTMETRICSA)pvParam;
1228 if (!pvParam) return FALSE;
1230 if (lpnm->cbSize == sizeof(NONCLIENTMETRICSA))
1232 /* clear the struct, so we have 'sane' members */
1233 memset(
1234 (char *)pvParam + sizeof(lpnm->cbSize),
1236 lpnm->cbSize - sizeof(lpnm->cbSize)
1239 /* initialize geometry entries */
1240 lpnm->iBorderWidth = 1;
1241 lpnm->iScrollWidth = GetSystemMetrics(SM_CXVSCROLL);
1242 lpnm->iScrollHeight = GetSystemMetrics(SM_CYHSCROLL);
1244 /* size of the normal caption buttons */
1245 lpnm->iCaptionWidth = GetSystemMetrics(SM_CXSIZE);
1246 lpnm->iCaptionHeight = GetSystemMetrics(SM_CYSIZE);
1248 /* caption font metrics */
1249 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0, (LPVOID)&(lpnm->lfCaptionFont), 0 );
1250 lpnm->lfCaptionFont.lfWeight = FW_BOLD;
1252 /* size of the small caption buttons */
1253 lpnm->iSmCaptionWidth = GetSystemMetrics(SM_CXSMSIZE);
1254 lpnm->iSmCaptionHeight = GetSystemMetrics(SM_CYSMSIZE);
1256 /* small caption font metrics */
1257 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0, (LPVOID)&(lpnm->lfSmCaptionFont), 0 );
1259 /* menus, FIXME: names of wine.conf entries are bogus */
1261 /* size of the menu (MDI) buttons */
1262 lpnm->iMenuWidth = GetSystemMetrics(SM_CXMENUSIZE);
1263 lpnm->iMenuHeight = GetSystemMetrics(SM_CYMENUSIZE);
1265 /* menu font metrics */
1266 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0, (LPVOID)&(lpnm->lfMenuFont), 0 );
1267 GetProfileStringA( "Desktop", "MenuFont",
1268 (TWEAK_WineLook > WIN31_LOOK) ? lpnm->lfCaptionFont.lfFaceName : "System",
1269 lpnm->lfMenuFont.lfFaceName, LF_FACESIZE );
1270 lpnm->lfMenuFont.lfHeight = -GetProfileIntA( "Desktop", "MenuFontSize", 11 );
1271 lpnm->lfMenuFont.lfWeight = (TWEAK_WineLook > WIN31_LOOK) ? FW_NORMAL : FW_BOLD;
1273 /* status bar font metrics */
1274 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0,
1275 (LPVOID)&(lpnm->lfStatusFont), 0 );
1276 /* message font metrics */
1277 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0,
1278 (LPVOID)&(lpnm->lfMessageFont), 0 );
1280 else
1282 WARN("size mismatch !! (is %d; should be %d)\n", lpnm->cbSize, sizeof(NONCLIENTMETRICSA));
1283 /* FIXME: SetLastError? */
1284 ret = FALSE;
1286 break;
1288 WINE_SPI_FIXME(SPI_SETNONCLIENTMETRICS); /* 42 WINVER >= 0x400 */
1290 case SPI_GETMINIMIZEDMETRICS: /* 43 WINVER >= 0x400 */
1292 MINIMIZEDMETRICS * lpMm = pvParam;
1293 if (lpMm && lpMm->cbSize == sizeof(*lpMm))
1295 /* these taken from Win2k SP3 */
1296 lpMm->iWidth = 154;
1297 lpMm->iHorzGap = 0;
1298 lpMm->iVertGap = 0;
1299 lpMm->iArrange = 8;
1301 else
1302 ret = FALSE;
1303 break;
1305 WINE_SPI_FIXME(SPI_SETMINIMIZEDMETRICS); /* 44 WINVER >= 0x400 */
1307 case SPI_GETICONMETRICS: /* 45 WINVER >= 0x400 */
1309 LPICONMETRICSA lpIcon = pvParam;
1310 if(lpIcon && lpIcon->cbSize == sizeof(*lpIcon))
1312 SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0,
1313 &lpIcon->iHorzSpacing, FALSE );
1314 SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0,
1315 &lpIcon->iVertSpacing, FALSE );
1316 SystemParametersInfoA( SPI_GETICONTITLEWRAP, 0,
1317 &lpIcon->iTitleWrap, FALSE );
1318 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0,
1319 &lpIcon->lfFont, FALSE );
1321 else
1323 ret = FALSE;
1325 break;
1327 WINE_SPI_FIXME(SPI_SETICONMETRICS); /* 46 WINVER >= 0x400 */
1329 case SPI_SETWORKAREA: /* 47 WINVER >= 0x400 */
1331 char buf[20];
1332 RECT *pr = (RECT *) pvParam;
1334 if (!pvParam) return FALSE;
1336 spi_idx = SPI_SETWORKAREA_IDX;
1337 sprintf(buf, "%ld %ld %ld %ld",
1338 pr->left, pr->top,
1339 pr->right, pr->bottom );
1341 if (SYSPARAMS_Save( SPI_SETWORKAREA_REGKEY,
1342 SPI_SETWORKAREA_VALNAME,
1343 buf, fWinIni ))
1345 CopyRect( &work_area, (RECT *)pvParam );
1346 spi_loaded[spi_idx] = TRUE;
1348 else
1349 ret = FALSE;
1350 break;
1353 case SPI_GETWORKAREA: /* 48 WINVER >= 0x400 */
1354 if (!pvParam) return FALSE;
1356 spi_idx = SPI_SETWORKAREA_IDX;
1357 if (!spi_loaded[spi_idx])
1359 char buf[20];
1361 SetRect( &work_area, 0, 0,
1362 GetSystemMetrics( SM_CXSCREEN ),
1363 GetSystemMetrics( SM_CYSCREEN ) );
1365 if (SYSPARAMS_Load( SPI_SETWORKAREA_REGKEY,
1366 SPI_SETWORKAREA_VALNAME,
1367 buf, sizeof(buf) ))
1369 sscanf( buf, "%ld %ld %ld %ld",
1370 &work_area.left, &work_area.top,
1371 &work_area.right, &work_area.bottom );
1373 spi_loaded[spi_idx] = TRUE;
1375 CopyRect( (RECT *)pvParam, &work_area );
1377 break;
1379 WINE_SPI_FIXME(SPI_SETPENWINDOWS); /* 49 WINVER >= 0x400 */
1381 case SPI_GETFILTERKEYS: /* 50 */
1383 LPFILTERKEYS lpFilterKeys = (LPFILTERKEYS)pvParam;
1384 WARN("SPI_GETFILTERKEYS not fully implemented\n");
1385 if (lpFilterKeys && lpFilterKeys->cbSize == sizeof(FILTERKEYS))
1387 /* Indicate that no FilterKeys feature available */
1388 lpFilterKeys->dwFlags = 0;
1389 lpFilterKeys->iWaitMSec = 0;
1390 lpFilterKeys->iDelayMSec = 0;
1391 lpFilterKeys->iRepeatMSec = 0;
1392 lpFilterKeys->iBounceMSec = 0;
1394 else
1396 ret = FALSE;
1398 break;
1400 WINE_SPI_FIXME(SPI_SETFILTERKEYS); /* 51 */
1402 case SPI_GETTOGGLEKEYS: /* 52 */
1404 LPTOGGLEKEYS lpToggleKeys = (LPTOGGLEKEYS)pvParam;
1405 WARN("SPI_GETTOGGLEKEYS not fully implemented\n");
1406 if (lpToggleKeys && lpToggleKeys->cbSize == sizeof(TOGGLEKEYS))
1408 /* Indicate that no ToggleKeys feature available */
1409 lpToggleKeys->dwFlags = 0;
1411 else
1413 ret = FALSE;
1415 break;
1417 WINE_SPI_FIXME(SPI_SETTOGGLEKEYS); /* 53 */
1419 case SPI_GETMOUSEKEYS: /* 54 */
1421 LPMOUSEKEYS lpMouseKeys = (LPMOUSEKEYS)pvParam;
1422 WARN("SPI_GETMOUSEKEYS not fully implemented\n");
1423 if (lpMouseKeys && lpMouseKeys->cbSize == sizeof(MOUSEKEYS))
1425 /* Indicate that no MouseKeys feature available */
1426 lpMouseKeys->dwFlags = 0;
1427 lpMouseKeys->iMaxSpeed = 360;
1428 lpMouseKeys->iTimeToMaxSpeed = 1000;
1429 lpMouseKeys->iCtrlSpeed = 0;
1430 lpMouseKeys->dwReserved1 = 0;
1431 lpMouseKeys->dwReserved2 = 0;
1433 else
1435 ret = FALSE;
1437 break;
1439 WINE_SPI_FIXME(SPI_SETMOUSEKEYS); /* 55 */
1441 case SPI_GETSHOWSOUNDS: /* 56 */
1442 if (!pvParam) return FALSE;
1444 spi_idx = SPI_SETSHOWSOUNDS_IDX;
1446 if (!spi_loaded[spi_idx])
1448 char buf[10];
1450 if (SYSPARAMS_Load( SPI_SETSHOWSOUNDS_REGKEY,
1451 SPI_SETSHOWSOUNDS_VALNAME, buf, sizeof(buf) ))
1453 SYSMETRICS_Set( SM_SHOWSOUNDS, atoi( buf ) );
1455 spi_loaded[spi_idx] = TRUE;
1458 *(INT *)pvParam = GetSystemMetrics( SM_SHOWSOUNDS );
1459 break;
1461 case SPI_SETSHOWSOUNDS: /* 57 */
1463 char buf[10];
1464 spi_idx = SPI_SETSHOWSOUNDS_IDX;
1466 sprintf(buf, "%u", uiParam);
1467 if (SYSPARAMS_Save( SPI_SETSHOWSOUNDS_REGKEY,
1468 SPI_SETSHOWSOUNDS_VALNAME,
1469 buf, fWinIni ))
1471 SYSMETRICS_Set( SM_SHOWSOUNDS, uiParam );
1472 spi_loaded[spi_idx] = TRUE;
1474 else
1475 ret = FALSE;
1476 break;
1479 case SPI_GETSTICKYKEYS: /* 58 */
1481 LPSTICKYKEYS lpStickyKeys = (LPSTICKYKEYS)pvParam;
1482 WARN("SPI_GETSTICKYKEYS not fully implemented\n");
1483 if (lpStickyKeys && lpStickyKeys->cbSize == sizeof(STICKYKEYS))
1485 /* Indicate that no StickyKeys feature available */
1486 lpStickyKeys->dwFlags = 0;
1488 else
1490 ret = FALSE;
1492 break;
1494 WINE_SPI_FIXME(SPI_SETSTICKYKEYS); /* 59 */
1496 case SPI_GETACCESSTIMEOUT: /* 60 */
1498 LPACCESSTIMEOUT lpAccessTimeout = (LPACCESSTIMEOUT)pvParam;
1499 WARN("SPI_GETACCESSTIMEOUT not fully implemented\n");
1500 if (lpAccessTimeout && lpAccessTimeout->cbSize == sizeof(ACCESSTIMEOUT))
1502 /* Indicate that no accessibility features timeout is available */
1503 lpAccessTimeout->dwFlags = 0;
1504 lpAccessTimeout->iTimeOutMSec = 0;
1506 else
1508 ret = FALSE;
1510 break;
1512 WINE_SPI_FIXME(SPI_SETACCESSTIMEOUT); /* 61 */
1514 case SPI_GETSERIALKEYS: /* 62 WINVER >= 0x400 */
1516 LPSERIALKEYSA lpSerialKeysA = (LPSERIALKEYSA)pvParam;
1517 WARN("SPI_GETSERIALKEYS not fully implemented\n");
1518 if (lpSerialKeysA && lpSerialKeysA->cbSize == sizeof(SERIALKEYSA))
1520 /* Indicate that no SerialKeys feature available */
1521 lpSerialKeysA->dwFlags = 0;
1522 lpSerialKeysA->lpszActivePort = NULL;
1523 lpSerialKeysA->lpszPort = NULL;
1524 lpSerialKeysA->iBaudRate = 0;
1525 lpSerialKeysA->iPortState = 0;
1527 else
1529 ret = FALSE;
1531 break;
1533 WINE_SPI_FIXME(SPI_SETSERIALKEYS); /* 63 WINVER >= 0x400 */
1535 case SPI_GETSOUNDSENTRY: /* 64 */
1537 LPSOUNDSENTRYA lpSoundSentryA = (LPSOUNDSENTRYA)pvParam;
1538 WARN("SPI_GETSOUNDSENTRY not fully implemented\n");
1539 if (lpSoundSentryA && lpSoundSentryA->cbSize == sizeof(SOUNDSENTRYA))
1541 /* Indicate that no SoundSentry feature available */
1542 lpSoundSentryA->dwFlags = 0;
1543 lpSoundSentryA->iFSTextEffect = 0;
1544 lpSoundSentryA->iFSTextEffectMSec = 0;
1545 lpSoundSentryA->iFSTextEffectColorBits = 0;
1546 lpSoundSentryA->iFSGrafEffect = 0;
1547 lpSoundSentryA->iFSGrafEffectMSec = 0;
1548 lpSoundSentryA->iFSGrafEffectColor = 0;
1549 lpSoundSentryA->iWindowsEffect = 0;
1550 lpSoundSentryA->iWindowsEffectMSec = 0;
1551 lpSoundSentryA->lpszWindowsEffectDLL = 0;
1552 lpSoundSentryA->iWindowsEffectOrdinal = 0;
1554 else
1556 ret = FALSE;
1558 break;
1560 WINE_SPI_FIXME(SPI_SETSOUNDSENTRY); /* 65 */
1562 case SPI_GETHIGHCONTRAST: /* 66 WINVER >= 0x400 */
1564 LPHIGHCONTRASTA lpHighContrastA = (LPHIGHCONTRASTA)pvParam;
1565 WARN("SPI_GETHIGHCONTRAST not fully implemented\n");
1566 if (lpHighContrastA && lpHighContrastA->cbSize == sizeof(HIGHCONTRASTA))
1568 /* Indicate that no high contrast feature available */
1569 lpHighContrastA->dwFlags = 0;
1570 lpHighContrastA->lpszDefaultScheme = NULL;
1572 else
1574 ret = FALSE;
1576 break;
1578 WINE_SPI_FIXME(SPI_SETHIGHCONTRAST); /* 67 WINVER >= 0x400 */
1580 case SPI_GETKEYBOARDPREF: /* 68 WINVER >= 0x400 */
1581 if (!pvParam) return FALSE;
1583 spi_idx = SPI_SETKEYBOARDPREF_IDX;
1584 if (!spi_loaded[spi_idx])
1586 char buf[5];
1588 if (SYSPARAMS_Load( SPI_SETKEYBOARDPREF_REGKEY,
1589 SPI_SETKEYBOARDPREF_VALNAME, buf, sizeof(buf) ))
1590 keyboard_pref = atoi(buf);
1591 spi_loaded[spi_idx] = TRUE;
1594 *(BOOL *)pvParam = keyboard_pref;
1595 break;
1597 case SPI_SETKEYBOARDPREF: /* 69 WINVER >= 0x400 */
1599 char buf[5];
1601 spi_idx = SPI_SETKEYBOARDPREF_IDX;
1602 sprintf(buf, "%u", uiParam);
1603 if (SYSPARAMS_Save( SPI_SETKEYBOARDPREF_REGKEY,
1604 SPI_SETKEYBOARDPREF_VALNAME,
1605 buf, fWinIni ))
1607 keyboard_pref = uiParam;
1608 spi_loaded[spi_idx] = TRUE;
1610 else
1611 ret = FALSE;
1612 break;
1615 case SPI_GETSCREENREADER: /* 70 WINVER >= 0x400 */
1616 if (!pvParam) return FALSE;
1618 spi_idx = SPI_SETSCREENREADER_IDX;
1619 if (!spi_loaded[spi_idx])
1621 char buf[5];
1623 if (SYSPARAMS_Load( SPI_SETSCREENREADER_REGKEY,
1624 SPI_SETSCREENREADER_VALNAME, buf, sizeof(buf) ))
1625 screen_reader = atoi(buf);
1626 spi_loaded[spi_idx] = TRUE;
1629 *(BOOL *)pvParam = screen_reader;
1630 break;
1632 case SPI_SETSCREENREADER: /* 71 WINVER >= 0x400 */
1634 char buf[5];
1636 spi_idx = SPI_SETSCREENREADER_IDX;
1637 sprintf(buf, "%u", uiParam);
1638 if (SYSPARAMS_Save( SPI_SETSCREENREADER_REGKEY,
1639 SPI_SETSCREENREADER_VALNAME,
1640 buf, fWinIni ))
1642 screen_reader = uiParam;
1643 spi_loaded[spi_idx] = TRUE;
1645 else
1646 ret = FALSE;
1647 break;
1650 case SPI_GETANIMATION: /* 72 WINVER >= 0x400 */
1652 LPANIMATIONINFO lpAnimInfo = (LPANIMATIONINFO)pvParam;
1654 /* Tell it "disabled" */
1655 if (lpAnimInfo && lpAnimInfo->cbSize == sizeof(ANIMATIONINFO))
1656 lpAnimInfo->iMinAnimate = 0; /* Minimise and restore animation is disabled (nonzero == enabled) */
1657 else
1658 ret = FALSE;
1659 break;
1661 WINE_SPI_WARN(SPI_SETANIMATION); /* 73 WINVER >= 0x400 */
1663 case SPI_GETFONTSMOOTHING: /* 74 WINVER >= 0x400 */
1664 if (!pvParam) return FALSE;
1666 spi_idx = SPI_SETFONTSMOOTHING_IDX;
1667 if (!spi_loaded[spi_idx])
1669 char buf[5];
1671 if (SYSPARAMS_Load( SPI_SETFONTSMOOTHING_REGKEY,
1672 SPI_SETFONTSMOOTHING_VALNAME, buf, sizeof(buf) ))
1674 spi_loaded[spi_idx] = TRUE;
1675 if (buf[0] == 0x01 || buf[0] == 0x02) /* 0x01 for 95/98/NT, 0x02 for 98/ME/2k/XP */
1677 font_smoothing = TRUE;
1682 *(BOOL *)pvParam = font_smoothing;
1684 break;
1686 WINE_SPI_FIXME(SPI_SETFONTSMOOTHING); /* 75 WINVER >= 0x400 */
1688 WINE_SPI_FIXME(SPI_SETDRAGWIDTH); /* 76 WINVER >= 0x400 */
1689 WINE_SPI_FIXME(SPI_SETDRAGHEIGHT); /* 77 WINVER >= 0x400 */
1691 WINE_SPI_FIXME(SPI_SETHANDHELD); /* 78 WINVER >= 0x400 */
1693 WINE_SPI_FIXME(SPI_GETLOWPOWERTIMEOUT); /* 79 WINVER >= 0x400 */
1694 WINE_SPI_FIXME(SPI_GETPOWEROFFTIMEOUT); /* 80 WINVER >= 0x400 */
1695 WINE_SPI_FIXME(SPI_SETLOWPOWERTIMEOUT); /* 81 WINVER >= 0x400 */
1696 WINE_SPI_FIXME(SPI_SETPOWEROFFTIMEOUT); /* 82 WINVER >= 0x400 */
1697 WINE_SPI_FIXME(SPI_GETLOWPOWERACTIVE); /* 83 WINVER >= 0x400 */
1698 WINE_SPI_FIXME(SPI_GETPOWEROFFACTIVE); /* 84 WINVER >= 0x400 */
1699 WINE_SPI_FIXME(SPI_SETLOWPOWERACTIVE); /* 85 WINVER >= 0x400 */
1700 WINE_SPI_FIXME(SPI_SETPOWEROFFACTIVE); /* 86 WINVER >= 0x400 */
1702 WINE_SPI_FIXME(SPI_SETCURSORS); /* 87 WINVER >= 0x400 */
1703 WINE_SPI_FIXME(SPI_SETICONS); /* 88 WINVER >= 0x400 */
1705 case SPI_GETDEFAULTINPUTLANG: /* 89 WINVER >= 0x400 */
1706 ret = GetKeyboardLayout(0) ? TRUE : FALSE;
1707 break;
1709 WINE_SPI_FIXME(SPI_SETDEFAULTINPUTLANG); /* 90 WINVER >= 0x400 */
1711 WINE_SPI_FIXME(SPI_SETLANGTOGGLE); /* 91 WINVER >= 0x400 */
1713 case SPI_GETWINDOWSEXTENSION: /* 92 WINVER >= 0x400 */
1714 WARN("pretend no support for Win9x Plus! for now.\n");
1715 ret = FALSE; /* yes, this is the result value */
1716 break;
1718 WINE_SPI_FIXME(SPI_SETMOUSETRAILS); /* 93 WINVER >= 0x400 */
1719 WINE_SPI_FIXME(SPI_GETMOUSETRAILS); /* 94 WINVER >= 0x400 */
1721 case SPI_SETSCREENSAVERRUNNING: /* 97 WINVER >= 0x400 */
1723 /* SPI_SCREENSAVERRUNNING is an alias for SPI_SETSCREENSAVERRUNNING */
1724 char buf[5];
1726 spi_idx = SPI_SETSCREENSAVERRUNNING_IDX;
1727 sprintf(buf, "%u", uiParam);
1729 /* save only temporarily */
1730 if (SYSPARAMS_Save( SPI_SETSCREENSAVERRUNNING_REGKEY,
1731 SPI_SETSCREENSAVERRUNNING_VALNAME,
1732 buf, 0 ))
1734 screensaver_running = uiParam;
1735 spi_loaded[spi_idx] = TRUE;
1737 else
1738 ret = FALSE;
1739 break;
1742 case SPI_GETMOUSEHOVERWIDTH: /* 98 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1743 if (!pvParam) return FALSE;
1744 *(UINT *)pvParam = 4;
1745 break;
1746 WINE_SPI_FIXME(SPI_SETMOUSEHOVERWIDTH); /* 99 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1748 case SPI_GETMOUSEHOVERHEIGHT: /* 100 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1749 if (!pvParam) return FALSE;
1750 *(UINT *)pvParam = 4;
1751 break;
1752 WINE_SPI_FIXME(SPI_SETMOUSEHOVERHEIGHT); /* 101 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1754 case SPI_GETMOUSEHOVERTIME: /* 102 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1755 if (!pvParam) return FALSE;
1756 *(UINT *)pvParam = 400; /* default for menu dropdowns */
1757 break;
1758 WINE_SPI_FIXME(SPI_SETMOUSEHOVERTIME); /* 103 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1760 case SPI_GETWHEELSCROLLLINES: /* 104 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1761 if (!pvParam) return FALSE;
1762 *(UINT *)pvParam = 3; /* default for num scroll lines */
1763 break;
1765 WINE_SPI_FIXME(SPI_SETWHEELSCROLLLINES); /* 105 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1767 case SPI_GETMENUSHOWDELAY: /* 106 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1768 if (!pvParam) return FALSE;
1769 *(UINT *)pvParam = 400; /* Tested against Windows NT 4.0 and Windows 2000 */
1770 break;
1772 WINE_SPI_FIXME(SPI_GETSHOWIMEUI); /* 110 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1773 WINE_SPI_FIXME(SPI_SETSHOWIMEUI); /* 111 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1775 case SPI_GETSCREENSAVERRUNNING: /* 114 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1776 if (!pvParam) return FALSE;
1778 spi_idx = SPI_SETSCREENSAVERRUNNING_IDX;
1779 if (!spi_loaded[spi_idx])
1781 char buf[5];
1783 if (SYSPARAMS_Load( SPI_SETSCREENSAVERRUNNING_REGKEY,
1784 SPI_SETSCREENSAVERRUNNING_VALNAME, buf, sizeof(buf) ))
1785 screensaver_running = atoi( buf );
1786 spi_loaded[spi_idx] = TRUE;
1789 *(BOOL *)pvParam = screensaver_running;
1790 break;
1792 case SPI_GETDESKWALLPAPER: /* 115 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1794 char buf[MAX_PATH];
1796 if (!pvParam) return FALSE;
1798 if (uiParam > MAX_PATH)
1800 uiParam = MAX_PATH;
1803 if (SYSPARAMS_Load(SPI_SETDESKWALLPAPER_REGKEY, SPI_SETDESKWALLPAPER_VALNAME, buf, sizeof(buf)))
1805 strncpy((char*)pvParam, buf, uiParam);
1807 else
1809 /* Return an empty string */
1810 memset((char*)pvParam, 0, uiParam);
1813 break;
1816 WINE_SPI_FIXME(SPI_GETACTIVEWINDOWTRACKING);/* 0x1000 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1817 WINE_SPI_FIXME(SPI_SETACTIVEWINDOWTRACKING);/* 0x1001 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1818 WINE_SPI_FIXME(SPI_GETMENUANIMATION); /* 0x1002 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1819 WINE_SPI_FIXME(SPI_SETMENUANIMATION); /* 0x1003 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1820 WINE_SPI_FIXME(SPI_GETCOMBOBOXANIMATION); /* 0x1004 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1821 WINE_SPI_FIXME(SPI_SETCOMBOBOXANIMATION); /* 0x1005 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1823 case SPI_GETLISTBOXSMOOTHSCROLLING: /* 0x1006 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1824 if (!pvParam) return FALSE;
1826 spi_idx = SPI_SETLISTBOXSMOOTHSCROLLING_IDX;
1827 if (!spi_loaded[spi_idx])
1829 char buf[5];
1831 if (SYSPARAMS_Load( SPI_SETLISTBOXSMOOTHSCROLLING_REGKEY,
1832 SPI_SETLISTBOXSMOOTHSCROLLING_VALNAME, buf, sizeof(buf) ))
1834 if ((buf[0]&0x01) == 0x01)
1836 listbox_smoothscrolling = TRUE;
1839 spi_loaded[spi_idx] = TRUE;
1842 *(BOOL *)pvParam = listbox_smoothscrolling;
1844 break;
1846 WINE_SPI_FIXME(SPI_SETLISTBOXSMOOTHSCROLLING);/* 0x1007 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1848 case SPI_GETGRADIENTCAPTIONS: /* 0x1008 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1849 if (!pvParam) return FALSE;
1851 spi_idx = SPI_SETGRADIENTCAPTIONS_IDX;
1852 if (!spi_loaded[spi_idx])
1854 char buf[5];
1856 if (SYSPARAMS_Load( SPI_USERPREFERENCEMASK_REGKEY,
1857 SPI_USERPREFERENCEMASK_VALNAME, buf, sizeof(buf) ))
1859 if ((buf[0]&0x10) == 0x10)
1861 gradient_captions = TRUE;
1864 spi_loaded[spi_idx] = TRUE;
1867 *(BOOL *)pvParam = gradient_captions;
1869 break;
1871 WINE_SPI_FIXME(SPI_SETGRADIENTCAPTIONS); /* 0x1009 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1873 case SPI_GETKEYBOARDCUES: /* 0x100A _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1874 if (!pvParam) return FALSE;
1876 spi_idx = SPI_SETKEYBOARDCUES_IDX;
1877 if (!spi_loaded[spi_idx])
1879 char buf[5];
1881 if (SYSPARAMS_Load( SPI_USERPREFERENCEMASK_REGKEY,
1882 SPI_USERPREFERENCEMASK_VALNAME, buf, sizeof(buf) ))
1884 if ((buf[0]&0x20) == 0x20)
1886 keyboard_cues = TRUE;
1889 spi_loaded[spi_idx] = TRUE;
1892 *(BOOL *)pvParam = keyboard_cues;
1894 break;
1896 WINE_SPI_FIXME(SPI_SETKEYBOARDCUES); /* 0x100B _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1897 WINE_SPI_FIXME(SPI_GETACTIVEWNDTRKZORDER); /* 0x100C _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1898 WINE_SPI_FIXME(SPI_SETACTIVEWNDTRKZORDER); /* 0x100D _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1899 case SPI_GETHOTTRACKING: /* 0x100E _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1900 if (!pvParam) return FALSE;
1902 spi_idx = SPI_SETHOTTRACKING_IDX;
1903 if (!spi_loaded[spi_idx])
1905 char buf[5];
1907 if (SYSPARAMS_Load( SPI_USERPREFERENCEMASK_REGKEY,
1908 SPI_USERPREFERENCEMASK_VALNAME, buf, sizeof(buf) ))
1910 if ((buf[0]&0x80) == 0x80)
1912 hot_tracking = TRUE;
1915 spi_loaded[spi_idx] = TRUE;
1918 *(BOOL *)pvParam = hot_tracking;
1920 break;
1922 WINE_SPI_FIXME(SPI_SETHOTTRACKING); /* 0x100F _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1923 WINE_SPI_FIXME(SPI_GETSELECTIONFADE); /* 0x1014 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1924 WINE_SPI_FIXME(SPI_SETSELECTIONFADE); /* 0x1015 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1925 WINE_SPI_FIXME(SPI_GETDROPSHADOW); /* 0x1024 _WIN32_WINNT >= 0x510 */
1926 WINE_SPI_FIXME(SPI_SETDROPSHADOW); /* 0x1025 _WIN32_WINNT >= 0x510 */
1927 WINE_SPI_FIXME(SPI_GETFOREGROUNDLOCKTIMEOUT);/* 0x2000 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1928 WINE_SPI_FIXME(SPI_SETFOREGROUNDLOCKTIMEOUT);/* 0x2001 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1929 WINE_SPI_FIXME(SPI_GETACTIVEWNDTRKTIMEOUT); /* 0x2002 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1930 WINE_SPI_FIXME(SPI_SETACTIVEWNDTRKTIMEOUT); /* 0x2003 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1931 WINE_SPI_FIXME(SPI_GETFOREGROUNDFLASHCOUNT);/* 0x2004 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1932 WINE_SPI_FIXME(SPI_SETFOREGROUNDFLASHCOUNT);/* 0x2005 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1934 default:
1935 FIXME( "Unknown action: %u\n", uiAction );
1936 SetLastError( ERROR_INVALID_SPI_VALUE );
1937 ret = FALSE;
1938 break;
1941 if (ret)
1942 SYSPARAMS_NotifyChange( uiAction, fWinIni );
1943 return ret;
1945 #undef WINE_SPI_FIXME
1946 #undef WINE_SPI_WARN
1950 /***********************************************************************
1951 * SystemParametersInfo (USER.483)
1953 BOOL16 WINAPI SystemParametersInfo16( UINT16 uAction, UINT16 uParam,
1954 LPVOID lpvParam, UINT16 fuWinIni )
1956 BOOL16 ret;
1958 TRACE("(%u, %u, %p, %u)\n", uAction, uParam, lpvParam, fuWinIni);
1960 switch (uAction)
1962 case SPI_GETBEEP: /* 1 */
1963 case SPI_GETSCREENSAVEACTIVE: /* 16 */
1964 case SPI_GETICONTITLEWRAP: /* 25 */
1965 case SPI_GETMENUDROPALIGNMENT: /* 27 */
1966 case SPI_GETFASTTASKSWITCH: /* 35 */
1967 case SPI_GETDRAGFULLWINDOWS: /* 38 WINVER >= 0x0400 */
1969 BOOL tmp;
1970 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1971 if (ret && lpvParam)
1972 *(BOOL16 *)lpvParam = tmp;
1973 break;
1976 case SPI_GETBORDER: /* 5 */
1977 case SPI_ICONHORIZONTALSPACING: /* 13 */
1978 case SPI_GETSCREENSAVETIMEOUT: /* 14 */
1979 case SPI_GETGRIDGRANULARITY: /* 18 */
1980 case SPI_GETKEYBOARDDELAY: /* 22 */
1981 case SPI_ICONVERTICALSPACING: /* 24 */
1983 INT tmp;
1984 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1985 if (ret && lpvParam)
1986 *(INT16 *)lpvParam = tmp;
1987 break;
1990 case SPI_GETKEYBOARDSPEED: /* 10 */
1992 DWORD tmp;
1993 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1994 if (ret && lpvParam)
1995 *(WORD *)lpvParam = tmp;
1996 break;
1999 case SPI_GETICONTITLELOGFONT: /* 31 */
2001 LOGFONTA tmp;
2002 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
2003 if (ret && lpvParam)
2004 SYSPARAMS_LogFont32ATo16( &tmp, (LPLOGFONT16)lpvParam );
2005 break;
2008 case SPI_GETNONCLIENTMETRICS: /* 41 WINVER >= 0x400 */
2010 NONCLIENTMETRICSA tmp;
2011 LPNONCLIENTMETRICS16 lpnm16 = (LPNONCLIENTMETRICS16)lpvParam;
2012 if (lpnm16 && lpnm16->cbSize == sizeof(NONCLIENTMETRICS16))
2014 tmp.cbSize = sizeof(NONCLIENTMETRICSA);
2015 ret = SystemParametersInfoA( uAction, uParam, &tmp, fuWinIni );
2016 if (ret)
2017 SYSPARAMS_NonClientMetrics32ATo16( &tmp, lpnm16 );
2019 else /* winfile 95 sets cbSize to 340 */
2020 ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
2021 break;
2024 case SPI_GETWORKAREA: /* 48 WINVER >= 0x400 */
2026 RECT tmp;
2027 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
2028 if (ret && lpvParam)
2029 CONV_RECT32TO16( &tmp, (RECT16 *)lpvParam );
2030 break;
2033 case SPI_GETMOUSEHOVERWIDTH: /* 98 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
2034 case SPI_GETMOUSEHOVERHEIGHT: /* 100 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
2035 case SPI_GETMOUSEHOVERTIME: /* 102 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
2037 UINT tmp;
2038 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
2039 if (ret && lpvParam)
2040 *(UINT16 *)lpvParam = tmp;
2041 break;
2044 default:
2045 ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
2048 return ret;
2051 /***********************************************************************
2052 * SystemParametersInfoW (USER32.@)
2054 BOOL WINAPI SystemParametersInfoW( UINT uiAction, UINT uiParam,
2055 PVOID pvParam, UINT fuWinIni )
2057 BOOL ret;
2059 TRACE("(%u, %u, %p, %u)\n", uiAction, uiParam, pvParam, fuWinIni);
2061 switch (uiAction)
2063 case SPI_SETDESKWALLPAPER: /* 20 */
2064 case SPI_SETDESKPATTERN: /* 21 */
2066 char buffer[256];
2067 if (pvParam)
2068 if (!WideCharToMultiByte( CP_ACP, 0, (LPWSTR)pvParam, -1,
2069 buffer, sizeof(buffer), NULL, NULL ))
2070 buffer[sizeof(buffer)-1] = 0;
2071 ret = SystemParametersInfoA( uiAction, uiParam, pvParam ? buffer : NULL, fuWinIni );
2072 break;
2075 case SPI_GETICONTITLELOGFONT: /* 31 */
2077 LOGFONTA tmp;
2078 ret = SystemParametersInfoA( uiAction, uiParam, pvParam ? &tmp : NULL, fuWinIni );
2079 if (ret && pvParam)
2080 SYSPARAMS_LogFont32ATo32W( &tmp, (LPLOGFONTW)pvParam );
2081 break;
2084 case SPI_GETNONCLIENTMETRICS: /* 41 WINVER >= 0x400 */
2086 NONCLIENTMETRICSA tmp;
2087 LPNONCLIENTMETRICSW lpnmW = (LPNONCLIENTMETRICSW)pvParam;
2088 if (lpnmW && lpnmW->cbSize == sizeof(NONCLIENTMETRICSW))
2090 tmp.cbSize = sizeof(NONCLIENTMETRICSA);
2091 ret = SystemParametersInfoA( uiAction, uiParam, &tmp, fuWinIni );
2092 if (ret)
2093 SYSPARAMS_NonClientMetrics32ATo32W( &tmp, lpnmW );
2095 else
2096 ret = FALSE;
2097 break;
2100 case SPI_GETICONMETRICS: /* 45 WINVER >= 0x400 */
2102 ICONMETRICSA tmp;
2103 LPICONMETRICSW lpimW = (LPICONMETRICSW)pvParam;
2104 if (lpimW && lpimW->cbSize == sizeof(ICONMETRICSW))
2106 tmp.cbSize = sizeof(ICONMETRICSA);
2107 ret = SystemParametersInfoA( uiAction, uiParam, &tmp, fuWinIni );
2108 if (ret)
2110 lpimW->iHorzSpacing = tmp.iHorzSpacing;
2111 lpimW->iVertSpacing = tmp.iVertSpacing;
2112 lpimW->iTitleWrap = tmp.iTitleWrap;
2113 SYSPARAMS_LogFont32ATo32W( &tmp.lfFont, &lpimW->lfFont );
2116 else
2117 ret = FALSE;
2118 break;
2121 case SPI_GETHIGHCONTRAST: /* 66 WINVER >= 0x400 */
2123 HIGHCONTRASTA tmp;
2124 LPHIGHCONTRASTW lphcW = (LPHIGHCONTRASTW)pvParam;
2125 if (lphcW && lphcW->cbSize == sizeof(HIGHCONTRASTW))
2127 tmp.cbSize = sizeof(HIGHCONTRASTA);
2128 ret = SystemParametersInfoA( uiAction, uiParam, &tmp, fuWinIni );
2129 if (ret)
2131 lphcW->dwFlags = tmp.dwFlags;
2132 lphcW->lpszDefaultScheme = NULL; /* FIXME? */
2135 else
2136 ret = FALSE;
2137 break;
2140 default:
2141 ret = SystemParametersInfoA( uiAction, uiParam, pvParam, fuWinIni );
2142 break;
2144 return ret;
2148 /**********************************************************************
2149 * SetDoubleClickTime (USER32.@)
2151 BOOL WINAPI SetDoubleClickTime( UINT interval )
2153 return SystemParametersInfoA(SPI_SETDOUBLECLICKTIME, interval, 0, 0);
2157 /**********************************************************************
2158 * GetDoubleClickTime (USER32.@)
2160 UINT WINAPI GetDoubleClickTime(void)
2162 char buf[10];
2164 if (!spi_loaded[SPI_SETDOUBLECLICKTIME_IDX])
2166 if (SYSPARAMS_Load( SPI_SETDOUBLECLICKTIME_REGKEY,
2167 SPI_SETDOUBLECLICKTIME_VALNAME,
2168 buf, sizeof(buf) ))
2170 double_click_time = atoi( buf );
2171 if (!double_click_time) double_click_time = 500;
2173 spi_loaded[SPI_SETDOUBLECLICKTIME_IDX] = TRUE;
2175 return double_click_time;