SetMenu should always call SetWindowPos whether the window is visible
[wine] / windows / sysparams.c
1 /*
2  * System parameters functions
3  *
4  * Copyright 1994 Alexandre Julliard
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include "config.h"
22
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"
34
35 #include "controls.h"
36 #include "user.h"
37 #include "wine/debug.h"
38
39 WINE_DEFAULT_DEBUG_CHANNEL(system);
40
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
68
69 #define SPI_WINE_IDX                            SPI_SETSCREENSAVERRUNNING_IDX
70
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.
77  */
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"
130
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"
138
139 /* volatile registry branch under CURRENT_USER_REGKEY for temporary values storage */
140 #define WINE_CURRENT_USER_REGKEY     "Wine"
141
142 /* Indicators whether system parameter value is loaded */
143 static char spi_loaded[SPI_WINE_IDX + 1];
144
145 static BOOL notify_change = TRUE;
146
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;
169
170 /***********************************************************************
171  *              GetTimerResolution (USER.14)
172  */
173 LONG WINAPI GetTimerResolution16(void)
174 {
175         return (1000);
176 }
177
178 /***********************************************************************
179  *              ControlPanelInfo (USER.273)
180  */
181 void WINAPI ControlPanelInfo16( INT16 nInfoType, WORD wData, LPSTR lpBuffer )
182 {
183         FIXME("(%d, %04x, %p): stub.\n", nInfoType, wData, lpBuffer);
184 }
185
186 /* This function is a copy of the one in objects/font.c */
187 static void SYSPARAMS_LogFont32ATo16( const LOGFONTA* font32, LPLOGFONT16 font16 )
188 {
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 );
203 }
204
205 static void SYSPARAMS_LogFont32ATo32W( const LOGFONTA* font32A, LPLOGFONTW font32W )
206 {
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;
222 }
223
224 static void SYSPARAMS_NonClientMetrics32ATo16( const NONCLIENTMETRICSA* lpnm32, LPNONCLIENTMETRICS16 lpnm16 )
225 {
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 );
240 }
241
242 static void SYSPARAMS_NonClientMetrics32ATo32W( const NONCLIENTMETRICSA* lpnm32A, LPNONCLIENTMETRICSW lpnm32W )
243 {
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 );
258 }
259
260 /***********************************************************************
261  *           SYSPARAMS_Reset
262  *
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.
267  *
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.
272  */
273 void SYSPARAMS_Reset( UINT uiAction )
274 {
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
281
282 #define WINE_IGNORE_SPI(x) \
283     case x: \
284         if (uiAction) \
285             break
286
287 #define WINE_INVALIDATE_SPI(x) \
288     case x: \
289         spi_loaded[x##_IDX] = FALSE; \
290         break
291
292     BOOL not_all_processed = TRUE;
293     char dummy_buf[10];
294
295     /* Execution falls through all the branches for uiAction == 0 */
296     switch (uiAction)
297     {
298     case 0:
299         memset( spi_loaded, 0, sizeof(spi_loaded) );
300
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);
310
311     default:
312         if (uiAction)
313         {
314             /* lazy loaded parameters */
315             switch (uiAction)
316             {
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;
333             }
334         }
335         else
336             not_all_processed = FALSE;
337         break;
338     }
339
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
346 }
347
348 /***********************************************************************
349  *           get_volatile_regkey
350  *
351  * Return a handle to the volatile registry key used to store
352  * non-permanently modified parameters.
353  */
354 static HKEY get_volatile_regkey(void)
355 {
356     static HKEY volatile_key;
357
358     if (!volatile_key)
359     {
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");
364     }
365     return volatile_key;
366 }
367
368 /***********************************************************************
369  *           SYSPARAMS_NotifyChange
370  *
371  * Sends notification about system parameter update.
372  */
373 void SYSPARAMS_NotifyChange( UINT uiAction, UINT fWinIni )
374 {
375     static const WCHAR emptyW[1];
376
377     if (notify_change)
378     {
379         if (fWinIni & SPIF_UPDATEINIFILE)
380         {
381             if (fWinIni & (SPIF_SENDWININICHANGE | SPIF_SENDCHANGE))
382                 SendMessageTimeoutW(HWND_BROADCAST, WM_SETTINGCHANGE,
383                                     uiAction, (LPARAM) emptyW,
384                                     SMTO_ABORTIFHUNG, 2000, NULL );
385         }
386         else
387         {
388             /* FIXME notify other wine processes with internal message */
389         }
390     }
391 }
392
393
394 /***********************************************************************
395  * Loads system parameter from user profile.
396  */
397 static BOOL SYSPARAMS_Load( LPCSTR lpRegKey, LPCSTR lpValName, LPSTR lpBuf, DWORD count )
398 {
399     BOOL ret = FALSE;
400     DWORD type;
401     HKEY hKey;
402
403     if ((RegOpenKeyA( get_volatile_regkey(), lpRegKey, &hKey ) == ERROR_SUCCESS) ||
404         (RegOpenKeyA( HKEY_CURRENT_USER, lpRegKey, &hKey ) == ERROR_SUCCESS))
405     {
406         ret = !RegQueryValueExA( hKey, lpValName, NULL, &type, lpBuf, &count );
407         RegCloseKey( hKey );
408     }
409     return ret;
410 }
411
412 /***********************************************************************
413  * Saves system parameter to user profile.
414  */
415 static BOOL SYSPARAMS_Save( LPCSTR lpRegKey, LPCSTR lpValName, LPCSTR lpValue,
416                             UINT fWinIni )
417 {
418     HKEY hKey;
419     HKEY hBaseKey;
420     DWORD dwOptions;
421     BOOL ret = FALSE;
422
423     if (fWinIni & SPIF_UPDATEINIFILE)
424     {
425         hBaseKey = HKEY_CURRENT_USER;
426         dwOptions = 0;
427     }
428     else
429     {
430         hBaseKey = get_volatile_regkey();
431         dwOptions = REG_OPTION_VOLATILE;
432     }
433
434     if (RegCreateKeyExA( hBaseKey, lpRegKey,
435                          0, 0, dwOptions, KEY_ALL_ACCESS,
436                          0, &hKey, 0 ) == ERROR_SUCCESS)
437     {
438         if (RegSetValueExA( hKey, lpValName, 0, REG_SZ,
439                             lpValue, strlen(lpValue) + 1 ) == ERROR_SUCCESS)
440         {
441             ret = TRUE;
442             if (hBaseKey == HKEY_CURRENT_USER)
443                 RegDeleteKeyA( get_volatile_regkey(), lpRegKey );
444         }
445         RegCloseKey( hKey );
446     }
447     return ret;
448 }
449
450
451 /***********************************************************************
452  *           SYSPARAMS_GetDoubleClickSize
453  *
454  * There is no SPI_GETDOUBLECLK* so we export this function instead.
455  */
456 void SYSPARAMS_GetDoubleClickSize( INT *width, INT *height )
457 {
458     char buf[10];
459
460     if (!spi_loaded[SPI_SETDOUBLECLKWIDTH_IDX])
461     {
462         char buf[10];
463
464         if (SYSPARAMS_Load( SPI_SETDOUBLECLKWIDTH_REGKEY1,
465                             SPI_SETDOUBLECLKWIDTH_VALNAME, buf, sizeof(buf) ))
466         {
467             SYSMETRICS_Set( SM_CXDOUBLECLK, atoi( buf ) );
468         }
469         spi_loaded[SPI_SETDOUBLECLKWIDTH_IDX] = TRUE;
470     }
471     if (!spi_loaded[SPI_SETDOUBLECLKHEIGHT_IDX])
472     {
473         if (SYSPARAMS_Load( SPI_SETDOUBLECLKHEIGHT_REGKEY1,
474                             SPI_SETDOUBLECLKHEIGHT_VALNAME, buf, sizeof(buf) ))
475         {
476             SYSMETRICS_Set( SM_CYDOUBLECLK, atoi( buf ) );
477         }
478         spi_loaded[SPI_SETDOUBLECLKHEIGHT_IDX] = TRUE;
479     }
480     *width  = GetSystemMetrics( SM_CXDOUBLECLK );
481     *height = GetSystemMetrics( SM_CYDOUBLECLK );
482 }
483
484
485 /***********************************************************************
486  *           SYSPARAMS_GetMouseButtonSwap
487  *
488  * There is no SPI_GETMOUSEBUTTONSWAP so we export this function instead.
489  */
490 INT SYSPARAMS_GetMouseButtonSwap( void )
491 {
492         int spi_idx = SPI_SETMOUSEBUTTONSWAP_IDX;
493
494         if (!spi_loaded[spi_idx])
495         {
496             char buf[5];
497
498             if (SYSPARAMS_Load( SPI_SETMOUSEBUTTONSWAP_REGKEY,
499                                 SPI_SETMOUSEBUTTONSWAP_VALNAME, buf, sizeof(buf) ))
500             {
501                 SYSMETRICS_Set( SM_SWAPBUTTON, atoi( buf ) );
502             }
503             spi_loaded[spi_idx] = TRUE;
504         }
505
506         return GetSystemMetrics( SM_SWAPBUTTON );
507 }
508
509 /***********************************************************************
510  *
511  *      SYSPARAMS_GetGUIFont
512  *
513  *  fills LOGFONT with 'default GUI font'.
514  */
515
516 static void SYSPARAMS_GetGUIFont( LOGFONTA* plf )
517 {
518         HFONT   hf;
519
520         memset( plf, 0, sizeof(LOGFONTA) );
521         hf = (HFONT)GetStockObject( DEFAULT_GUI_FONT );
522         if ( GetObjectA( hf, sizeof(LOGFONTA), plf ) != sizeof(LOGFONTA) )
523         {
524                 /*
525                  * GetObjectA() would be succeeded always
526                  * since this is a stock object
527                  */
528                 ERR("GetObjectA() failed\n");
529         }
530 }
531
532 /* copied from GetSystemMetrics()'s RegistryTwips2Pixels() */
533 inline static int SYSPARAMS_Twips2Pixels(int x)
534 {
535     if (x < 0)
536         x = (-x+7)/15;
537     return x;
538 }
539
540 /***********************************************************************
541  *              SystemParametersInfoA (USER32.@)
542  *
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
560  *
561  * Some SPI values can also be stored as Twips values in the registry,
562  * don't forget the conversion!
563  */
564 BOOL WINAPI SystemParametersInfoA( UINT uiAction, UINT uiParam,
565                                    PVOID pvParam, UINT fWinIni )
566 {
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
577
578     BOOL ret = TRUE;
579     unsigned spi_idx = 0;
580
581     TRACE("(%u, %u, %p, %u)\n", uiAction, uiParam, pvParam, fWinIni);
582
583     switch (uiAction)
584     {
585     case SPI_GETBEEP:                           /*      1 */
586         if (!pvParam) return FALSE;
587
588         spi_idx = SPI_SETBEEP_IDX;
589         if (!spi_loaded[spi_idx])
590         {
591             char buf[5];
592
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;
596         }
597
598         *(BOOL *)pvParam = beep_active;
599         break;
600
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 ))
605         {
606             beep_active = uiParam;
607             spi_loaded[spi_idx] = TRUE;
608         }
609         else
610             ret = FALSE;
611         break;
612
613     case SPI_GETMOUSE:                          /*      3 */
614         if (!pvParam) return FALSE;
615
616         spi_idx = SPI_SETMOUSE_IDX;
617         if (!spi_loaded[spi_idx])
618         {
619             char buf[10];
620
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;
631         }
632         ((INT *)pvParam)[0] = mouse_threshold1;
633         ((INT *)pvParam)[1] = mouse_threshold2;
634         ((INT *)pvParam)[2] = mouse_speed;
635         break;
636
637     case SPI_SETMOUSE:                          /*      4 */
638     {
639         char buf[10];
640
641         if (!pvParam) return FALSE;
642
643         spi_idx = SPI_SETMOUSE_IDX;
644         sprintf(buf, "%d", ((INT *)pvParam)[0]);
645
646         if (SYSPARAMS_Save( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME1,
647                             buf, fWinIni ))
648         {
649             mouse_threshold1 = ((INT *)pvParam)[0];
650             spi_loaded[spi_idx] = TRUE;
651
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];
656
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];
661         }
662         else
663             ret = FALSE;
664         break;
665     }
666
667     case SPI_GETBORDER:                         /*      5 */
668         if (!pvParam) return FALSE;
669
670         spi_idx = SPI_SETBORDER_IDX;
671         if (!spi_loaded[spi_idx])
672         {
673             char buf[10];
674
675             if (SYSPARAMS_Load( SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME, buf, sizeof(buf) ))
676                 border = SYSPARAMS_Twips2Pixels( atoi(buf) );
677
678             spi_loaded[spi_idx] = TRUE;
679             if (TWEAK_WineLook > WIN31_LOOK)
680             {
681                 SYSMETRICS_Set( SM_CXFRAME, border + GetSystemMetrics( SM_CXDLGFRAME ) );
682                 SYSMETRICS_Set( SM_CYFRAME, border + GetSystemMetrics( SM_CXDLGFRAME ) );
683             }
684         }
685         *(INT *)pvParam = border;
686         break;
687
688     case SPI_SETBORDER:                         /*      6 */
689     {
690         char buf[10];
691
692         spi_idx = SPI_SETBORDER_IDX;
693         sprintf(buf, "%u", uiParam);
694
695         if (SYSPARAMS_Save( SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME,
696                             buf, fWinIni ))
697         {
698             if (uiParam > 0)
699             {
700                 border = uiParam;
701                 spi_loaded[spi_idx] = TRUE;
702                 if (TWEAK_WineLook > WIN31_LOOK)
703                 {
704                     SYSMETRICS_Set( SM_CXFRAME, uiParam + GetSystemMetrics( SM_CXDLGFRAME ) );
705                     SYSMETRICS_Set( SM_CYFRAME, uiParam + GetSystemMetrics( SM_CXDLGFRAME ) );
706                 }
707             }
708         }
709         else
710             ret = FALSE;
711         break;
712     }
713
714     case SPI_GETKEYBOARDSPEED:                  /*     10 */
715         if (!pvParam) return FALSE;
716
717         spi_idx = SPI_SETKEYBOARDSPEED_IDX;
718         if (!spi_loaded[spi_idx])
719         {
720             char buf[10];
721
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;
727         }
728         *(INT *)pvParam = keyboard_speed;
729         break;
730
731     case SPI_SETKEYBOARDSPEED:                  /*     11 */
732     {
733         char buf[10];
734
735         spi_idx = SPI_SETKEYBOARDSPEED_IDX;
736         if (uiParam > 31)
737             uiParam = 31;
738         sprintf(buf, "%u", uiParam);
739
740         if (SYSPARAMS_Save( SPI_SETKEYBOARDSPEED_REGKEY,
741                             SPI_SETKEYBOARDSPEED_VALNAME,
742                             buf, fWinIni ))
743         {
744             keyboard_speed = uiParam;
745             spi_loaded[spi_idx] = TRUE;
746         }
747         else
748             ret = FALSE;
749         break;
750     }
751
752     /* not implemented in Windows */
753     WINE_SPI_WARN(SPI_LANGDRIVER);              /*     12 */
754
755     case SPI_ICONHORIZONTALSPACING:             /*     13 */
756         spi_idx = SPI_ICONHORIZONTALSPACING_IDX;
757         if (pvParam != NULL)
758         {
759             if (!spi_loaded[spi_idx])
760             {
761                 char buf[10];
762                 int val;
763
764                 if (SYSPARAMS_Load( SPI_ICONHORIZONTALSPACING_REGKEY,
765                                     SPI_ICONHORIZONTALSPACING_VALNAME, buf, sizeof(buf) ))
766                 {
767                     val = SYSPARAMS_Twips2Pixels( atoi(buf) );
768                     SYSMETRICS_Set( SM_CXICONSPACING, val );
769                 }
770                 spi_loaded[spi_idx] = TRUE;
771             }
772
773             *(INT *)pvParam = GetSystemMetrics( SM_CXICONSPACING );
774         }
775         else
776         {
777             char buf[10];
778
779             if (uiParam < 32) uiParam = 32;
780
781             sprintf(buf, "%u", uiParam);
782             if (SYSPARAMS_Save( SPI_ICONHORIZONTALSPACING_REGKEY,
783                                 SPI_ICONHORIZONTALSPACING_VALNAME,
784                                 buf, fWinIni ))
785             {
786                 SYSMETRICS_Set( SM_CXICONSPACING, uiParam );
787                 spi_loaded[spi_idx] = TRUE;
788             }
789             else
790                 ret = FALSE;
791         }
792         break;
793
794     case SPI_GETSCREENSAVETIMEOUT:              /*     14 */
795         if (!pvParam) return FALSE;
796
797         spi_idx = SPI_SETSCREENSAVETIMEOUT_IDX;
798         if (!spi_loaded[spi_idx])
799         {
800             char buf[10];
801
802             if (SYSPARAMS_Load( SPI_SETSCREENSAVETIMEOUT_REGKEY,
803                                 SPI_SETSCREENSAVETIMEOUT_VALNAME,
804                                 buf, sizeof(buf) ))
805                 screensave_timeout = atoi( buf );
806
807             spi_loaded[spi_idx] = TRUE;
808         }
809         *(INT *)pvParam = screensave_timeout;
810         break;
811
812     case SPI_SETSCREENSAVETIMEOUT:              /*     15 */
813     {
814         char buf[10];
815
816         spi_idx = SPI_SETSCREENSAVETIMEOUT_IDX;
817         sprintf(buf, "%u", uiParam);
818
819         if (SYSPARAMS_Save( SPI_SETSCREENSAVETIMEOUT_REGKEY,
820                             SPI_SETSCREENSAVETIMEOUT_VALNAME,
821                             buf, fWinIni ))
822         {
823             screensave_timeout = uiParam;
824             spi_loaded[spi_idx] = TRUE;
825         }
826         else
827             ret = FALSE;
828         break;
829     }
830
831     case SPI_GETSCREENSAVEACTIVE:               /*     16 */
832         if (!pvParam) return FALSE;
833         *(BOOL *)pvParam = USER_Driver.pGetScreenSaveActive();
834         break;
835
836     case SPI_SETSCREENSAVEACTIVE:               /*     17 */
837     {
838         char buf[5];
839
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;
847     }
848
849     case SPI_GETGRIDGRANULARITY:                /*     18 */
850         if (!pvParam) return FALSE;
851
852         spi_idx = SPI_SETGRIDGRANULARITY_IDX;
853         if (!spi_loaded[spi_idx])
854         {
855             char buf[10];
856
857             if (SYSPARAMS_Load( SPI_SETGRIDGRANULARITY_REGKEY,
858                                 SPI_SETGRIDGRANULARITY_VALNAME,
859                                 buf, sizeof(buf) ))
860                 grid_granularity = atoi( buf );
861
862             spi_loaded[spi_idx] = TRUE;
863         }
864         *(INT *)pvParam = grid_granularity;
865         break;
866
867     case SPI_SETGRIDGRANULARITY:                /*     19 */
868     {
869         char buf[10];
870
871         spi_idx = SPI_SETGRIDGRANULARITY_IDX;
872         sprintf(buf, "%u", uiParam);
873
874         if (SYSPARAMS_Save( SPI_SETGRIDGRANULARITY_REGKEY,
875                             SPI_SETGRIDGRANULARITY_VALNAME,
876                             buf, fWinIni ))
877         {
878             grid_granularity = uiParam;
879             spi_loaded[spi_idx] = TRUE;
880         }
881         else
882             ret = FALSE;
883         break;
884     }
885
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)
894         {
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;
903
904     case SPI_GETKEYBOARDDELAY:                  /*     22 */
905         if (!pvParam) return FALSE;
906
907         spi_idx = SPI_SETKEYBOARDDELAY_IDX;
908         if (!spi_loaded[spi_idx])
909         {
910             char buf[10];
911
912             if (SYSPARAMS_Load( SPI_SETKEYBOARDDELAY_REGKEY,
913                                 SPI_SETKEYBOARDDELAY_VALNAME,
914                                 buf, sizeof(buf) ))
915             {
916                 int i = atoi( buf );
917                 if ( (i >= 0) && (i <= 3)) keyboard_delay = i;
918             }
919
920             spi_loaded[spi_idx] = TRUE;
921         }
922         *(INT *)pvParam = keyboard_delay;
923         break;
924
925     case SPI_SETKEYBOARDDELAY:                  /*     23 */
926     {
927         char buf[10];
928
929         spi_idx = SPI_SETKEYBOARDDELAY_IDX;
930         sprintf(buf, "%u", uiParam);
931
932         if (SYSPARAMS_Save( SPI_SETKEYBOARDDELAY_REGKEY,
933                             SPI_SETKEYBOARDDELAY_VALNAME,
934                             buf, fWinIni ))
935         {
936             if (uiParam <= 3)
937                 keyboard_delay = uiParam;
938             spi_loaded[spi_idx] = TRUE;
939         }
940         else
941             ret = FALSE;
942         break;
943     }
944
945     case SPI_ICONVERTICALSPACING:               /*     24 */
946         spi_idx = SPI_ICONVERTICALSPACING_IDX;
947         if (pvParam != NULL)
948         {
949             if (!spi_loaded[spi_idx])
950             {
951                 char buf[10];
952                 int val;
953
954                 if (SYSPARAMS_Load( SPI_ICONVERTICALSPACING_REGKEY,
955                                     SPI_ICONVERTICALSPACING_VALNAME, buf, sizeof(buf) ))
956                 {
957                     val = SYSPARAMS_Twips2Pixels( atoi(buf) );
958                     SYSMETRICS_Set( SM_CYICONSPACING, val );
959                 }
960                 spi_loaded[spi_idx] = TRUE;
961             }
962
963             *(INT *)pvParam = GetSystemMetrics( SM_CYICONSPACING );
964         }
965         else
966         {
967             char buf[10];
968
969             if (uiParam < 32) uiParam = 32;
970
971             sprintf(buf, "%u", uiParam);
972             if (SYSPARAMS_Save( SPI_ICONVERTICALSPACING_REGKEY,
973                                 SPI_ICONVERTICALSPACING_VALNAME,
974                                 buf, fWinIni ))
975             {
976                 SYSMETRICS_Set( SM_CYICONSPACING, uiParam );
977                 spi_loaded[spi_idx] = TRUE;
978             }
979             else
980                 ret = FALSE;
981         }
982
983         break;
984
985     case SPI_GETICONTITLEWRAP:                  /*     25 */
986         if (!pvParam) return FALSE;
987
988         spi_idx = SPI_SETICONTITLEWRAP_IDX;
989         if (!spi_loaded[spi_idx])
990         {
991             char buf[5];
992
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;
997         }
998
999         *(BOOL *)pvParam = icon_title_wrap;
1000         break;
1001
1002     case SPI_SETICONTITLEWRAP:                  /*     26 */
1003     {
1004         char buf[5];
1005
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 ))
1011         {
1012             SYSPARAMS_Save( SPI_SETICONTITLEWRAP_REGKEY2,
1013                             SPI_SETICONTITLEWRAP_VALNAME,
1014                             buf, fWinIni );
1015             icon_title_wrap = uiParam;
1016             spi_loaded[spi_idx] = TRUE;
1017         }
1018         else
1019             ret = FALSE;
1020         break;
1021     }
1022
1023     case SPI_GETMENUDROPALIGNMENT:              /*     27 */
1024         if (!pvParam) return FALSE;
1025
1026         spi_idx = SPI_SETMENUDROPALIGNMENT_IDX;
1027
1028         if (!spi_loaded[spi_idx])
1029         {
1030             char buf[5];
1031
1032             if (SYSPARAMS_Load( SPI_SETMENUDROPALIGNMENT_REGKEY1,
1033                                 SPI_SETMENUDROPALIGNMENT_VALNAME, buf, sizeof(buf) ))
1034             {
1035                 SYSMETRICS_Set( SM_MENUDROPALIGNMENT, atoi( buf ) );
1036             }
1037             spi_loaded[spi_idx] = TRUE;
1038         }
1039
1040         *(BOOL *)pvParam = GetSystemMetrics( SM_MENUDROPALIGNMENT );
1041         break;
1042
1043     case SPI_SETMENUDROPALIGNMENT:              /*     28 */
1044     {
1045         char buf[5];
1046         spi_idx = SPI_SETMENUDROPALIGNMENT_IDX;
1047
1048         sprintf(buf, "%u", uiParam);
1049         if (SYSPARAMS_Save( SPI_SETMENUDROPALIGNMENT_REGKEY1,
1050                             SPI_SETMENUDROPALIGNMENT_VALNAME,
1051                             buf, fWinIni ))
1052         {
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;
1058         }
1059         else
1060             ret = FALSE;
1061         break;
1062     }
1063
1064     case SPI_SETDOUBLECLKWIDTH:                 /*     29 */
1065     {
1066         char buf[10];
1067         spi_idx = SPI_SETDOUBLECLKWIDTH_IDX;
1068
1069         sprintf(buf, "%u", uiParam);
1070         if (SYSPARAMS_Save( SPI_SETDOUBLECLKWIDTH_REGKEY1,
1071                             SPI_SETDOUBLECLKWIDTH_VALNAME,
1072                             buf, fWinIni ))
1073         {
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;
1079         }
1080         else
1081             ret = FALSE;
1082         break;
1083     }
1084
1085     case SPI_SETDOUBLECLKHEIGHT:                /*     30 */
1086     {
1087         char buf[10];
1088         spi_idx = SPI_SETDOUBLECLKHEIGHT_IDX;
1089
1090         sprintf(buf, "%u", uiParam);
1091         if (SYSPARAMS_Save( SPI_SETDOUBLECLKHEIGHT_REGKEY1,
1092                             SPI_SETDOUBLECLKHEIGHT_VALNAME,
1093                             buf, fWinIni ))
1094         {
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;
1100         }
1101         else
1102             ret = FALSE;
1103         break;
1104     }
1105
1106     case SPI_GETICONTITLELOGFONT:               /*     31 */
1107     {
1108         LPLOGFONTA lpLogFont = (LPLOGFONTA)pvParam;
1109         LOGFONTA        lfDefault;
1110
1111         if (!pvParam) return FALSE;
1112
1113         /*
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.
1117          */
1118         SYSPARAMS_GetGUIFont( &lfDefault );
1119
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;
1136     }
1137
1138     case SPI_SETDOUBLECLICKTIME:                /*     32 */
1139     {
1140         char buf[10];
1141
1142         spi_idx = SPI_SETDOUBLECLICKTIME_IDX;
1143         sprintf(buf, "%u", uiParam);
1144
1145         if (SYSPARAMS_Save( SPI_SETDOUBLECLICKTIME_REGKEY,
1146                             SPI_SETDOUBLECLICKTIME_VALNAME,
1147                             buf, fWinIni ))
1148         {
1149             if (!uiParam)
1150                 uiParam = 500;
1151             double_click_time = uiParam;
1152             spi_loaded[spi_idx] = TRUE;
1153         }
1154         else
1155             ret = FALSE;
1156         break;
1157     }
1158
1159     case SPI_SETMOUSEBUTTONSWAP:                /*     33 */
1160     {
1161         char buf[5];
1162         spi_idx = SPI_SETMOUSEBUTTONSWAP_IDX;
1163
1164         sprintf(buf, "%u", uiParam);
1165         if (SYSPARAMS_Save( SPI_SETMOUSEBUTTONSWAP_REGKEY,
1166                             SPI_SETMOUSEBUTTONSWAP_VALNAME,
1167                             buf, fWinIni ))
1168         {
1169             SYSMETRICS_Set( SM_SWAPBUTTON, uiParam );
1170             spi_loaded[spi_idx] = TRUE;
1171         }
1172         else
1173             ret = FALSE;
1174         break;
1175     }
1176
1177     WINE_SPI_FIXME(SPI_SETICONTITLELOGFONT);    /*     34 */
1178
1179     case SPI_GETFASTTASKSWITCH:                 /*     35 */
1180         if (!pvParam) return FALSE;
1181         *(BOOL *)pvParam = 1;
1182         break;
1183
1184     case SPI_SETFASTTASKSWITCH:                 /*     36 */
1185         /* the action is disabled */
1186         ret = FALSE;
1187         break;
1188
1189     case SPI_SETDRAGFULLWINDOWS:                /*     37  WINVER >= 0x0400 */
1190     {
1191         char buf[5];
1192
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 ))
1198         {
1199             drag_full_windows = uiParam;
1200             spi_loaded[spi_idx] = TRUE;
1201         }
1202         else
1203             ret = FALSE;
1204         break;
1205     }
1206
1207     case SPI_GETDRAGFULLWINDOWS:                /*     38  WINVER >= 0x0400 */
1208         if (!pvParam) return FALSE;
1209
1210         spi_idx = SPI_SETDRAGFULLWINDOWS_IDX;
1211         if (!spi_loaded[spi_idx])
1212         {
1213             char buf[5];
1214
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;
1219         }
1220
1221         *(BOOL *)pvParam = drag_full_windows;
1222         break;
1223
1224     case SPI_GETNONCLIENTMETRICS:               /*     41  WINVER >= 0x400 */
1225     {
1226         LPNONCLIENTMETRICSA lpnm = (LPNONCLIENTMETRICSA)pvParam;
1227
1228         if (!pvParam) return FALSE;
1229
1230         if (lpnm->cbSize == sizeof(NONCLIENTMETRICSA))
1231         {
1232             /* clear the struct, so we have 'sane' members */
1233             memset(
1234                 (char *)pvParam + sizeof(lpnm->cbSize),
1235                 0,
1236                 lpnm->cbSize - sizeof(lpnm->cbSize)
1237                 );
1238
1239             /* initialize geometry entries */
1240             lpnm->iBorderWidth = 1;
1241             lpnm->iScrollWidth = GetSystemMetrics(SM_CXVSCROLL);
1242             lpnm->iScrollHeight = GetSystemMetrics(SM_CYHSCROLL);
1243
1244             /* size of the normal caption buttons */
1245             lpnm->iCaptionWidth = GetSystemMetrics(SM_CXSIZE);
1246             lpnm->iCaptionHeight = GetSystemMetrics(SM_CYSIZE);
1247
1248             /* caption font metrics */
1249             SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0, (LPVOID)&(lpnm->lfCaptionFont), 0 );
1250             lpnm->lfCaptionFont.lfWeight = FW_BOLD;
1251
1252             /* size of the small caption buttons */
1253             lpnm->iSmCaptionWidth = GetSystemMetrics(SM_CXSMSIZE);
1254             lpnm->iSmCaptionHeight = GetSystemMetrics(SM_CYSMSIZE);
1255
1256             /* small caption font metrics */
1257             SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0, (LPVOID)&(lpnm->lfSmCaptionFont), 0 );
1258
1259             /* menus, FIXME: names of wine.conf entries are bogus */
1260
1261             /* size of the menu (MDI) buttons */
1262             lpnm->iMenuWidth = GetSystemMetrics(SM_CXMENUSIZE);
1263             lpnm->iMenuHeight = GetSystemMetrics(SM_CYMENUSIZE);
1264
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;
1272
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 );
1279         }
1280         else
1281         {
1282             WARN("size mismatch !! (is %d; should be %d)\n", lpnm->cbSize, sizeof(NONCLIENTMETRICSA));
1283             /* FIXME: SetLastError? */
1284             ret = FALSE;
1285         }
1286         break;
1287     }
1288     WINE_SPI_FIXME(SPI_SETNONCLIENTMETRICS);    /*     42  WINVER >= 0x400 */
1289
1290     case SPI_GETMINIMIZEDMETRICS:               /*     43  WINVER >= 0x400 */
1291     {
1292         MINIMIZEDMETRICS * lpMm = pvParam;
1293         if (lpMm && lpMm->cbSize == sizeof(*lpMm))
1294         {
1295             /* these taken from Win2k SP3 */
1296             lpMm->iWidth = 154;
1297             lpMm->iHorzGap = 0;
1298             lpMm->iVertGap = 0;
1299             lpMm->iArrange = 8;
1300         }
1301         else
1302             ret = FALSE;
1303         break;
1304     }
1305     WINE_SPI_FIXME(SPI_SETMINIMIZEDMETRICS);    /*     44  WINVER >= 0x400 */
1306
1307     case SPI_GETICONMETRICS:                    /*     45  WINVER >= 0x400 */
1308     {
1309         LPICONMETRICSA lpIcon = pvParam;
1310         if(lpIcon && lpIcon->cbSize == sizeof(*lpIcon))
1311         {
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 );
1320         }
1321         else
1322         {
1323             ret = FALSE;
1324         }
1325         break;
1326     }
1327     WINE_SPI_FIXME(SPI_SETICONMETRICS);         /*     46  WINVER >= 0x400 */
1328
1329     case SPI_SETWORKAREA:                       /*     47  WINVER >= 0x400 */
1330     {
1331         char buf[20];
1332         RECT *pr = (RECT *) pvParam;
1333
1334         if (!pvParam) return FALSE;
1335
1336         spi_idx = SPI_SETWORKAREA_IDX;
1337         sprintf(buf, "%ld %ld %ld %ld",
1338                 pr->left, pr->top,
1339                 pr->right, pr->bottom );
1340
1341         if (SYSPARAMS_Save( SPI_SETWORKAREA_REGKEY,
1342                             SPI_SETWORKAREA_VALNAME,
1343                             buf, fWinIni ))
1344         {
1345             CopyRect( &work_area, (RECT *)pvParam );
1346             spi_loaded[spi_idx] = TRUE;
1347         }
1348         else
1349             ret = FALSE;
1350         break;
1351     }
1352
1353     case SPI_GETWORKAREA:                       /*     48  WINVER >= 0x400 */
1354         if (!pvParam) return FALSE;
1355
1356       spi_idx = SPI_SETWORKAREA_IDX;
1357       if (!spi_loaded[spi_idx])
1358       {
1359           char buf[20];
1360
1361           SetRect( &work_area, 0, 0,
1362                    GetSystemMetrics( SM_CXSCREEN ),
1363                    GetSystemMetrics( SM_CYSCREEN ) );
1364
1365           if (SYSPARAMS_Load( SPI_SETWORKAREA_REGKEY,
1366                               SPI_SETWORKAREA_VALNAME,
1367                               buf, sizeof(buf) ))
1368           {
1369               sscanf( buf, "%ld %ld %ld %ld",
1370                       &work_area.left, &work_area.top,
1371                       &work_area.right, &work_area.bottom );
1372           }
1373           spi_loaded[spi_idx] = TRUE;
1374       }
1375       CopyRect( (RECT *)pvParam, &work_area );
1376
1377       break;
1378
1379     WINE_SPI_FIXME(SPI_SETPENWINDOWS);          /*     49  WINVER >= 0x400 */
1380
1381     case SPI_GETFILTERKEYS:                     /*     50 */
1382     {
1383         LPFILTERKEYS lpFilterKeys = (LPFILTERKEYS)pvParam;
1384         WARN("SPI_GETFILTERKEYS not fully implemented\n");
1385         if (lpFilterKeys && lpFilterKeys->cbSize == sizeof(FILTERKEYS))
1386         {
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;
1393          }
1394         else
1395         {
1396             ret = FALSE;
1397         }
1398         break;
1399     }
1400     WINE_SPI_FIXME(SPI_SETFILTERKEYS);          /*     51 */
1401
1402     case SPI_GETTOGGLEKEYS:                     /*     52 */
1403     {
1404         LPTOGGLEKEYS lpToggleKeys = (LPTOGGLEKEYS)pvParam;
1405         WARN("SPI_GETTOGGLEKEYS not fully implemented\n");
1406         if (lpToggleKeys && lpToggleKeys->cbSize == sizeof(TOGGLEKEYS))
1407         {
1408             /* Indicate that no ToggleKeys feature available */
1409             lpToggleKeys->dwFlags = 0;
1410         }
1411         else
1412         {
1413             ret = FALSE;
1414         }
1415         break;
1416     }
1417     WINE_SPI_FIXME(SPI_SETTOGGLEKEYS);          /*     53 */
1418
1419     case SPI_GETMOUSEKEYS:                      /*     54 */
1420     {
1421         LPMOUSEKEYS lpMouseKeys = (LPMOUSEKEYS)pvParam;
1422         WARN("SPI_GETMOUSEKEYS not fully implemented\n");
1423         if (lpMouseKeys && lpMouseKeys->cbSize == sizeof(MOUSEKEYS))
1424         {
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;
1432         }
1433         else
1434         {
1435             ret = FALSE;
1436         }
1437         break;
1438     }
1439     WINE_SPI_FIXME(SPI_SETMOUSEKEYS);           /*     55 */
1440
1441     case SPI_GETSHOWSOUNDS:                     /*     56 */
1442         if (!pvParam) return FALSE;
1443
1444         spi_idx = SPI_SETSHOWSOUNDS_IDX;
1445
1446         if (!spi_loaded[spi_idx])
1447         {
1448             char buf[10];
1449
1450             if (SYSPARAMS_Load( SPI_SETSHOWSOUNDS_REGKEY,
1451                                 SPI_SETSHOWSOUNDS_VALNAME, buf, sizeof(buf) ))
1452             {
1453                 SYSMETRICS_Set( SM_SHOWSOUNDS, atoi( buf ) );
1454             }
1455             spi_loaded[spi_idx] = TRUE;
1456         }
1457
1458         *(INT *)pvParam = GetSystemMetrics( SM_SHOWSOUNDS );
1459         break;
1460
1461     case SPI_SETSHOWSOUNDS:                     /*     57 */
1462     {
1463         char buf[10];
1464         spi_idx = SPI_SETSHOWSOUNDS_IDX;
1465
1466         sprintf(buf, "%u", uiParam);
1467         if (SYSPARAMS_Save( SPI_SETSHOWSOUNDS_REGKEY,
1468                             SPI_SETSHOWSOUNDS_VALNAME,
1469                             buf, fWinIni ))
1470         {
1471             SYSMETRICS_Set( SM_SHOWSOUNDS, uiParam );
1472             spi_loaded[spi_idx] = TRUE;
1473         }
1474         else
1475             ret = FALSE;
1476         break;
1477     }
1478
1479     case SPI_GETSTICKYKEYS:                     /*     58 */
1480     {
1481         LPSTICKYKEYS lpStickyKeys = (LPSTICKYKEYS)pvParam;
1482         WARN("SPI_GETSTICKYKEYS not fully implemented\n");
1483         if (lpStickyKeys && lpStickyKeys->cbSize == sizeof(STICKYKEYS))
1484         {
1485             /* Indicate that no StickyKeys feature available */
1486             lpStickyKeys->dwFlags = 0;
1487         }
1488         else
1489         {
1490             ret = FALSE;
1491         }
1492         break;
1493     }
1494     WINE_SPI_FIXME(SPI_SETSTICKYKEYS);          /*     59 */
1495
1496     case SPI_GETACCESSTIMEOUT:                  /*     60 */
1497     {
1498         LPACCESSTIMEOUT lpAccessTimeout = (LPACCESSTIMEOUT)pvParam;
1499         WARN("SPI_GETACCESSTIMEOUT not fully implemented\n");
1500         if (lpAccessTimeout && lpAccessTimeout->cbSize == sizeof(ACCESSTIMEOUT))
1501         {
1502             /* Indicate that no accessibility features timeout is available */
1503             lpAccessTimeout->dwFlags = 0;
1504             lpAccessTimeout->iTimeOutMSec = 0;
1505         }
1506         else
1507         {
1508             ret = FALSE;
1509         }
1510         break;
1511     }
1512     WINE_SPI_FIXME(SPI_SETACCESSTIMEOUT);       /*     61 */
1513
1514     case SPI_GETSERIALKEYS:                     /*     62  WINVER >= 0x400 */
1515     {
1516         LPSERIALKEYSA lpSerialKeysA = (LPSERIALKEYSA)pvParam;
1517         WARN("SPI_GETSERIALKEYS not fully implemented\n");
1518         if (lpSerialKeysA && lpSerialKeysA->cbSize == sizeof(SERIALKEYSA))
1519         {
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;
1526         }
1527         else
1528         {
1529             ret = FALSE;
1530         }
1531         break;
1532     }
1533     WINE_SPI_FIXME(SPI_SETSERIALKEYS);          /*     63  WINVER >= 0x400 */
1534
1535     case SPI_GETSOUNDSENTRY:                    /*     64 */
1536     {
1537         LPSOUNDSENTRYA lpSoundSentryA = (LPSOUNDSENTRYA)pvParam;
1538         WARN("SPI_GETSOUNDSENTRY not fully implemented\n");
1539         if (lpSoundSentryA && lpSoundSentryA->cbSize == sizeof(SOUNDSENTRYA))
1540         {
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;
1553         }
1554         else
1555         {
1556             ret = FALSE;
1557         }
1558         break;
1559     }
1560     WINE_SPI_FIXME(SPI_SETSOUNDSENTRY);         /*     65 */
1561
1562     case SPI_GETHIGHCONTRAST:                   /*     66  WINVER >= 0x400 */
1563     {
1564         LPHIGHCONTRASTA lpHighContrastA = (LPHIGHCONTRASTA)pvParam;
1565         WARN("SPI_GETHIGHCONTRAST not fully implemented\n");
1566         if (lpHighContrastA && lpHighContrastA->cbSize == sizeof(HIGHCONTRASTA))
1567         {
1568             /* Indicate that no high contrast feature available */
1569             lpHighContrastA->dwFlags = 0;
1570             lpHighContrastA->lpszDefaultScheme = NULL;
1571         }
1572         else
1573         {
1574             ret = FALSE;
1575         }
1576         break;
1577     }
1578     WINE_SPI_FIXME(SPI_SETHIGHCONTRAST);        /*     67  WINVER >= 0x400 */
1579
1580     case SPI_GETKEYBOARDPREF:                   /*     68  WINVER >= 0x400 */
1581         if (!pvParam) return FALSE;
1582
1583         spi_idx = SPI_SETKEYBOARDPREF_IDX;
1584         if (!spi_loaded[spi_idx])
1585         {
1586             char buf[5];
1587
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;
1592         }
1593
1594         *(BOOL *)pvParam = keyboard_pref;
1595         break;
1596
1597     case SPI_SETKEYBOARDPREF:                   /*     69  WINVER >= 0x400 */
1598     {
1599         char buf[5];
1600
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 ))
1606         {
1607             keyboard_pref = uiParam;
1608             spi_loaded[spi_idx] = TRUE;
1609         }
1610         else
1611             ret = FALSE;
1612         break;
1613     }
1614
1615     case SPI_GETSCREENREADER:                   /*     70  WINVER >= 0x400 */
1616         if (!pvParam) return FALSE;
1617
1618         spi_idx = SPI_SETSCREENREADER_IDX;
1619         if (!spi_loaded[spi_idx])
1620         {
1621             char buf[5];
1622
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;
1627         }
1628
1629         *(BOOL *)pvParam = screen_reader;
1630         break;
1631
1632     case SPI_SETSCREENREADER:                   /*     71  WINVER >= 0x400 */
1633     {
1634         char buf[5];
1635
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 ))
1641         {
1642             screen_reader = uiParam;
1643             spi_loaded[spi_idx] = TRUE;
1644         }
1645         else
1646             ret = FALSE;
1647         break;
1648     }
1649
1650     case SPI_GETANIMATION:                      /*     72  WINVER >= 0x400 */
1651     {
1652         LPANIMATIONINFO lpAnimInfo = (LPANIMATIONINFO)pvParam;
1653
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;
1660     }
1661     WINE_SPI_WARN(SPI_SETANIMATION);            /*     73  WINVER >= 0x400 */
1662
1663     case SPI_GETFONTSMOOTHING:    /*     74  WINVER >= 0x400 */
1664         if (!pvParam) return FALSE;
1665
1666         spi_idx = SPI_SETFONTSMOOTHING_IDX;
1667         if (!spi_loaded[spi_idx])
1668         {
1669             char buf[5];
1670
1671             if (SYSPARAMS_Load( SPI_SETFONTSMOOTHING_REGKEY,
1672                                 SPI_SETFONTSMOOTHING_VALNAME, buf, sizeof(buf) ))
1673             {
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 */
1676                 {
1677                     font_smoothing = TRUE;
1678                 }
1679             }
1680         }
1681
1682         *(BOOL *)pvParam = font_smoothing;
1683
1684         break;
1685
1686     WINE_SPI_FIXME(SPI_SETFONTSMOOTHING);       /*     75  WINVER >= 0x400 */
1687
1688     WINE_SPI_FIXME(SPI_SETDRAGWIDTH);           /*     76  WINVER >= 0x400 */
1689     WINE_SPI_FIXME(SPI_SETDRAGHEIGHT);          /*     77  WINVER >= 0x400 */
1690
1691     WINE_SPI_FIXME(SPI_SETHANDHELD);            /*     78  WINVER >= 0x400 */
1692
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 */
1701
1702     WINE_SPI_FIXME(SPI_SETCURSORS);             /*     87  WINVER >= 0x400 */
1703     WINE_SPI_FIXME(SPI_SETICONS);               /*     88  WINVER >= 0x400 */
1704
1705     case SPI_GETDEFAULTINPUTLANG:       /*     89  WINVER >= 0x400 */
1706         ret = GetKeyboardLayout(0) ? TRUE : FALSE;
1707         break;
1708
1709     WINE_SPI_FIXME(SPI_SETDEFAULTINPUTLANG);    /*     90  WINVER >= 0x400 */
1710
1711     WINE_SPI_FIXME(SPI_SETLANGTOGGLE);          /*     91  WINVER >= 0x400 */
1712
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;
1717
1718     WINE_SPI_FIXME(SPI_SETMOUSETRAILS);         /*     93  WINVER >= 0x400 */
1719     WINE_SPI_FIXME(SPI_GETMOUSETRAILS);         /*     94  WINVER >= 0x400 */
1720
1721     case SPI_SETSCREENSAVERRUNNING:             /*     97  WINVER >= 0x400 */
1722         {
1723         /* SPI_SCREENSAVERRUNNING is an alias for SPI_SETSCREENSAVERRUNNING */
1724         char buf[5];
1725
1726         spi_idx = SPI_SETSCREENSAVERRUNNING_IDX;
1727         sprintf(buf, "%u", uiParam);
1728
1729         /* save only temporarily */
1730         if (SYSPARAMS_Save( SPI_SETSCREENSAVERRUNNING_REGKEY,
1731                             SPI_SETSCREENSAVERRUNNING_VALNAME,
1732                             buf, 0 ))
1733         {
1734             screensaver_running = uiParam;
1735             spi_loaded[spi_idx] = TRUE;
1736         }
1737         else
1738             ret = FALSE;
1739         break;
1740     }
1741
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 */
1747
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 */
1753
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 */
1759
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;
1764
1765     WINE_SPI_FIXME(SPI_SETWHEELSCROLLLINES);    /*    105  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1766
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;
1771
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 */
1774
1775     case SPI_GETSCREENSAVERRUNNING:             /*    114  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1776         if (!pvParam) return FALSE;
1777
1778         spi_idx = SPI_SETSCREENSAVERRUNNING_IDX;
1779         if (!spi_loaded[spi_idx])
1780         {
1781             char buf[5];
1782
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;
1787         }
1788
1789         *(BOOL *)pvParam = screensaver_running;
1790         break;
1791
1792     case SPI_GETDESKWALLPAPER:                  /*    115  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1793     {
1794         char buf[MAX_PATH];
1795
1796         if (!pvParam) return FALSE;
1797
1798         if (uiParam > MAX_PATH)
1799         {
1800             uiParam = MAX_PATH;
1801         }
1802
1803         if (SYSPARAMS_Load(SPI_SETDESKWALLPAPER_REGKEY, SPI_SETDESKWALLPAPER_VALNAME, buf, sizeof(buf)))
1804         {
1805             strncpy((char*)pvParam, buf, uiParam);
1806         }
1807         else
1808         {
1809             /* Return an empty string */
1810             memset((char*)pvParam, 0, uiParam);
1811         }
1812
1813         break;
1814     }
1815
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 */
1822
1823     case SPI_GETLISTBOXSMOOTHSCROLLING:    /* 0x1006  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1824         if (!pvParam) return FALSE;
1825
1826         spi_idx = SPI_SETLISTBOXSMOOTHSCROLLING_IDX;
1827         if (!spi_loaded[spi_idx])
1828         {
1829             char buf[5];
1830
1831             if (SYSPARAMS_Load( SPI_SETLISTBOXSMOOTHSCROLLING_REGKEY,
1832                                 SPI_SETLISTBOXSMOOTHSCROLLING_VALNAME, buf, sizeof(buf) ))
1833             {
1834                 if ((buf[0]&0x01) == 0x01)
1835                 {
1836                     listbox_smoothscrolling = TRUE;
1837                 }
1838             }
1839             spi_loaded[spi_idx] = TRUE;
1840         }
1841
1842         *(BOOL *)pvParam = listbox_smoothscrolling;
1843
1844         break;
1845
1846     WINE_SPI_FIXME(SPI_SETLISTBOXSMOOTHSCROLLING);/* 0x1007  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1847
1848     case SPI_GETGRADIENTCAPTIONS:    /* 0x1008  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1849         if (!pvParam) return FALSE;
1850
1851         spi_idx = SPI_SETGRADIENTCAPTIONS_IDX;
1852         if (!spi_loaded[spi_idx])
1853         {
1854             char buf[5];
1855
1856             if (SYSPARAMS_Load( SPI_USERPREFERENCEMASK_REGKEY,
1857                                 SPI_USERPREFERENCEMASK_VALNAME, buf, sizeof(buf) ))
1858             {
1859                 if ((buf[0]&0x10) == 0x10)
1860                 {
1861                     gradient_captions = TRUE;
1862                 }
1863             }
1864             spi_loaded[spi_idx] = TRUE;
1865         }
1866
1867         *(BOOL *)pvParam = gradient_captions;
1868
1869         break;
1870
1871     WINE_SPI_FIXME(SPI_SETGRADIENTCAPTIONS);    /* 0x1009  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1872
1873     case SPI_GETKEYBOARDCUES:     /* 0x100A  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1874         if (!pvParam) return FALSE;
1875
1876         spi_idx = SPI_SETKEYBOARDCUES_IDX;
1877         if (!spi_loaded[spi_idx])
1878         {
1879             char buf[5];
1880
1881             if (SYSPARAMS_Load( SPI_USERPREFERENCEMASK_REGKEY,
1882                                 SPI_USERPREFERENCEMASK_VALNAME, buf, sizeof(buf) ))
1883             {
1884                 if ((buf[0]&0x20) == 0x20)
1885                 {
1886                     keyboard_cues = TRUE;
1887                 }
1888             }
1889             spi_loaded[spi_idx] = TRUE;
1890         }
1891
1892         *(BOOL *)pvParam = keyboard_cues;
1893
1894         break;
1895
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;
1901
1902         spi_idx = SPI_SETHOTTRACKING_IDX;
1903         if (!spi_loaded[spi_idx])
1904         {
1905             char buf[5];
1906
1907             if (SYSPARAMS_Load( SPI_USERPREFERENCEMASK_REGKEY,
1908                                 SPI_USERPREFERENCEMASK_VALNAME, buf, sizeof(buf) ))
1909             {
1910                 if ((buf[0]&0x80) == 0x80)
1911                 {
1912                     hot_tracking = TRUE;
1913                 }
1914             }
1915             spi_loaded[spi_idx] = TRUE;
1916         }
1917
1918         *(BOOL *)pvParam = hot_tracking;
1919
1920         break;
1921
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 */
1933
1934     default:
1935         FIXME( "Unknown action: %u\n", uiAction );
1936         SetLastError( ERROR_INVALID_SPI_VALUE );
1937         ret = FALSE;
1938         break;
1939     }
1940
1941     if (ret)
1942         SYSPARAMS_NotifyChange( uiAction, fWinIni );
1943     return ret;
1944
1945 #undef WINE_SPI_FIXME
1946 #undef WINE_SPI_WARN
1947 }
1948
1949
1950 /***********************************************************************
1951  *              SystemParametersInfo (USER.483)
1952  */
1953 BOOL16 WINAPI SystemParametersInfo16( UINT16 uAction, UINT16 uParam,
1954                                       LPVOID lpvParam, UINT16 fuWinIni )
1955 {
1956     BOOL16 ret;
1957
1958     TRACE("(%u, %u, %p, %u)\n", uAction, uParam, lpvParam, fuWinIni);
1959
1960     switch (uAction)
1961     {
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 */
1968     {
1969         BOOL tmp;
1970         ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1971         if (ret && lpvParam)
1972             *(BOOL16 *)lpvParam = tmp;
1973         break;
1974     }
1975
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 */
1982     {
1983         INT tmp;
1984         ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1985         if (ret && lpvParam)
1986             *(INT16 *)lpvParam = tmp;
1987         break;
1988     }
1989
1990     case SPI_GETKEYBOARDSPEED:                  /*     10 */
1991     {
1992         DWORD tmp;
1993         ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
1994         if (ret && lpvParam)
1995             *(WORD *)lpvParam = tmp;
1996         break;
1997     }
1998
1999     case SPI_GETICONTITLELOGFONT:               /*     31 */
2000     {
2001         LOGFONTA tmp;
2002         ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
2003         if (ret && lpvParam)
2004             SYSPARAMS_LogFont32ATo16( &tmp, (LPLOGFONT16)lpvParam );
2005         break;
2006     }
2007
2008     case SPI_GETNONCLIENTMETRICS:               /*     41  WINVER >= 0x400 */
2009     {
2010         NONCLIENTMETRICSA tmp;
2011         LPNONCLIENTMETRICS16 lpnm16 = (LPNONCLIENTMETRICS16)lpvParam;
2012         if (lpnm16 && lpnm16->cbSize == sizeof(NONCLIENTMETRICS16))
2013         {
2014             tmp.cbSize = sizeof(NONCLIENTMETRICSA);
2015             ret = SystemParametersInfoA( uAction, uParam, &tmp, fuWinIni );
2016             if (ret)
2017                 SYSPARAMS_NonClientMetrics32ATo16( &tmp, lpnm16 );
2018         }
2019         else /* winfile 95 sets cbSize to 340 */
2020             ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
2021         break;
2022     }
2023
2024     case SPI_GETWORKAREA:                       /*     48  WINVER >= 0x400 */
2025     {
2026         RECT tmp;
2027         ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
2028         if (ret && lpvParam)
2029             CONV_RECT32TO16( &tmp, (RECT16 *)lpvParam );
2030         break;
2031     }
2032
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 */
2036     {
2037         UINT tmp;
2038         ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
2039         if (ret && lpvParam)
2040             *(UINT16 *)lpvParam = tmp;
2041         break;
2042     }
2043
2044     default:
2045         ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
2046     }
2047
2048     return ret;
2049 }
2050
2051 /***********************************************************************
2052  *              SystemParametersInfoW (USER32.@)
2053  */
2054 BOOL WINAPI SystemParametersInfoW( UINT uiAction, UINT uiParam,
2055                                    PVOID pvParam, UINT fuWinIni )
2056 {
2057     BOOL ret;
2058
2059     TRACE("(%u, %u, %p, %u)\n", uiAction, uiParam, pvParam, fuWinIni);
2060
2061     switch (uiAction)
2062     {
2063     case SPI_SETDESKWALLPAPER:                  /*     20 */
2064     case SPI_SETDESKPATTERN:                    /*     21 */
2065     {
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;
2073     }
2074
2075     case SPI_GETICONTITLELOGFONT:               /*     31 */
2076     {
2077         LOGFONTA tmp;
2078         ret = SystemParametersInfoA( uiAction, uiParam, pvParam ? &tmp : NULL, fuWinIni );
2079         if (ret && pvParam)
2080             SYSPARAMS_LogFont32ATo32W( &tmp, (LPLOGFONTW)pvParam );
2081         break;
2082     }
2083
2084     case SPI_GETNONCLIENTMETRICS:               /*     41  WINVER >= 0x400 */
2085     {
2086         NONCLIENTMETRICSA tmp;
2087         LPNONCLIENTMETRICSW lpnmW = (LPNONCLIENTMETRICSW)pvParam;
2088         if (lpnmW && lpnmW->cbSize == sizeof(NONCLIENTMETRICSW))
2089         {
2090             tmp.cbSize = sizeof(NONCLIENTMETRICSA);
2091             ret = SystemParametersInfoA( uiAction, uiParam, &tmp, fuWinIni );
2092             if (ret)
2093                 SYSPARAMS_NonClientMetrics32ATo32W( &tmp, lpnmW );
2094         }
2095         else
2096             ret = FALSE;
2097         break;
2098     }
2099
2100     case SPI_GETICONMETRICS:                    /*     45  WINVER >= 0x400 */
2101     {
2102         ICONMETRICSA tmp;
2103         LPICONMETRICSW lpimW = (LPICONMETRICSW)pvParam;
2104         if (lpimW && lpimW->cbSize == sizeof(ICONMETRICSW))
2105         {
2106             tmp.cbSize = sizeof(ICONMETRICSA);
2107             ret = SystemParametersInfoA( uiAction, uiParam, &tmp, fuWinIni );
2108             if (ret)
2109             {
2110                 lpimW->iHorzSpacing = tmp.iHorzSpacing;
2111                 lpimW->iVertSpacing = tmp.iVertSpacing;
2112                 lpimW->iTitleWrap   = tmp.iTitleWrap;
2113                 SYSPARAMS_LogFont32ATo32W( &tmp.lfFont, &lpimW->lfFont );
2114             }
2115         }
2116         else
2117             ret = FALSE;
2118         break;
2119     }
2120
2121     case SPI_GETHIGHCONTRAST:                   /*     66  WINVER >= 0x400 */
2122     {
2123         HIGHCONTRASTA tmp;
2124         LPHIGHCONTRASTW lphcW = (LPHIGHCONTRASTW)pvParam;
2125         if (lphcW && lphcW->cbSize == sizeof(HIGHCONTRASTW))
2126         {
2127             tmp.cbSize = sizeof(HIGHCONTRASTA);
2128             ret = SystemParametersInfoA( uiAction, uiParam, &tmp, fuWinIni );
2129             if (ret)
2130             {
2131                 lphcW->dwFlags = tmp.dwFlags;
2132                 lphcW->lpszDefaultScheme = NULL;  /* FIXME? */
2133             }
2134         }
2135         else
2136             ret = FALSE;
2137         break;
2138     }
2139
2140     default:
2141         ret = SystemParametersInfoA( uiAction, uiParam, pvParam, fuWinIni );
2142         break;
2143     }
2144     return ret;
2145 }
2146
2147
2148 /**********************************************************************
2149  *              SetDoubleClickTime (USER32.@)
2150  */
2151 BOOL WINAPI SetDoubleClickTime( UINT interval )
2152 {
2153     return SystemParametersInfoA(SPI_SETDOUBLECLICKTIME, interval, 0, 0);
2154 }
2155
2156
2157 /**********************************************************************
2158  *              GetDoubleClickTime (USER32.@)
2159  */
2160 UINT WINAPI GetDoubleClickTime(void)
2161 {
2162     char buf[10];
2163
2164     if (!spi_loaded[SPI_SETDOUBLECLICKTIME_IDX])
2165     {
2166         if (SYSPARAMS_Load( SPI_SETDOUBLECLICKTIME_REGKEY,
2167                             SPI_SETDOUBLECLICKTIME_VALNAME,
2168                             buf, sizeof(buf) ))
2169         {
2170             double_click_time = atoi( buf );
2171             if (!double_click_time) double_click_time = 500;
2172         }
2173         spi_loaded[SPI_SETDOUBLECLICKTIME_IDX] = TRUE;
2174     }
2175     return double_click_time;
2176 }