Implemented processing for actions SPI_SETMOUSEBUTTONSWAP,
[wine/multimedia.git] / windows / sysparams.c
blobf1eb8843860938537c26138b94517c4c32d15102
1 /*
2 * System parameters functions
4 * Copyright 1994 Alexandre Julliard
5 */
7 #include "config.h"
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include "windef.h"
13 #include "winbase.h"
14 #include "winnls.h"
15 #include "wingdi.h"
16 #include "winreg.h"
17 #include "wine/winuser16.h"
18 #include "winerror.h"
20 #include "controls.h"
21 #include "user.h"
22 #include "debugtools.h"
23 #include "sysmetrics.h"
25 DEFAULT_DEBUG_CHANNEL(system);
27 /* System parameter indexes */
28 #define SPI_SETBEEP_IDX 0
29 #define SPI_SETMOUSE_IDX 1
30 #define SPI_SETBORDER_IDX 2
31 #define SPI_SETKEYBOARDSPEED_IDX 3
32 #define SPI_ICONHORIZONTALSPACING_IDX 4
33 #define SPI_SETSCREENSAVETIMEOUT_IDX 5
34 #define SPI_SETGRIDGRANULARITY_IDX 6
35 #define SPI_SETKEYBOARDDELAY_IDX 7
36 #define SPI_ICONVERTICALSPACING_IDX 8
37 #define SPI_SETICONTITLEWRAP_IDX 9
38 #define SPI_SETMENUDROPALIGNMENT_IDX 10
39 #define SPI_SETDOUBLECLKWIDTH_IDX 11
40 #define SPI_SETDOUBLECLKHEIGHT_IDX 12
41 #define SPI_SETDOUBLECLICKTIME_IDX 13
42 #define SPI_SETMOUSEBUTTONSWAP_IDX 14
43 #define SPI_SETFASTTASKSWITCH_IDX 15
44 #define SPI_SETDRAGFULLWINDOWS_IDX 16
45 #define SPI_SETWORKAREA_IDX 17
46 #define SPI_SETSHOWSOUNDS_IDX 18
47 #define SPI_SETSCREENSAVERRUNNING_IDX 19
48 #define SPI_WINE_IDX SPI_SETSCREENSAVERRUNNING_IDX
50 /**
51 * Names of the registry subkeys of HKEY_CURRENT_USER key and value names
52 * for the system parameters.
53 * Names of the keys are created by adding string "_REGKEY" to
54 * "SET" action names, value names are created by adding "_REG_NAME"
55 * to the "SET" action name.
57 #define SPI_SETBEEP_REGKEY "Control Panel\\Sound"
58 #define SPI_SETBEEP_VALNAME "Beep"
59 #define SPI_SETMOUSE_REGKEY "Control Panel\\Mouse"
60 #define SPI_SETMOUSE_VALNAME1 "MouseThreshold1"
61 #define SPI_SETMOUSE_VALNAME2 "MouseThreshold2"
62 #define SPI_SETMOUSE_VALNAME3 "MouseSpeed"
63 #define SPI_SETBORDER_REGKEY "Control Panel\\Desktop"
64 #define SPI_SETBORDER_VALNAME "BorderWidth"
65 #define SPI_SETKEYBOARDSPEED_REGKEY "Control Panel\\Keyboard"
66 #define SPI_SETKEYBOARDSPEED_VALNAME "KeyboardSpeed"
67 #define SPI_ICONHORIZONTALSPACING_REGKEY "Control Panel\\Desktop"
68 #define SPI_ICONHORIZONTALSPACING_VALNAME "IconSpacing"
69 #define SPI_SETSCREENSAVETIMEOUT_REGKEY "Control Panel\\Desktop"
70 #define SPI_SETSCREENSAVETIMEOUT_VALNAME "ScreenSaveTimeOut"
71 #define SPI_SETGRIDGRANULARITY_REGKEY "Control Panel\\Desktop"
72 #define SPI_SETGRIDGRANULARITY_VALNAME "GridGranularity"
73 #define SPI_SETKEYBOARDDELAY_REGKEY "Control Panel\\Keyboard"
74 #define SPI_SETKEYBOARDDELAY_VALNAME "KeyboardDelay"
75 #define SPI_ICONVERTICALSPACING_REGKEY "Control Panel\\Desktop"
76 #define SPI_ICONVERTICALSPACING_VALNAME "IconVerticalSpacing"
77 #define SPI_SETICONTITLEWRAP_REGKEY "Control Panel\\Desktop"
78 #define SPI_SETICONTITLEWRAP_VALNAME "IconTitleWrap"
79 #define SPI_SETMENUDROPALIGNMENT_REGKEY "Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows"
80 #define SPI_SETMENUDROPALIGNMENT_VALNAME "MenuDropAlignment"
81 #define SPI_SETDOUBLECLKWIDTH_REGKEY "Control Panel\\Mouse"
82 #define SPI_SETDOUBLECLKWIDTH_VALNAME "DoubleClickWidth"
83 #define SPI_SETDOUBLECLKHEIGHT_REGKEY "Control Panel\\Mouse"
84 #define SPI_SETDOUBLECLKHEIGHT_VALNAME "DoubleClickHeight"
85 #define SPI_SETDOUBLECLICKTIME_REGKEY "Control Panel\\Mouse"
86 #define SPI_SETDOUBLECLICKTIME_VALNAME "DoubleClickSpeed"
87 #define SPI_SETMOUSEBUTTONSWAP_REGKEY "Control Panel\\Mouse"
88 #define SPI_SETMOUSEBUTTONSWAP_VALNAME "SwapMouseButtons"
89 #define SPI_SETFASTTASKSWITCH_REGKEY "Control Panel\\Desktop"
90 #define SPI_SETFASTTASKSWITCH_VALNAME "CoolSwitch"
91 #define SPI_SETDRAGFULLWINDOWS_REGKEY "Control Panel\\Desktop"
92 #define SPI_SETDRAGFULLWINDOWS_VALNAME "DragFullWindows"
93 #define SPI_SETWORKAREA_REGKEY "Control Panel\\Desktop"
94 #define SPI_SETWORKAREA_VALNAME "WINE_WorkArea"
95 #define SPI_SETSHOWSOUNDS_REGKEY "Control Panel\\Accessibility\\ShowSounds"
96 #define SPI_SETSHOWSOUNDS_VALNAME "On"
97 #define SPI_SETSCREENSAVERRUNNING_REGKEY "Control Panel\\Desktop"
98 #define SPI_SETSCREENSAVERRUNNING_VALNAME "WINE_ScreenSaverRunning"
100 /* volatile registry branch under CURRENT_USER_REGKEY for temporary values storage */
101 #define WINE_CURRENT_USER_REGKEY "Wine"
103 /* Indicators whether system parameter value is loaded */
104 static char spi_loaded[SPI_WINE_IDX + 1];
106 static BOOL notify_change = TRUE;
108 /* System parameters storage */
109 static BOOL beep_active = TRUE;
110 static int mouse_threshold1 = 6;
111 static int mouse_threshold2 = 10;
112 static int mouse_speed = 1;
113 static int border = 1;
114 static int keyboard_speed = 31;
115 static int screensave_timeout = 300;
116 static int grid_granularity = 0;
117 static int keyboard_delay = 1;
118 static BOOL icon_title_wrap = TRUE;
119 static int double_click_time = 500;
120 static BOOL fast_task_switch = TRUE;
121 static BOOL drag_full_windows = FALSE;
122 static RECT work_area;
123 static BOOL screensaver_running = FALSE;
125 /***********************************************************************
126 * GetTimerResolution (USER.14)
128 LONG WINAPI GetTimerResolution16(void)
130 return (1000);
133 /***********************************************************************
134 * ControlPanelInfo (USER.273)
136 void WINAPI ControlPanelInfo16( INT16 nInfoType, WORD wData, LPSTR lpBuffer )
138 FIXME("(%d, %04x, %p): stub.\n", nInfoType, wData, lpBuffer);
141 /* This function is a copy of the one in objects/font.c */
142 static void SYSPARAMS_LogFont32ATo16( const LOGFONTA* font32, LPLOGFONT16 font16 )
144 font16->lfHeight = font32->lfHeight;
145 font16->lfWidth = font32->lfWidth;
146 font16->lfEscapement = font32->lfEscapement;
147 font16->lfOrientation = font32->lfOrientation;
148 font16->lfWeight = font32->lfWeight;
149 font16->lfItalic = font32->lfItalic;
150 font16->lfUnderline = font32->lfUnderline;
151 font16->lfStrikeOut = font32->lfStrikeOut;
152 font16->lfCharSet = font32->lfCharSet;
153 font16->lfOutPrecision = font32->lfOutPrecision;
154 font16->lfClipPrecision = font32->lfClipPrecision;
155 font16->lfQuality = font32->lfQuality;
156 font16->lfPitchAndFamily = font32->lfPitchAndFamily;
157 lstrcpynA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
160 static void SYSPARAMS_LogFont32ATo32W( const LOGFONTA* font32A, LPLOGFONTW font32W )
162 font32W->lfHeight = font32A->lfHeight;
163 font32W->lfWidth = font32A->lfWidth;
164 font32W->lfEscapement = font32A->lfEscapement;
165 font32W->lfOrientation = font32A->lfOrientation;
166 font32W->lfWeight = font32A->lfWeight;
167 font32W->lfItalic = font32A->lfItalic;
168 font32W->lfUnderline = font32A->lfUnderline;
169 font32W->lfStrikeOut = font32A->lfStrikeOut;
170 font32W->lfCharSet = font32A->lfCharSet;
171 font32W->lfOutPrecision = font32A->lfOutPrecision;
172 font32W->lfClipPrecision = font32A->lfClipPrecision;
173 font32W->lfQuality = font32A->lfQuality;
174 font32W->lfPitchAndFamily = font32A->lfPitchAndFamily;
175 MultiByteToWideChar( CP_ACP, 0, font32A->lfFaceName, -1, font32W->lfFaceName, LF_FACESIZE );
176 font32W->lfFaceName[LF_FACESIZE-1] = 0;
179 static void SYSPARAMS_NonClientMetrics32ATo16( const NONCLIENTMETRICSA* lpnm32, LPNONCLIENTMETRICS16 lpnm16 )
181 lpnm16->iBorderWidth = lpnm32->iBorderWidth;
182 lpnm16->iScrollWidth = lpnm32->iScrollWidth;
183 lpnm16->iScrollHeight = lpnm32->iScrollHeight;
184 lpnm16->iCaptionWidth = lpnm32->iCaptionWidth;
185 lpnm16->iCaptionHeight = lpnm32->iCaptionHeight;
186 SYSPARAMS_LogFont32ATo16( &lpnm32->lfCaptionFont, &lpnm16->lfCaptionFont );
187 lpnm16->iSmCaptionWidth = lpnm32->iSmCaptionWidth;
188 lpnm16->iSmCaptionHeight = lpnm32->iSmCaptionHeight;
189 SYSPARAMS_LogFont32ATo16( &lpnm32->lfSmCaptionFont, &lpnm16->lfSmCaptionFont );
190 lpnm16->iMenuWidth = lpnm32->iMenuWidth;
191 lpnm16->iMenuHeight = lpnm32->iMenuHeight;
192 SYSPARAMS_LogFont32ATo16( &lpnm32->lfMenuFont, &lpnm16->lfMenuFont );
193 SYSPARAMS_LogFont32ATo16( &lpnm32->lfStatusFont, &lpnm16->lfStatusFont );
194 SYSPARAMS_LogFont32ATo16( &lpnm32->lfMessageFont, &lpnm16->lfMessageFont );
197 static void SYSPARAMS_NonClientMetrics32ATo32W( const NONCLIENTMETRICSA* lpnm32A, LPNONCLIENTMETRICSW lpnm32W )
199 lpnm32W->iBorderWidth = lpnm32A->iBorderWidth;
200 lpnm32W->iScrollWidth = lpnm32A->iScrollWidth;
201 lpnm32W->iScrollHeight = lpnm32A->iScrollHeight;
202 lpnm32W->iCaptionWidth = lpnm32A->iCaptionWidth;
203 lpnm32W->iCaptionHeight = lpnm32A->iCaptionHeight;
204 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfCaptionFont, &lpnm32W->lfCaptionFont );
205 lpnm32W->iSmCaptionWidth = lpnm32A->iSmCaptionWidth;
206 lpnm32W->iSmCaptionHeight = lpnm32A->iSmCaptionHeight;
207 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfSmCaptionFont, &lpnm32W->lfSmCaptionFont );
208 lpnm32W->iMenuWidth = lpnm32A->iMenuWidth;
209 lpnm32W->iMenuHeight = lpnm32A->iMenuHeight;
210 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfMenuFont, &lpnm32W->lfMenuFont );
211 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfStatusFont, &lpnm32W->lfStatusFont );
212 SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfMessageFont, &lpnm32W->lfMessageFont );
215 /***********************************************************************
216 * SYSPARAMS_Reset
218 * Sets the system parameter which should be always loaded to
219 * current value stored in registry.
220 * Invalidates lazy loaded parameter, so it will be loaded the next time
221 * it is requested.
223 * Parameters:
224 * uiAction - system parameter to reload value for.
225 * Note, only "SET" values can be used for this parameter.
226 * If uiAction is 0 all system parameters are reset.
228 void SYSPARAMS_Reset( UINT uiAction )
230 #define WINE_RELOAD_SPI(x) \
231 case x: \
232 spi_loaded[x##_IDX] = FALSE; \
233 SystemParametersInfoA( x, 0, dummy_buf, 0 );\
234 if (uiAction) \
235 break
237 #define WINE_IGNORE_SPI(x) \
238 case x: \
239 if (uiAction) \
240 break
242 #define WINE_INVALIDATE_SPI(x) \
243 case x: \
244 spi_loaded[x##_IDX] = FALSE; \
245 break
247 BOOL not_all_processed = TRUE;
248 char dummy_buf[10];
250 /* Execution falls through all the branches for uiAction == 0 */
251 switch (uiAction)
253 case 0:
254 memset( spi_loaded, 0, sizeof(spi_loaded) );
256 WINE_RELOAD_SPI(SPI_SETBORDER);
257 WINE_RELOAD_SPI(SPI_ICONHORIZONTALSPACING);
258 WINE_RELOAD_SPI(SPI_ICONVERTICALSPACING);
259 WINE_IGNORE_SPI(SPI_SETSCREENSAVEACTIVE);
260 WINE_RELOAD_SPI(SPI_SETDOUBLECLKWIDTH);
261 WINE_RELOAD_SPI(SPI_SETDOUBLECLKHEIGHT);
262 WINE_RELOAD_SPI(SPI_SETMOUSEBUTTONSWAP);
263 WINE_RELOAD_SPI(SPI_SETSHOWSOUNDS);
264 WINE_RELOAD_SPI(SPI_SETMENUDROPALIGNMENT);
266 default:
267 if (uiAction)
269 /* lazy loaded parameters */
270 switch (uiAction)
272 WINE_INVALIDATE_SPI(SPI_SETBEEP);
273 WINE_INVALIDATE_SPI(SPI_SETMOUSE);
274 WINE_INVALIDATE_SPI(SPI_SETKEYBOARDSPEED);
275 WINE_INVALIDATE_SPI(SPI_SETSCREENSAVETIMEOUT);
276 WINE_INVALIDATE_SPI(SPI_SETGRIDGRANULARITY);
277 WINE_INVALIDATE_SPI(SPI_SETKEYBOARDDELAY);
278 WINE_INVALIDATE_SPI(SPI_SETICONTITLEWRAP);
279 WINE_INVALIDATE_SPI(SPI_SETDOUBLECLICKTIME);
280 WINE_INVALIDATE_SPI(SPI_SETFASTTASKSWITCH);
281 WINE_INVALIDATE_SPI(SPI_SETDRAGFULLWINDOWS);
282 WINE_INVALIDATE_SPI(SPI_SETWORKAREA);
283 WINE_INVALIDATE_SPI(SPI_SETSCREENSAVERRUNNING);
284 default:
285 FIXME( "Unknown action reset: %u\n", uiAction );
286 break;
289 else
290 not_all_processed = FALSE;
291 break;
294 if (!uiAction && not_all_processed)
295 ERR( "Incorrect implementation of SYSPARAMS_Reset. "
296 "Not all params are reloaded.\n" );
297 #undef WINE_INVALIDATE_SPI
298 #undef WINE_IGNORE_SPI
299 #undef WINE_RELOAD_SPI
302 /***********************************************************************
303 * get_volatile_regkey
305 * Return a handle to the volatile registry key used to store
306 * non-permanently modified parameters.
308 static HKEY get_volatile_regkey(void)
310 static HKEY volatile_key;
312 if (!volatile_key)
314 if (RegCreateKeyExA( HKEY_CURRENT_USER, WINE_CURRENT_USER_REGKEY,
315 0, 0, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, 0,
316 &volatile_key, 0 ) != ERROR_SUCCESS)
317 ERR("Can't create wine configuration registry branch");
319 return volatile_key;
322 /***********************************************************************
323 * SYSPARAMS_NotifyChange
325 * Sends notification about system parameter update.
327 void SYSPARAMS_NotifyChange( UINT uiAction, UINT fWinIni )
329 if (notify_change)
331 if (fWinIni & SPIF_UPDATEINIFILE)
333 if (fWinIni & (SPIF_SENDWININICHANGE | SPIF_SENDCHANGE))
334 SendMessageA(HWND_BROADCAST, WM_SETTINGCHANGE,
335 uiAction, (LPARAM) "");
337 else
339 /* FIXME notify other wine processes with internal message */
345 /***********************************************************************
346 * Loads system parameter from user profile.
348 BOOL SYSPARAMS_Load( LPSTR lpRegKey, LPSTR lpValName, LPSTR lpBuf )
350 BOOL ret = FALSE;
351 DWORD type;
352 HKEY hKey;
353 DWORD count;
355 if ((RegOpenKeyA( get_volatile_regkey(), lpRegKey,
356 &hKey ) == ERROR_SUCCESS) ||
357 (RegOpenKeyA( HKEY_CURRENT_USER, lpRegKey,
358 &hKey ) == ERROR_SUCCESS))
360 ret = !RegQueryValueExA( hKey, lpValName, NULL, &type, lpBuf, &count );
361 RegCloseKey( hKey );
363 return ret;
366 /***********************************************************************
367 * Saves system parameter to user profile.
369 BOOL SYSPARAMS_Save( LPSTR lpRegKey, LPSTR lpValName, LPSTR lpValue,
370 UINT fWinIni )
372 HKEY hKey;
373 HKEY hBaseKey;
374 DWORD dwOptions;
375 BOOL ret = FALSE;
377 if (fWinIni & SPIF_UPDATEINIFILE)
379 hBaseKey = HKEY_CURRENT_USER;
380 dwOptions = 0;
382 else
384 hBaseKey = get_volatile_regkey();
385 dwOptions = REG_OPTION_VOLATILE;
388 if (RegCreateKeyExA( hBaseKey, lpRegKey,
389 0, 0, dwOptions, KEY_ALL_ACCESS,
390 0, &hKey, 0 ) == ERROR_SUCCESS)
392 if (RegSetValueExA( hKey, lpValName, 0, REG_SZ,
393 lpValue, strlen(lpValue) + 1 ) == ERROR_SUCCESS)
395 ret = TRUE;
396 if (hBaseKey == HKEY_CURRENT_USER)
397 RegDeleteKeyA( get_volatile_regkey(), lpRegKey );
399 RegCloseKey( hKey );
401 return ret;
405 /***********************************************************************
406 * SYSPARAMS_GetDoubleClickSize
408 * There is no SPI_GETDOUBLECLK* so we export this function instead.
410 void SYSPARAMS_GetDoubleClickSize( INT *width, INT *height )
412 char buf[10];
414 if (!spi_loaded[SPI_SETDOUBLECLKWIDTH_IDX])
416 char buf[10];
418 if (SYSPARAMS_Load( SPI_SETDOUBLECLKWIDTH_REGKEY,
419 SPI_SETDOUBLECLKWIDTH_VALNAME, buf ))
421 SYSMETRICS_Set( SM_CXDOUBLECLK, atoi( buf ) );
423 spi_loaded[SPI_SETDOUBLECLKWIDTH_IDX] = TRUE;
425 if (!spi_loaded[SPI_SETDOUBLECLKHEIGHT_IDX])
427 if (SYSPARAMS_Load( SPI_SETDOUBLECLKHEIGHT_REGKEY,
428 SPI_SETDOUBLECLKHEIGHT_VALNAME, buf ))
430 SYSMETRICS_Set( SM_CYDOUBLECLK, atoi( buf ) );
432 spi_loaded[SPI_SETDOUBLECLKHEIGHT_IDX] = TRUE;
434 *width = GetSystemMetrics( SM_CXDOUBLECLK );
435 *height = GetSystemMetrics( SM_CYDOUBLECLK );
439 /***********************************************************************
440 * SYSPARAMS_GetMouseButtonSwap
442 * There is no SPI_GETMOUSEBUTTONSWAP so we export this function instead.
444 INT SYSPARAMS_GetMouseButtonSwap( void )
446 int spi_idx = SPI_SETMOUSEBUTTONSWAP_IDX;
448 if (!spi_loaded[spi_idx])
450 char buf[5];
452 if (SYSPARAMS_Load( SPI_SETMOUSEBUTTONSWAP_REGKEY,
453 SPI_SETMOUSEBUTTONSWAP_VALNAME, buf ))
455 SYSMETRICS_Set( SM_SWAPBUTTON, atoi( buf ) );
457 spi_loaded[spi_idx] = TRUE;
460 return GetSystemMetrics( SM_SWAPBUTTON );
463 /***********************************************************************
464 * SystemParametersInfoA (USER32.@)
466 * Each system parameter has flag which shows whether the parameter
467 * is loaded or not. Parameters, stored directly in SysParametersInfo are
468 * loaded from registry only when they are requested and the flag is
469 * "false", after the loading the flag is set to "true". On interprocess
470 * notification of the parameter change the corresponding parameter flag is
471 * set to "false". The parameter value will be reloaded when it is requested
472 * the next time.
473 * Parameters, backed by or depend on GetSystemMetrics are processed
474 * differently. These parameters are always loaded. They are reloaded right
475 * away on interprocess change notification. We can't do lazy loading because
476 * we don't want to complicate GetSystemMetrics.
477 * Parameters, backed by X settings are read from corresponding setting.
478 * On the parameter change request the setting is changed. Interprocess change
479 * notifications are ignored.
480 * When parameter value is updated the changed value is stored in permanent
481 * registry branch if saving is requested. Otherwise it is stored
482 * in temporary branch
485 BOOL WINAPI SystemParametersInfoA( UINT uiAction, UINT uiParam,
486 PVOID pvParam, UINT fWinIni )
488 #define WINE_SPI_FIXME(x) \
489 case x: \
490 FIXME( "Unimplemented action: %u (%s)\n", x, #x ); \
491 SetLastError( ERROR_INVALID_SPI_VALUE ); \
492 ret = FALSE; \
493 break
494 #define WINE_SPI_WARN(x) \
495 case x: \
496 WARN( "Ignored action: %u (%s)\n", x, #x ); \
497 break
499 BOOL ret = TRUE;
500 unsigned spi_idx = 0;
502 TRACE("(%u, %u, %p, %u)\n", uiAction, uiParam, pvParam, fWinIni);
504 switch (uiAction)
506 case SPI_GETBEEP: /* 1 */
507 spi_idx = SPI_SETBEEP_IDX;
508 if (!spi_loaded[spi_idx])
510 char buf[5];
512 if (SYSPARAMS_Load( SPI_SETBEEP_REGKEY, SPI_SETBEEP_VALNAME, buf ))
513 beep_active = !strcasecmp( "Yes", buf );
514 spi_loaded[spi_idx] = TRUE;
517 *(BOOL *)pvParam = beep_active;
518 break;
520 case SPI_SETBEEP: /* 2 */
521 spi_idx = SPI_SETBEEP_IDX;
522 if (SYSPARAMS_Save( SPI_SETBEEP_REGKEY, SPI_SETBEEP_VALNAME,
523 (uiParam ? "Yes" : "No"), fWinIni ))
525 beep_active = uiParam;
526 spi_loaded[spi_idx] = TRUE;
528 else
529 ret = FALSE;
530 break;
532 case SPI_GETMOUSE: /* 3 */
533 spi_idx = SPI_SETMOUSE_IDX;
534 if (!spi_loaded[spi_idx])
536 char buf[10];
538 if (SYSPARAMS_Load( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME1,
539 buf ))
540 mouse_threshold1 = atoi( buf );
541 if (SYSPARAMS_Load( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME2,
542 buf ))
543 mouse_threshold2 = atoi( buf );
544 if (SYSPARAMS_Load( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME3,
545 buf ))
546 mouse_speed = atoi( buf );
547 spi_loaded[spi_idx] = TRUE;
549 ((INT *)pvParam)[0] = mouse_threshold1;
550 ((INT *)pvParam)[1] = mouse_threshold2;
551 ((INT *)pvParam)[2] = mouse_speed;
552 break;
554 case SPI_SETMOUSE: /* 4 */
556 char buf[10];
558 spi_idx = SPI_SETMOUSE_IDX;
559 sprintf(buf, "%d", ((INT *)pvParam)[0]);
561 if (SYSPARAMS_Save( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME1,
562 buf, fWinIni ))
564 mouse_threshold1 = ((INT *)pvParam)[0];
565 spi_loaded[spi_idx] = TRUE;
567 sprintf(buf, "%d", ((INT *)pvParam)[1]);
568 SYSPARAMS_Save( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME2,
569 buf, fWinIni );
570 mouse_threshold2 = ((INT *)pvParam)[1];
572 sprintf(buf, "%d", ((INT *)pvParam)[2]);
573 SYSPARAMS_Save( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME3,
574 buf, fWinIni );
575 mouse_speed = ((INT *)pvParam)[2];
577 else
578 ret = FALSE;
579 break;
582 case SPI_GETBORDER: /* 5 */
583 spi_idx = SPI_SETBORDER_IDX;
584 if (!spi_loaded[spi_idx])
586 char buf[10];
588 if (SYSPARAMS_Load( SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME,
589 buf ))
591 int i = atoi( buf );
592 if (i > 0) border = i;
594 spi_loaded[spi_idx] = TRUE;
595 if (TWEAK_WineLook > WIN31_LOOK)
597 SYSMETRICS_Set( SM_CXFRAME, border + GetSystemMetrics( SM_CXDLGFRAME ) );
598 SYSMETRICS_Set( SM_CYFRAME, border + GetSystemMetrics( SM_CXDLGFRAME ) );
601 *(INT *)pvParam = border;
602 break;
604 case SPI_SETBORDER: /* 6 */
606 char buf[10];
608 spi_idx = SPI_SETBORDER_IDX;
609 sprintf(buf, "%u", uiParam);
611 if (SYSPARAMS_Save( SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME,
612 buf, fWinIni ))
614 if (uiParam > 0)
616 border = uiParam;
617 spi_loaded[spi_idx] = TRUE;
618 if (TWEAK_WineLook > WIN31_LOOK)
620 SYSMETRICS_Set( SM_CXFRAME, uiParam + GetSystemMetrics( SM_CXDLGFRAME ) );
621 SYSMETRICS_Set( SM_CYFRAME, uiParam + GetSystemMetrics( SM_CXDLGFRAME ) );
625 else
626 ret = FALSE;
627 break;
630 case SPI_GETKEYBOARDSPEED: /* 10 */
631 spi_idx = SPI_SETKEYBOARDSPEED_IDX;
632 if (!spi_loaded[spi_idx])
634 char buf[10];
636 if (SYSPARAMS_Load( SPI_SETKEYBOARDSPEED_REGKEY,
637 SPI_SETKEYBOARDSPEED_VALNAME,
638 buf ))
639 keyboard_speed = atoi( buf );
640 spi_loaded[spi_idx] = TRUE;
642 *(INT *)pvParam = keyboard_speed;
643 break;
645 case SPI_SETKEYBOARDSPEED: /* 11 */
647 char buf[10];
649 spi_idx = SPI_SETKEYBOARDSPEED_IDX;
650 if (uiParam > 31)
651 uiParam = 31;
652 sprintf(buf, "%u", uiParam);
654 if (SYSPARAMS_Save( SPI_SETKEYBOARDSPEED_REGKEY,
655 SPI_SETKEYBOARDSPEED_VALNAME,
656 buf, fWinIni ))
658 keyboard_speed = uiParam;
659 spi_loaded[spi_idx] = TRUE;
661 else
662 ret = FALSE;
663 break;
666 /* not implemented in Windows */
667 WINE_SPI_WARN(SPI_LANGDRIVER); /* 12 */
669 case SPI_ICONHORIZONTALSPACING: /* 13 */
670 spi_idx = SPI_ICONHORIZONTALSPACING_IDX;
671 if (pvParam != NULL)
673 if (!spi_loaded[spi_idx])
675 char buf[10];
677 if (SYSPARAMS_Load( SPI_ICONHORIZONTALSPACING_REGKEY,
678 SPI_ICONHORIZONTALSPACING_VALNAME, buf ))
680 SYSMETRICS_Set( SM_CXICONSPACING, atoi( buf ) );
682 spi_loaded[spi_idx] = TRUE;
685 *(INT *)pvParam = GetSystemMetrics( SM_CXICONSPACING );
687 else
689 char buf[10];
691 if (uiParam < 32) uiParam = 32;
693 sprintf(buf, "%u", uiParam);
694 if (SYSPARAMS_Save( SPI_ICONHORIZONTALSPACING_REGKEY,
695 SPI_ICONHORIZONTALSPACING_VALNAME,
696 buf, fWinIni ))
698 SYSMETRICS_Set( SM_CXICONSPACING, uiParam );
699 spi_loaded[spi_idx] = TRUE;
701 else
702 ret = FALSE;
704 break;
706 case SPI_GETSCREENSAVETIMEOUT: /* 14 */
707 spi_idx = SPI_SETSCREENSAVETIMEOUT_IDX;
708 if (!spi_loaded[spi_idx])
710 char buf[10];
712 if (SYSPARAMS_Load( SPI_SETSCREENSAVETIMEOUT_REGKEY,
713 SPI_SETSCREENSAVETIMEOUT_VALNAME,
714 buf ))
715 screensave_timeout = atoi( buf );
717 spi_loaded[spi_idx] = TRUE;
719 *(INT *)pvParam = screensave_timeout;
720 break;
722 case SPI_SETSCREENSAVETIMEOUT: /* 15 */
724 char buf[10];
726 spi_idx = SPI_SETSCREENSAVETIMEOUT_IDX;
727 sprintf(buf, "%u", uiParam);
729 if (SYSPARAMS_Save( SPI_SETSCREENSAVETIMEOUT_REGKEY,
730 SPI_SETSCREENSAVETIMEOUT_VALNAME,
731 buf, fWinIni ))
733 screensave_timeout = uiParam;
734 spi_loaded[spi_idx] = TRUE;
736 else
737 ret = FALSE;
738 break;
741 case SPI_GETSCREENSAVEACTIVE: /* 16 */
742 *(BOOL *)pvParam = USER_Driver.pGetScreenSaveActive();
743 break;
745 case SPI_SETSCREENSAVEACTIVE: /* 17 */
747 char buf[5];
749 sprintf(buf, "%u", uiParam);
750 USER_Driver.pSetScreenSaveActive( uiParam );
751 break;
754 case SPI_GETGRIDGRANULARITY: /* 18 */
755 spi_idx = SPI_SETGRIDGRANULARITY_IDX;
756 if (!spi_loaded[spi_idx])
758 char buf[10];
760 if (SYSPARAMS_Load( SPI_SETGRIDGRANULARITY_REGKEY,
761 SPI_SETGRIDGRANULARITY_VALNAME,
762 buf ))
763 grid_granularity = atoi( buf );
765 spi_loaded[spi_idx] = TRUE;
767 *(INT *)pvParam = grid_granularity;
768 break;
770 case SPI_SETGRIDGRANULARITY: /* 19 */
772 char buf[10];
774 spi_idx = SPI_SETGRIDGRANULARITY_IDX;
775 sprintf(buf, "%u", uiParam);
777 if (SYSPARAMS_Save( SPI_SETGRIDGRANULARITY_REGKEY,
778 SPI_SETGRIDGRANULARITY_VALNAME,
779 buf, fWinIni ))
781 grid_granularity = uiParam;
782 spi_loaded[spi_idx] = TRUE;
784 else
785 ret = FALSE;
786 break;
789 case SPI_SETDESKWALLPAPER: /* 20 */
790 ret = SetDeskWallPaper( (LPSTR)pvParam );
791 break;
792 case SPI_SETDESKPATTERN: /* 21 */
793 /* FIXME: the ability to specify a pattern in pvParam
794 doesn't seem to be documented for Win32 */
795 if ((INT16)uiParam == -1)
797 char buffer[256];
798 GetProfileStringA( "Desktop", "Pattern",
799 "170 85 170 85 170 85 170 85",
800 buffer, sizeof(buffer) );
801 ret = DESKTOP_SetPattern( (LPSTR)buffer );
802 } else
803 ret = DESKTOP_SetPattern( (LPSTR)pvParam );
804 break;
806 case SPI_GETKEYBOARDDELAY: /* 22 */
807 spi_idx = SPI_SETKEYBOARDDELAY_IDX;
808 if (!spi_loaded[spi_idx])
810 char buf[10];
812 if (SYSPARAMS_Load( SPI_SETKEYBOARDDELAY_REGKEY,
813 SPI_SETKEYBOARDDELAY_VALNAME,
814 buf ))
816 int i = atoi( buf );
817 if ( (i >= 0) && (i <= 3)) keyboard_delay = i;
820 spi_loaded[spi_idx] = TRUE;
822 *(INT *)pvParam = keyboard_delay;
823 break;
825 case SPI_SETKEYBOARDDELAY: /* 23 */
827 char buf[10];
829 spi_idx = SPI_SETKEYBOARDDELAY_IDX;
830 sprintf(buf, "%u", uiParam);
832 if (SYSPARAMS_Save( SPI_SETKEYBOARDDELAY_REGKEY,
833 SPI_SETKEYBOARDDELAY_VALNAME,
834 buf, fWinIni ))
836 if (uiParam <= 3)
837 keyboard_delay = uiParam;
838 spi_loaded[spi_idx] = TRUE;
840 else
841 ret = FALSE;
842 break;
845 case SPI_ICONVERTICALSPACING: /* 24 */
846 spi_idx = SPI_ICONVERTICALSPACING_IDX;
847 if (pvParam != NULL)
849 if (!spi_loaded[spi_idx])
851 char buf[10];
853 if (SYSPARAMS_Load( SPI_ICONVERTICALSPACING_REGKEY,
854 SPI_ICONVERTICALSPACING_VALNAME, buf ))
856 SYSMETRICS_Set( SM_CYICONSPACING, atoi( buf ) );
858 spi_loaded[spi_idx] = TRUE;
861 *(INT *)pvParam = GetSystemMetrics( SM_CYICONSPACING );
863 else
865 char buf[10];
867 if (uiParam < 32) uiParam = 32;
869 sprintf(buf, "%u", uiParam);
870 if (SYSPARAMS_Save( SPI_ICONVERTICALSPACING_REGKEY,
871 SPI_ICONVERTICALSPACING_VALNAME,
872 buf, fWinIni ))
874 SYSMETRICS_Set( SM_CYICONSPACING, uiParam );
875 spi_loaded[spi_idx] = TRUE;
877 else
878 ret = FALSE;
881 break;
883 case SPI_GETICONTITLEWRAP: /* 25 */
884 spi_idx = SPI_SETICONTITLEWRAP_IDX;
885 if (!spi_loaded[spi_idx])
887 char buf[5];
889 if (SYSPARAMS_Load( SPI_SETICONTITLEWRAP_REGKEY,
890 SPI_SETICONTITLEWRAP_VALNAME, buf ))
891 icon_title_wrap = atoi(buf);
892 spi_loaded[spi_idx] = TRUE;
895 *(BOOL *)pvParam = icon_title_wrap;
896 break;
898 case SPI_SETICONTITLEWRAP: /* 26 */
900 char buf[5];
902 spi_idx = SPI_SETICONTITLEWRAP_IDX;
903 sprintf(buf, "%u", uiParam);
904 if (SYSPARAMS_Save( SPI_SETICONTITLEWRAP_REGKEY,
905 SPI_SETICONTITLEWRAP_VALNAME,
906 buf, fWinIni ))
908 icon_title_wrap = uiParam;
909 spi_loaded[spi_idx] = TRUE;
911 else
912 ret = FALSE;
913 break;
916 case SPI_GETMENUDROPALIGNMENT: /* 27 */
917 spi_idx = SPI_SETMENUDROPALIGNMENT_IDX;
919 if (!spi_loaded[spi_idx])
921 char buf[5];
923 if (SYSPARAMS_Load( SPI_SETMENUDROPALIGNMENT_REGKEY,
924 SPI_SETMENUDROPALIGNMENT_VALNAME, buf ))
926 SYSMETRICS_Set( SM_MENUDROPALIGNMENT, atoi( buf ) );
928 spi_loaded[spi_idx] = TRUE;
932 *(BOOL *)pvParam = GetSystemMetrics( SM_MENUDROPALIGNMENT );
933 break;
935 case SPI_SETMENUDROPALIGNMENT: /* 28 */
937 char buf[5];
938 spi_idx = SPI_SETMENUDROPALIGNMENT_IDX;
940 sprintf(buf, "%u", uiParam);
941 if (SYSPARAMS_Save( SPI_SETMENUDROPALIGNMENT_REGKEY,
942 SPI_SETMENUDROPALIGNMENT_VALNAME,
943 buf, fWinIni ))
945 SYSMETRICS_Set( SM_MENUDROPALIGNMENT, uiParam );
946 spi_loaded[spi_idx] = TRUE;
948 else
949 ret = FALSE;
950 break;
953 case SPI_SETDOUBLECLKWIDTH: /* 29 */
955 char buf[10];
956 spi_idx = SPI_SETDOUBLECLKWIDTH_IDX;
958 sprintf(buf, "%u", uiParam);
959 if (SYSPARAMS_Save( SPI_SETDOUBLECLKWIDTH_REGKEY,
960 SPI_SETDOUBLECLKWIDTH_VALNAME,
961 buf, fWinIni ))
963 SYSMETRICS_Set( SM_CXDOUBLECLK, uiParam );
964 spi_loaded[spi_idx] = TRUE;
966 else
967 ret = FALSE;
968 break;
971 case SPI_SETDOUBLECLKHEIGHT: /* 30 */
973 char buf[10];
974 spi_idx = SPI_SETDOUBLECLKHEIGHT_IDX;
976 sprintf(buf, "%u", uiParam);
977 if (SYSPARAMS_Save( SPI_SETDOUBLECLKHEIGHT_REGKEY,
978 SPI_SETDOUBLECLKHEIGHT_VALNAME,
979 buf, fWinIni ))
981 SYSMETRICS_Set( SM_CYDOUBLECLK, uiParam );
982 spi_loaded[spi_idx] = TRUE;
984 else
985 ret = FALSE;
986 break;
989 case SPI_GETICONTITLELOGFONT: /* 31 */
991 LPLOGFONTA lpLogFont = (LPLOGFONTA)pvParam;
993 /* from now on we always have an alias for MS Sans Serif */
995 GetProfileStringA( "Desktop", "IconTitleFaceName", "MS Sans Serif",
996 lpLogFont->lfFaceName, LF_FACESIZE );
997 lpLogFont->lfHeight = -GetProfileIntA( "Desktop", "IconTitleSize", 13 );
998 lpLogFont->lfWidth = 0;
999 lpLogFont->lfEscapement = lpLogFont->lfOrientation = 0;
1000 lpLogFont->lfWeight = FW_NORMAL;
1001 lpLogFont->lfItalic = FALSE;
1002 lpLogFont->lfStrikeOut = FALSE;
1003 lpLogFont->lfUnderline = FALSE;
1004 lpLogFont->lfCharSet = ANSI_CHARSET;
1005 lpLogFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
1006 lpLogFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
1007 lpLogFont->lfPitchAndFamily = DEFAULT_PITCH | FF_SWISS;
1008 break;
1011 case SPI_SETDOUBLECLICKTIME: /* 32 */
1013 char buf[10];
1015 spi_idx = SPI_SETDOUBLECLICKTIME_IDX;
1016 sprintf(buf, "%u", uiParam);
1018 if (SYSPARAMS_Save( SPI_SETDOUBLECLICKTIME_REGKEY,
1019 SPI_SETDOUBLECLICKTIME_VALNAME,
1020 buf, fWinIni ))
1022 if (!uiParam)
1023 uiParam = 500;
1024 double_click_time = uiParam;
1025 spi_loaded[spi_idx] = TRUE;
1027 else
1028 ret = FALSE;
1029 break;
1032 case SPI_SETMOUSEBUTTONSWAP: /* 33 */
1034 char buf[5];
1035 spi_idx = SPI_SETMOUSEBUTTONSWAP_IDX;
1037 sprintf(buf, "%u", uiParam);
1038 if (SYSPARAMS_Save( SPI_SETMOUSEBUTTONSWAP_REGKEY,
1039 SPI_SETMOUSEBUTTONSWAP_VALNAME,
1040 buf, fWinIni ))
1042 SYSMETRICS_Set( SM_SWAPBUTTON, uiParam );
1043 spi_loaded[spi_idx] = TRUE;
1045 else
1046 ret = FALSE;
1047 break;
1050 WINE_SPI_FIXME(SPI_SETICONTITLELOGFONT); /* 34 */
1052 case SPI_GETFASTTASKSWITCH: /* 35 */
1053 spi_idx = SPI_SETFASTTASKSWITCH_IDX;
1054 if (!spi_loaded[spi_idx])
1056 char buf[5];
1058 if (SYSPARAMS_Load( SPI_SETFASTTASKSWITCH_REGKEY,
1059 SPI_SETFASTTASKSWITCH_VALNAME, buf ))
1060 fast_task_switch = atoi(buf);
1061 spi_loaded[spi_idx] = TRUE;
1064 *(BOOL *)pvParam = fast_task_switch;
1065 break;
1067 case SPI_SETFASTTASKSWITCH: /* 36 */
1069 char buf[5];
1071 spi_idx = SPI_SETFASTTASKSWITCH_IDX;
1072 sprintf(buf, "%u", uiParam);
1073 if (SYSPARAMS_Save( SPI_SETFASTTASKSWITCH_REGKEY,
1074 SPI_SETFASTTASKSWITCH_VALNAME,
1075 buf, fWinIni ))
1077 fast_task_switch = uiParam;
1078 spi_loaded[spi_idx] = TRUE;
1080 else
1081 ret = FALSE;
1082 break;
1085 case SPI_SETDRAGFULLWINDOWS: /* 37 WINVER >= 0x0400 */
1087 char buf[5];
1089 spi_idx = SPI_SETDRAGFULLWINDOWS_IDX;
1090 sprintf(buf, "%u", uiParam);
1091 if (SYSPARAMS_Save( SPI_SETDRAGFULLWINDOWS_REGKEY,
1092 SPI_SETDRAGFULLWINDOWS_VALNAME,
1093 buf, fWinIni ))
1095 drag_full_windows = uiParam;
1096 spi_loaded[spi_idx] = TRUE;
1098 else
1099 ret = FALSE;
1100 break;
1103 case SPI_GETDRAGFULLWINDOWS: /* 38 WINVER >= 0x0400 */
1104 spi_idx = SPI_SETDRAGFULLWINDOWS_IDX;
1105 if (!spi_loaded[spi_idx])
1107 char buf[5];
1109 if (SYSPARAMS_Load( SPI_SETDRAGFULLWINDOWS_REGKEY,
1110 SPI_SETDRAGFULLWINDOWS_VALNAME, buf ))
1111 drag_full_windows = atoi(buf);
1112 spi_loaded[spi_idx] = TRUE;
1115 *(BOOL *)pvParam = drag_full_windows;
1116 break;
1118 case SPI_GETNONCLIENTMETRICS: /* 41 WINVER >= 0x400 */
1120 LPNONCLIENTMETRICSA lpnm = (LPNONCLIENTMETRICSA)pvParam;
1122 if (lpnm->cbSize == sizeof(NONCLIENTMETRICSA))
1124 LPLOGFONTA lpLogFont = &(lpnm->lfMenuFont);
1126 /* clear the struct, so we have 'sane' members */
1127 memset(
1128 (char *)pvParam + sizeof(lpnm->cbSize),
1130 lpnm->cbSize - sizeof(lpnm->cbSize)
1133 /* FIXME: initialize geometry entries */
1134 /* FIXME: As these values are presumably in device units,
1135 * we should calculate the defaults based on the screen dpi
1137 /* caption */
1138 lpnm->iCaptionWidth = ((TWEAK_WineLook > WIN31_LOOK) ? 32 : 20);
1139 lpnm->iCaptionHeight = lpnm->iCaptionWidth;
1140 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0, (LPVOID)&(lpnm->lfCaptionFont), 0 );
1141 lpnm->lfCaptionFont.lfWeight = FW_BOLD;
1143 /* small caption */
1144 lpnm->iSmCaptionWidth = ((TWEAK_WineLook > WIN31_LOOK) ? 32 : 17);
1145 lpnm->iSmCaptionHeight = lpnm->iSmCaptionWidth;
1146 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0, (LPVOID)&(lpnm->lfSmCaptionFont), 0 );
1148 /* menus, FIXME: names of wine.conf entries are bogus */
1150 lpnm->iMenuWidth = GetProfileIntA( "Desktop", "MenuWidth", 13 ); /* size of the menu buttons*/
1151 lpnm->iMenuHeight = GetProfileIntA( "Desktop", "MenuHeight",
1152 (TWEAK_WineLook > WIN31_LOOK) ? 13 : 27 );
1154 GetProfileStringA( "Desktop", "MenuFont",
1155 (TWEAK_WineLook > WIN31_LOOK) ? "MS Sans Serif": "System",
1156 lpLogFont->lfFaceName, LF_FACESIZE );
1158 lpLogFont->lfHeight = -GetProfileIntA( "Desktop", "MenuFontSize", 13 );
1159 lpLogFont->lfWidth = 0;
1160 lpLogFont->lfEscapement = lpLogFont->lfOrientation = 0;
1161 lpLogFont->lfWeight = (TWEAK_WineLook > WIN31_LOOK) ? FW_NORMAL : FW_BOLD;
1162 lpLogFont->lfItalic = FALSE;
1163 lpLogFont->lfStrikeOut = FALSE;
1164 lpLogFont->lfUnderline = FALSE;
1165 lpLogFont->lfCharSet = ANSI_CHARSET;
1166 lpLogFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
1167 lpLogFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
1168 lpLogFont->lfPitchAndFamily = DEFAULT_PITCH | FF_SWISS;
1170 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0,
1171 (LPVOID)&(lpnm->lfStatusFont), 0 );
1172 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0,
1173 (LPVOID)&(lpnm->lfMessageFont), 0 );
1175 else
1177 WARN("size mismatch !! (is %d; should be %d)\n", lpnm->cbSize, sizeof(NONCLIENTMETRICSA));
1178 /* FIXME: SetLastError? */
1179 ret = FALSE;
1181 break;
1183 WINE_SPI_FIXME(SPI_SETNONCLIENTMETRICS); /* 42 WINVER >= 0x400 */
1185 WINE_SPI_FIXME(SPI_GETMINIMIZEDMETRICS); /* 43 WINVER >= 0x400 */
1186 WINE_SPI_FIXME(SPI_SETMINIMIZEDMETRICS); /* 44 WINVER >= 0x400 */
1188 case SPI_GETICONMETRICS: /* 45 WINVER >= 0x400 */
1190 LPICONMETRICSA lpIcon = pvParam;
1191 if(lpIcon && lpIcon->cbSize == sizeof(*lpIcon))
1193 SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0,
1194 &lpIcon->iHorzSpacing, FALSE );
1195 SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0,
1196 &lpIcon->iVertSpacing, FALSE );
1197 SystemParametersInfoA( SPI_GETICONTITLEWRAP, 0,
1198 &lpIcon->iTitleWrap, FALSE );
1199 SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0,
1200 &lpIcon->lfFont, FALSE );
1202 else
1204 ret = FALSE;
1206 break;
1208 WINE_SPI_FIXME(SPI_SETICONMETRICS); /* 46 WINVER >= 0x400 */
1210 case SPI_SETWORKAREA: /* 47 WINVER >= 0x400 */
1212 char buf[20];
1213 RECT *pr = (RECT *) pvParam;
1215 spi_idx = SPI_SETWORKAREA_IDX;
1216 sprintf(buf, "%d %d %d %d",
1217 pr->left, pr->top,
1218 pr->right, pr->bottom );
1220 if (SYSPARAMS_Save( SPI_SETWORKAREA_REGKEY,
1221 SPI_SETWORKAREA_VALNAME,
1222 buf, fWinIni ))
1224 CopyRect( &work_area, (RECT *)pvParam );
1225 spi_loaded[spi_idx] = TRUE;
1227 else
1228 ret = FALSE;
1229 break;
1232 case SPI_GETWORKAREA: /* 48 WINVER >= 0x400 */
1233 spi_idx = SPI_SETWORKAREA_IDX;
1234 if (!spi_loaded[spi_idx])
1236 char buf[20];
1238 SetRect( &work_area, 0, 0,
1239 GetSystemMetrics( SM_CXSCREEN ),
1240 GetSystemMetrics( SM_CYSCREEN ) );
1242 if (SYSPARAMS_Load( SPI_SETWORKAREA_REGKEY,
1243 SPI_SETWORKAREA_VALNAME,
1244 buf ))
1246 sscanf( buf, "%d %d %d %d",
1247 &work_area.left, &work_area.top,
1248 &work_area.right, &work_area.bottom );
1250 spi_loaded[spi_idx] = TRUE;
1252 CopyRect( (RECT *)pvParam, &work_area );
1254 break;
1256 WINE_SPI_FIXME(SPI_SETPENWINDOWS); /* 49 WINVER >= 0x400 */
1258 WINE_SPI_FIXME(SPI_GETFILTERKEYS); /* 50 */
1259 WINE_SPI_FIXME(SPI_SETFILTERKEYS); /* 51 */
1260 WINE_SPI_FIXME(SPI_GETTOGGLEKEYS); /* 52 */
1261 WINE_SPI_FIXME(SPI_SETTOGGLEKEYS); /* 53 */
1262 WINE_SPI_FIXME(SPI_GETMOUSEKEYS); /* 54 */
1263 WINE_SPI_FIXME(SPI_SETMOUSEKEYS); /* 55 */
1264 case SPI_GETSHOWSOUNDS: /* 56 */
1265 spi_idx = SPI_SETSHOWSOUNDS_IDX;
1267 if (!spi_loaded[spi_idx])
1269 char buf[10];
1271 if (SYSPARAMS_Load( SPI_SETSHOWSOUNDS_REGKEY,
1272 SPI_SETSHOWSOUNDS_VALNAME, buf ))
1274 SYSMETRICS_Set( SM_SHOWSOUNDS, atoi( buf ) );
1276 spi_loaded[spi_idx] = TRUE;
1280 *(INT *)pvParam = GetSystemMetrics( SM_SHOWSOUNDS );
1281 break;
1283 case SPI_SETSHOWSOUNDS: /* 57 */
1285 char buf[10];
1286 spi_idx = SPI_SETSHOWSOUNDS_IDX;
1288 sprintf(buf, "%u", uiParam);
1289 if (SYSPARAMS_Save( SPI_SETSHOWSOUNDS_REGKEY,
1290 SPI_SETSHOWSOUNDS_VALNAME,
1291 buf, fWinIni ))
1293 SYSMETRICS_Set( SM_SHOWSOUNDS, uiParam );
1294 spi_loaded[spi_idx] = TRUE;
1296 else
1297 ret = FALSE;
1298 break;
1300 WINE_SPI_FIXME(SPI_GETSTICKYKEYS); /* 58 */
1301 WINE_SPI_FIXME(SPI_SETSTICKYKEYS); /* 59 */
1302 WINE_SPI_FIXME(SPI_GETACCESSTIMEOUT); /* 60 */
1303 WINE_SPI_FIXME(SPI_SETACCESSTIMEOUT); /* 61 */
1305 WINE_SPI_FIXME(SPI_GETSERIALKEYS); /* 62 WINVER >= 0x400 */
1306 WINE_SPI_FIXME(SPI_SETSERIALKEYS); /* 63 WINVER >= 0x400 */
1308 WINE_SPI_FIXME(SPI_GETSOUNDSENTRY); /* 64 */
1309 WINE_SPI_FIXME(SPI_SETSOUNDSENTRY); /* 65 */
1311 case SPI_GETHIGHCONTRAST: /* 66 WINVER >= 0x400 */
1313 LPHIGHCONTRASTA lpHighContrastA = (LPHIGHCONTRASTA)pvParam;
1314 WARN("SPI_GETHIGHCONTRAST not fully implemented\n");
1315 if (lpHighContrastA->cbSize == sizeof(HIGHCONTRASTA))
1317 /* Indicate that there is no high contrast available */
1318 lpHighContrastA->dwFlags = 0;
1319 lpHighContrastA->lpszDefaultScheme = NULL;
1321 else
1323 ret = FALSE;
1325 break;
1327 WINE_SPI_FIXME(SPI_SETHIGHCONTRAST); /* 67 WINVER >= 0x400 */
1329 WINE_SPI_FIXME(SPI_GETKEYBOARDPREF); /* 68 WINVER >= 0x400 */
1330 WINE_SPI_FIXME(SPI_SETKEYBOARDPREF); /* 69 WINVER >= 0x400 */
1332 case SPI_GETSCREENREADER:
1334 LPBOOL bool = (LPBOOL)pvParam;
1335 *bool = FALSE;
1336 break;
1339 WINE_SPI_FIXME(SPI_SETSCREENREADER); /* 71 WINVER >= 0x400 */
1341 case SPI_GETANIMATION: /* 72 WINVER >= 0x400 */
1343 LPANIMATIONINFO lpAnimInfo = (LPANIMATIONINFO)pvParam;
1345 /* Tell it "disabled" */
1346 if (lpAnimInfo->cbSize == sizeof(ANIMATIONINFO))
1347 lpAnimInfo->iMinAnimate = 0; /* Minimise and restore animation is disabled (nonzero == enabled) */
1348 else
1349 ret = FALSE;
1350 break;
1352 WINE_SPI_WARN(SPI_SETANIMATION); /* 73 WINVER >= 0x400 */
1354 WINE_SPI_FIXME(SPI_GETFONTSMOOTHING); /* 74 WINVER >= 0x400 */
1355 WINE_SPI_FIXME(SPI_SETFONTSMOOTHING); /* 75 WINVER >= 0x400 */
1357 WINE_SPI_FIXME(SPI_SETDRAGWIDTH); /* 76 WINVER >= 0x400 */
1358 WINE_SPI_FIXME(SPI_SETDRAGHEIGHT); /* 77 WINVER >= 0x400 */
1360 WINE_SPI_FIXME(SPI_SETHANDHELD); /* 78 WINVER >= 0x400 */
1362 WINE_SPI_FIXME(SPI_GETLOWPOWERTIMEOUT); /* 79 WINVER >= 0x400 */
1363 WINE_SPI_FIXME(SPI_GETPOWEROFFTIMEOUT); /* 80 WINVER >= 0x400 */
1364 WINE_SPI_FIXME(SPI_SETLOWPOWERTIMEOUT); /* 81 WINVER >= 0x400 */
1365 WINE_SPI_FIXME(SPI_SETPOWEROFFTIMEOUT); /* 82 WINVER >= 0x400 */
1366 WINE_SPI_FIXME(SPI_GETLOWPOWERACTIVE); /* 83 WINVER >= 0x400 */
1367 WINE_SPI_FIXME(SPI_GETPOWEROFFACTIVE); /* 84 WINVER >= 0x400 */
1368 WINE_SPI_FIXME(SPI_SETLOWPOWERACTIVE); /* 85 WINVER >= 0x400 */
1369 WINE_SPI_FIXME(SPI_SETPOWEROFFACTIVE); /* 86 WINVER >= 0x400 */
1371 WINE_SPI_FIXME(SPI_SETCURSORS); /* 87 WINVER >= 0x400 */
1372 WINE_SPI_FIXME(SPI_SETICONS); /* 88 WINVER >= 0x400 */
1374 WINE_SPI_FIXME(SPI_GETDEFAULTINPUTLANG); /* 89 WINVER >= 0x400 */
1375 WINE_SPI_FIXME(SPI_SETDEFAULTINPUTLANG); /* 90 WINVER >= 0x400 */
1377 WINE_SPI_FIXME(SPI_SETLANGTOGGLE); /* 91 WINVER >= 0x400 */
1379 case SPI_GETWINDOWSEXTENSION: /* 92 WINVER >= 0x400 */
1380 WARN("pretend no support for Win9x Plus! for now.\n");
1381 ret = FALSE; /* yes, this is the result value */
1382 break;
1384 WINE_SPI_FIXME(SPI_SETMOUSETRAILS); /* 93 WINVER >= 0x400 */
1385 WINE_SPI_FIXME(SPI_GETMOUSETRAILS); /* 94 WINVER >= 0x400 */
1387 case SPI_SETSCREENSAVERRUNNING: /* 97 WINVER >= 0x400 */
1389 /* SPI_SCREENSAVERRUNNING is an alias for SPI_SETSCREENSAVERRUNNING */
1390 char buf[5];
1392 spi_idx = SPI_SETSCREENSAVERRUNNING_IDX;
1393 sprintf(buf, "%u", uiParam);
1395 /* save only temporarily */
1396 if (SYSPARAMS_Save( SPI_SETSCREENSAVERRUNNING_REGKEY,
1397 SPI_SETSCREENSAVERRUNNING_VALNAME,
1398 buf, 0 ))
1400 screensaver_running = uiParam;
1401 spi_loaded[spi_idx] = TRUE;
1403 else
1404 ret = FALSE;
1405 break;
1408 case SPI_GETMOUSEHOVERWIDTH: /* 98 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1409 *(UINT *)pvParam = 4;
1410 break;
1411 WINE_SPI_FIXME(SPI_SETMOUSEHOVERWIDTH); /* 99 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1413 case SPI_GETMOUSEHOVERHEIGHT: /* 100 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1414 *(UINT *)pvParam = 4;
1415 break;
1416 WINE_SPI_FIXME(SPI_SETMOUSEHOVERHEIGHT); /* 101 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1418 case SPI_GETMOUSEHOVERTIME: /* 102 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1419 *(UINT *)pvParam = 400; /* default for menu dropdowns */
1420 break;
1421 WINE_SPI_FIXME(SPI_SETMOUSEHOVERTIME); /* 103 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1423 case SPI_GETWHEELSCROLLLINES: /* 104 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1424 *(UINT *)pvParam = 3; /* default for num scroll lines */
1425 break;
1427 WINE_SPI_FIXME(SPI_SETWHEELSCROLLLINES); /* 105 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1429 case SPI_GETMENUSHOWDELAY: /* 106 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1430 *(UINT *)pvParam = 400; /* Tested against Windows NT 4.0 and Windows 2000 */
1431 break;
1433 WINE_SPI_FIXME(SPI_GETSHOWIMEUI); /* 110 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1434 WINE_SPI_FIXME(SPI_SETSHOWIMEUI); /* 111 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1436 case SPI_GETSCREENSAVERRUNNING: /* 114 _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1437 spi_idx = SPI_SETSCREENSAVERRUNNING_IDX;
1438 if (!spi_loaded[spi_idx])
1440 char buf[5];
1442 if (SYSPARAMS_Load( SPI_SETSCREENSAVERRUNNING_REGKEY,
1443 SPI_SETSCREENSAVERRUNNING_VALNAME, buf ))
1444 screensaver_running = atoi( buf );
1445 spi_loaded[spi_idx] = TRUE;
1448 *(BOOL *)pvParam = screensaver_running;
1449 break;
1451 default:
1452 FIXME( "Unknown action: %u\n", uiAction );
1453 SetLastError( ERROR_INVALID_SPI_VALUE );
1454 ret = FALSE;
1455 break;
1458 if (ret)
1459 SYSPARAMS_NotifyChange( uiAction, fWinIni );
1460 return ret;
1462 #undef WINE_SPI_FIXME
1463 #undef WINE_SPI_WARN
1467 /***********************************************************************
1468 * SystemParametersInfo (USER.483)
1470 BOOL16 WINAPI SystemParametersInfo16( UINT16 uAction, UINT16 uParam,
1471 LPVOID lpvParam, UINT16 fuWinIni )
1473 BOOL16 ret;
1475 TRACE("(%u, %u, %p, %u)\n", uAction, uParam, lpvParam, fuWinIni);
1477 switch (uAction)
1479 case SPI_GETBEEP: /* 1 */
1480 case SPI_GETSCREENSAVEACTIVE: /* 16 */
1481 case SPI_GETICONTITLEWRAP: /* 25 */
1482 case SPI_GETMENUDROPALIGNMENT: /* 27 */
1483 case SPI_GETFASTTASKSWITCH: /* 35 */
1484 case SPI_GETDRAGFULLWINDOWS: /* 38 WINVER >= 0x0400 */
1486 BOOL tmp;
1487 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1488 if (ret && lpvParam)
1489 *(BOOL16 *)lpvParam = tmp;
1490 break;
1493 case SPI_GETBORDER: /* 5 */
1494 case SPI_ICONHORIZONTALSPACING: /* 13 */
1495 case SPI_GETSCREENSAVETIMEOUT: /* 14 */
1496 case SPI_GETGRIDGRANULARITY: /* 18 */
1497 case SPI_GETKEYBOARDDELAY: /* 22 */
1498 case SPI_ICONVERTICALSPACING: /* 24 */
1500 INT tmp;
1501 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1502 if (ret && lpvParam)
1503 *(INT16 *)lpvParam = tmp;
1504 break;
1507 case SPI_GETKEYBOARDSPEED: /* 10 */
1509 DWORD tmp;
1510 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1511 if (ret && lpvParam)
1512 *(WORD *)lpvParam = tmp;
1513 break;
1516 case SPI_GETICONTITLELOGFONT: /* 31 */
1518 LOGFONTA tmp;
1519 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1520 if (ret && lpvParam)
1521 SYSPARAMS_LogFont32ATo16( &tmp, (LPLOGFONT16)lpvParam );
1522 break;
1525 case SPI_GETNONCLIENTMETRICS: /* 41 WINVER >= 0x400 */
1527 NONCLIENTMETRICSA tmp;
1528 LPNONCLIENTMETRICS16 lpnm16 = (LPNONCLIENTMETRICS16)lpvParam;
1529 if (lpnm16 && lpnm16->cbSize == sizeof(NONCLIENTMETRICS16))
1531 tmp.cbSize = sizeof(NONCLIENTMETRICSA);
1532 ret = SystemParametersInfoA( uAction, uParam, &tmp, fuWinIni );
1533 if (ret)
1534 SYSPARAMS_NonClientMetrics32ATo16( &tmp, lpnm16 );
1536 else /* winfile 95 sets cbSize to 340 */
1537 ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
1538 break;
1541 case SPI_GETWORKAREA: /* 48 WINVER >= 0x400 */
1543 RECT tmp;
1544 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1545 if (ret && lpvParam)
1546 CONV_RECT32TO16( &tmp, (RECT16 *)lpvParam );
1547 break;
1550 case SPI_GETMOUSEHOVERWIDTH: /* 98 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1551 case SPI_GETMOUSEHOVERHEIGHT: /* 100 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1552 case SPI_GETMOUSEHOVERTIME: /* 102 _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1554 UINT tmp;
1555 ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1556 if (ret && lpvParam)
1557 *(UINT16 *)lpvParam = tmp;
1558 break;
1561 default:
1562 ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
1565 return ret;
1568 /***********************************************************************
1569 * SystemParametersInfoW (USER32.@)
1571 BOOL WINAPI SystemParametersInfoW( UINT uiAction, UINT uiParam,
1572 PVOID pvParam, UINT fuWinIni )
1574 BOOL ret;
1576 TRACE("(%u, %u, %p, %u)\n", uiAction, uiParam, pvParam, fuWinIni);
1578 switch (uiAction)
1580 case SPI_SETDESKWALLPAPER: /* 20 */
1581 case SPI_SETDESKPATTERN: /* 21 */
1583 char buffer[256];
1584 if (pvParam)
1585 if (!WideCharToMultiByte( CP_ACP, 0, (LPWSTR)pvParam, -1,
1586 buffer, sizeof(buffer), NULL, NULL ))
1587 buffer[sizeof(buffer)-1] = 0;
1588 ret = SystemParametersInfoA( uiAction, uiParam, pvParam ? buffer : NULL, fuWinIni );
1589 break;
1592 case SPI_GETICONTITLELOGFONT: /* 31 */
1594 LOGFONTA tmp;
1595 ret = SystemParametersInfoA( uiAction, uiParam, pvParam ? &tmp : NULL, fuWinIni );
1596 if (ret && pvParam)
1597 SYSPARAMS_LogFont32ATo32W( &tmp, (LPLOGFONTW)pvParam );
1598 break;
1601 case SPI_GETNONCLIENTMETRICS: /* 41 WINVER >= 0x400 */
1603 NONCLIENTMETRICSA tmp;
1604 LPNONCLIENTMETRICSW lpnmW = (LPNONCLIENTMETRICSW)pvParam;
1605 if (lpnmW && lpnmW->cbSize == sizeof(NONCLIENTMETRICSW))
1607 tmp.cbSize = sizeof(NONCLIENTMETRICSA);
1608 ret = SystemParametersInfoA( uiAction, uiParam, &tmp, fuWinIni );
1609 if (ret)
1610 SYSPARAMS_NonClientMetrics32ATo32W( &tmp, lpnmW );
1612 else
1613 ret = FALSE;
1614 break;
1617 case SPI_GETICONMETRICS: /* 45 WINVER >= 0x400 */
1619 ICONMETRICSA tmp;
1620 LPICONMETRICSW lpimW = (LPICONMETRICSW)pvParam;
1621 if (lpimW && lpimW->cbSize == sizeof(ICONMETRICSW))
1623 tmp.cbSize = sizeof(ICONMETRICSA);
1624 ret = SystemParametersInfoA( uiAction, uiParam, &tmp, fuWinIni );
1625 if (ret)
1627 lpimW->iHorzSpacing = tmp.iHorzSpacing;
1628 lpimW->iVertSpacing = tmp.iVertSpacing;
1629 lpimW->iTitleWrap = tmp.iTitleWrap;
1630 SYSPARAMS_LogFont32ATo32W( &tmp.lfFont, &lpimW->lfFont );
1633 else
1634 ret = FALSE;
1635 break;
1638 case SPI_GETHIGHCONTRAST: /* 66 WINVER >= 0x400 */
1640 HIGHCONTRASTA tmp;
1641 LPHIGHCONTRASTW lphcW = (LPHIGHCONTRASTW)pvParam;
1642 if (lphcW && lphcW->cbSize == sizeof(HIGHCONTRASTW))
1644 tmp.cbSize = sizeof(HIGHCONTRASTA);
1645 ret = SystemParametersInfoA( uiAction, uiParam, &tmp, fuWinIni );
1646 if (ret)
1648 lphcW->dwFlags = tmp.dwFlags;
1649 lphcW->lpszDefaultScheme = NULL; /* FIXME? */
1652 else
1653 ret = FALSE;
1654 break;
1657 default:
1658 ret = SystemParametersInfoA( uiAction, uiParam, pvParam, fuWinIni );
1659 break;
1661 return ret;
1665 /**********************************************************************
1666 * SetDoubleClickTime (USER32.@)
1668 BOOL WINAPI SetDoubleClickTime( UINT interval )
1670 return SystemParametersInfoA(SPI_SETDOUBLECLICKTIME, interval, 0, 0);
1674 /**********************************************************************
1675 * GetDoubleClickTime (USER32.@)
1677 UINT WINAPI GetDoubleClickTime(void)
1679 char buf[10];
1681 if (!spi_loaded[SPI_SETDOUBLECLICKTIME_IDX])
1683 if (SYSPARAMS_Load( SPI_SETDOUBLECLICKTIME_REGKEY,
1684 SPI_SETDOUBLECLICKTIME_VALNAME,
1685 buf ))
1687 double_click_time = atoi( buf );
1688 if (!double_click_time) double_click_time = 500;
1690 spi_loaded[SPI_SETDOUBLECLICKTIME_IDX] = TRUE;
1692 return double_click_time;