Replace fixme for SPI_GETWHEELSCROLLLINES with the default value of 3.
[wine] / windows / sysparams.c
1 /*
2  * System parameters functions
3  *
4  * Copyright 1994 Alexandre Julliard
5  */
6
7 #include "config.h"
8
9 #include <stdlib.h>
10 #include <string.h>
11 #include "windef.h"
12 #include "winbase.h"
13 #include "winnls.h"
14 #include "wingdi.h"
15 #include "winreg.h"
16 #include "wine/winuser16.h"
17 #include "winerror.h"
18
19 #include "controls.h"
20 #include "keyboard.h"
21 #include "user.h"
22 #include "debugtools.h"
23
24 DEFAULT_DEBUG_CHANNEL(system);
25
26 /***********************************************************************
27  *              GetTimerResolution (USER.14)
28  */
29 LONG WINAPI GetTimerResolution16(void)
30 {
31         return (1000);
32 }
33
34 /***********************************************************************
35  *              ControlPanelInfo (USER.273)
36  */
37 void WINAPI ControlPanelInfo16( INT16 nInfoType, WORD wData, LPSTR lpBuffer )
38 {
39         FIXME("(%d, %04x, %p): stub.\n", nInfoType, wData, lpBuffer);
40 }
41
42 /* This function is a copy of the one in objects/font.c */
43 static void SYSPARAMS_LogFont32ATo16( const LOGFONTA* font32, LPLOGFONT16 font16 )
44 {
45     font16->lfHeight = font32->lfHeight;
46     font16->lfWidth = font32->lfWidth;
47     font16->lfEscapement = font32->lfEscapement;
48     font16->lfOrientation = font32->lfOrientation;
49     font16->lfWeight = font32->lfWeight;
50     font16->lfItalic = font32->lfItalic;
51     font16->lfUnderline = font32->lfUnderline;
52     font16->lfStrikeOut = font32->lfStrikeOut;
53     font16->lfCharSet = font32->lfCharSet;
54     font16->lfOutPrecision = font32->lfOutPrecision;
55     font16->lfClipPrecision = font32->lfClipPrecision;
56     font16->lfQuality = font32->lfQuality;
57     font16->lfPitchAndFamily = font32->lfPitchAndFamily;
58     lstrcpynA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
59 }
60
61 static void SYSPARAMS_LogFont32ATo32W( const LOGFONTA* font32A, LPLOGFONTW font32W )
62 {
63     font32W->lfHeight = font32A->lfHeight;
64     font32W->lfWidth = font32A->lfWidth;
65     font32W->lfEscapement = font32A->lfEscapement;
66     font32W->lfOrientation = font32A->lfOrientation;
67     font32W->lfWeight = font32A->lfWeight;
68     font32W->lfItalic = font32A->lfItalic;
69     font32W->lfUnderline = font32A->lfUnderline;
70     font32W->lfStrikeOut = font32A->lfStrikeOut;
71     font32W->lfCharSet = font32A->lfCharSet;
72     font32W->lfOutPrecision = font32A->lfOutPrecision;
73     font32W->lfClipPrecision = font32A->lfClipPrecision;
74     font32W->lfQuality = font32A->lfQuality;
75     font32W->lfPitchAndFamily = font32A->lfPitchAndFamily;
76     MultiByteToWideChar( CP_ACP, 0, font32A->lfFaceName, -1, font32W->lfFaceName, LF_FACESIZE );
77     font32W->lfFaceName[LF_FACESIZE-1] = 0;
78 }
79
80 static void SYSPARAMS_NonClientMetrics32ATo16( const NONCLIENTMETRICSA* lpnm32, LPNONCLIENTMETRICS16 lpnm16 )
81 {
82     lpnm16->iBorderWidth        = lpnm32->iBorderWidth;
83     lpnm16->iScrollWidth        = lpnm32->iScrollWidth;
84     lpnm16->iScrollHeight       = lpnm32->iScrollHeight;
85     lpnm16->iCaptionWidth       = lpnm32->iCaptionWidth;
86     lpnm16->iCaptionHeight      = lpnm32->iCaptionHeight;
87     SYSPARAMS_LogFont32ATo16( &lpnm32->lfCaptionFont,   &lpnm16->lfCaptionFont );
88     lpnm16->iSmCaptionWidth     = lpnm32->iSmCaptionWidth;
89     lpnm16->iSmCaptionHeight    = lpnm32->iSmCaptionHeight;
90     SYSPARAMS_LogFont32ATo16( &lpnm32->lfSmCaptionFont, &lpnm16->lfSmCaptionFont );
91     lpnm16->iMenuWidth          = lpnm32->iMenuWidth;
92     lpnm16->iMenuHeight         = lpnm32->iMenuHeight;
93     SYSPARAMS_LogFont32ATo16( &lpnm32->lfMenuFont,      &lpnm16->lfMenuFont );
94     SYSPARAMS_LogFont32ATo16( &lpnm32->lfStatusFont,    &lpnm16->lfStatusFont );
95     SYSPARAMS_LogFont32ATo16( &lpnm32->lfMessageFont,   &lpnm16->lfMessageFont );
96 }
97
98 static void SYSPARAMS_NonClientMetrics32ATo32W( const NONCLIENTMETRICSA* lpnm32A, LPNONCLIENTMETRICSW lpnm32W )
99 {
100     lpnm32W->iBorderWidth       = lpnm32A->iBorderWidth;
101     lpnm32W->iScrollWidth       = lpnm32A->iScrollWidth;
102     lpnm32W->iScrollHeight      = lpnm32A->iScrollHeight;
103     lpnm32W->iCaptionWidth      = lpnm32A->iCaptionWidth;
104     lpnm32W->iCaptionHeight     = lpnm32A->iCaptionHeight;
105     SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfCaptionFont,         &lpnm32W->lfCaptionFont );
106     lpnm32W->iSmCaptionWidth    = lpnm32A->iSmCaptionWidth;
107     lpnm32W->iSmCaptionHeight   = lpnm32A->iSmCaptionHeight;
108     SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfSmCaptionFont,       &lpnm32W->lfSmCaptionFont );
109     lpnm32W->iMenuWidth         = lpnm32A->iMenuWidth;
110     lpnm32W->iMenuHeight        = lpnm32A->iMenuHeight;
111     SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfMenuFont,            &lpnm32W->lfMenuFont );
112     SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfStatusFont,          &lpnm32W->lfStatusFont );
113     SYSPARAMS_LogFont32ATo32W( &lpnm32A->lfMessageFont,         &lpnm32W->lfMessageFont );
114 }
115
116 /***********************************************************************
117  *              SystemParametersInfoA (USER32.@)
118  */
119 BOOL WINAPI SystemParametersInfoA( UINT uiAction, UINT uiParam,
120                                    PVOID pvParam, UINT fWinIni )
121 {
122 #define WINE_SPI_FIXME(x) \
123     case x: \
124         FIXME( "Unimplemented action: %u (%s)\n", x, #x ); \
125         SetLastError( ERROR_INVALID_SPI_VALUE ); \
126         ret = FALSE; \
127         break
128 #define WINE_SPI_WARN(x) \
129     case x: \
130         WARN( "Ignored action: %u (%s)\n", x, #x ); \
131         break
132
133     BOOL ret = TRUE;
134     
135     TRACE("(%u, %u, %p, %u)\n", uiAction, uiParam, pvParam, fWinIni);
136     
137     switch (uiAction)
138     {
139     case SPI_GETBEEP:                           /*      1 */
140         *(BOOL *)pvParam = KEYBOARD_GetBeepActive();
141         break;
142     case SPI_SETBEEP:                           /*      2 */
143         KEYBOARD_SetBeepActive( uiParam );
144         break;
145
146     WINE_SPI_FIXME(SPI_GETMOUSE);               /*      3 */
147     WINE_SPI_FIXME(SPI_SETMOUSE);               /*      4 */
148
149     case SPI_GETBORDER:                         /*      5 */
150         *(INT *)pvParam = GetSystemMetrics( SM_CXFRAME );
151         break;
152     WINE_SPI_WARN(SPI_SETBORDER);               /*      6 */
153
154     case SPI_GETKEYBOARDSPEED:                  /*     10 */
155         *(DWORD *)pvParam = GetProfileIntA( "keyboard", "KeyboardSpeed", 30 );
156         break;
157     WINE_SPI_WARN(SPI_SETKEYBOARDSPEED);        /*     11 */
158
159     WINE_SPI_WARN(SPI_LANGDRIVER);              /*     12 */
160
161     case SPI_ICONHORIZONTALSPACING:             /*     13 */
162         /* FIXME Get/SetProfileInt */
163         if (pvParam == NULL)
164             /*SetSystemMetrics( SM_CXICONSPACING, uiParam )*/ ;
165         else
166             *(INT *)pvParam = GetSystemMetrics( SM_CXICONSPACING );
167         break;
168
169     case SPI_GETSCREENSAVETIMEOUT:              /*     14 */
170     {
171         int     timeout;
172         timeout = USER_Driver.pGetScreenSaveTimeout();
173         if (!timeout)
174             timeout = GetProfileIntA( "windows", "ScreenSaveTimeout", 300 );
175         *(INT *)pvParam = timeout;
176         break;
177     }
178     case SPI_SETSCREENSAVETIMEOUT:              /*     15 */
179         USER_Driver.pSetScreenSaveTimeout( uiParam );
180         break;
181         
182     case SPI_GETSCREENSAVEACTIVE:               /*     16 */
183         if (USER_Driver.pGetScreenSaveActive() ||
184             GetProfileIntA( "windows", "ScreenSaveActive", 1 ) == 1)
185             *(BOOL *)pvParam = TRUE;
186         else
187             *(BOOL *)pvParam = FALSE;
188         break;
189     case SPI_SETSCREENSAVEACTIVE:               /*     17 */
190         USER_Driver.pSetScreenSaveActive( uiParam );
191         break;
192         
193     case SPI_GETGRIDGRANULARITY:                /*     18 */
194         *(INT *)pvParam = GetProfileIntA( "desktop", "GridGranularity", 1 );
195         break;
196     WINE_SPI_FIXME(SPI_SETGRIDGRANULARITY);     /*     19 */
197
198     case SPI_SETDESKWALLPAPER:                  /*     20 */
199         ret = SetDeskWallPaper( (LPSTR)pvParam );
200         break;
201     case SPI_SETDESKPATTERN:                    /*     21 */
202         /* FIXME: the ability to specify a pattern in pvParam
203            doesn't seem to be documented for Win32 */
204         if ((INT16)uiParam == -1)
205         {
206             char buffer[256];
207             GetProfileStringA( "Desktop", "Pattern", 
208                                "170 85 170 85 170 85 170 85", 
209                                buffer, sizeof(buffer) );
210             ret = DESKTOP_SetPattern( (LPSTR)buffer );
211         } else
212             ret = DESKTOP_SetPattern( (LPSTR)pvParam );
213         break;
214
215     case SPI_GETKEYBOARDDELAY:                  /*     22 */
216         *(INT *)pvParam = GetProfileIntA( "keyboard", "KeyboardDelay", 1 );
217         break;
218     WINE_SPI_WARN(SPI_SETKEYBOARDDELAY);        /*     23 */
219
220     case SPI_ICONVERTICALSPACING:               /*     24 */
221         /* FIXME Get/SetProfileInt */
222         if (pvParam == NULL)
223             /*SetSystemMetrics( SM_CYICONSPACING, uiParam )*/ ;
224         else
225             *(INT *)pvParam = GetSystemMetrics( SM_CYICONSPACING );
226         break;
227
228     case SPI_GETICONTITLEWRAP:                  /*     25 */
229         *(BOOL *)pvParam = GetProfileIntA( "desktop", "IconTitleWrap", TRUE );
230         break;
231     WINE_SPI_FIXME(SPI_SETICONTITLEWRAP);       /*     26 */
232
233     case SPI_GETMENUDROPALIGNMENT:              /*     27 */
234         *(BOOL *)pvParam = GetSystemMetrics( SM_MENUDROPALIGNMENT ); /* XXX check this */
235         break;
236     WINE_SPI_FIXME(SPI_SETMENUDROPALIGNMENT);   /*     28 */
237
238     WINE_SPI_WARN(SPI_SETDOUBLECLKWIDTH);       /*     29 */
239     WINE_SPI_WARN(SPI_SETDOUBLECLKHEIGHT);      /*     30 */
240
241     case SPI_GETICONTITLELOGFONT:               /*     31 */
242     {
243         LPLOGFONTA lpLogFont = (LPLOGFONTA)pvParam;
244
245         /* from now on we always have an alias for MS Sans Serif */
246
247         GetProfileStringA( "Desktop", "IconTitleFaceName", "MS Sans Serif", 
248                            lpLogFont->lfFaceName, LF_FACESIZE );
249         lpLogFont->lfHeight = -GetProfileIntA( "Desktop", "IconTitleSize", 13 );
250         lpLogFont->lfWidth = 0;
251         lpLogFont->lfEscapement = lpLogFont->lfOrientation = 0;
252         lpLogFont->lfWeight = FW_NORMAL;
253         lpLogFont->lfItalic = FALSE;
254         lpLogFont->lfStrikeOut = FALSE;
255         lpLogFont->lfUnderline = FALSE;
256         lpLogFont->lfCharSet = ANSI_CHARSET;
257         lpLogFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
258         lpLogFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
259         lpLogFont->lfPitchAndFamily = DEFAULT_PITCH | FF_SWISS;
260         break;
261     }
262
263     WINE_SPI_WARN(SPI_SETDOUBLECLICKTIME);      /*     32 */
264     
265     WINE_SPI_FIXME(SPI_SETMOUSEBUTTONSWAP);     /*     33 */
266     WINE_SPI_FIXME(SPI_SETICONTITLELOGFONT);    /*     34 */
267
268     case SPI_GETFASTTASKSWITCH:                 /*     35 */
269         if (GetProfileIntA( "windows", "CoolSwitch", 1 ) == 1)
270             *(BOOL *)pvParam = TRUE;
271         else
272             *(BOOL *)pvParam = FALSE;
273         break;
274     WINE_SPI_WARN(SPI_SETFASTTASKSWITCH);       /*     36 */
275
276     WINE_SPI_WARN(SPI_SETDRAGFULLWINDOWS);      /*     37  WINVER >= 0x0400 */
277     case SPI_GETDRAGFULLWINDOWS:                /*     38  WINVER >= 0x0400 */
278     {
279         HKEY hKey;
280         char buffer[20];
281         DWORD dwBufferSize = sizeof(buffer);
282
283         *(BOOL *)pvParam = FALSE;
284         if (RegOpenKeyExA( HKEY_CURRENT_USER,
285                            "Control Panel\\desktop",
286                            0, KEY_QUERY_VALUE, &hKey ) == ERROR_SUCCESS)
287         {
288             if (RegQueryValueExA( hKey, "DragFullWindows", NULL,
289                                   0, buffer, &dwBufferSize ) == ERROR_SUCCESS)
290                 *(BOOL *)pvParam = atoi( buffer ) != 0;
291             
292             RegCloseKey( hKey );
293         }
294         break;
295     }
296
297     case SPI_GETNONCLIENTMETRICS:               /*     41  WINVER >= 0x400 */
298     {
299         LPNONCLIENTMETRICSA lpnm = (LPNONCLIENTMETRICSA)pvParam;
300                 
301         if (lpnm->cbSize == sizeof(NONCLIENTMETRICSA))
302         {
303             LPLOGFONTA lpLogFont = &(lpnm->lfMenuFont);
304             
305             /* clear the struct, so we have 'sane' members */
306             memset(
307                 (char *)pvParam + sizeof(lpnm->cbSize),
308                 0,
309                 lpnm->cbSize - sizeof(lpnm->cbSize)
310                 );
311
312             /* FIXME: initialize geometry entries */
313             /* FIXME: As these values are presumably in device units,
314              *  we should calculate the defaults based on the screen dpi
315              */
316             /* caption */
317             lpnm->iCaptionWidth = ((TWEAK_WineLook > WIN31_LOOK)  ? 32 : 20);
318             lpnm->iCaptionHeight = lpnm->iCaptionWidth;
319             SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0, (LPVOID)&(lpnm->lfCaptionFont), 0 );
320             lpnm->lfCaptionFont.lfWeight = FW_BOLD;
321
322             /* small caption */
323             lpnm->iSmCaptionWidth = ((TWEAK_WineLook > WIN31_LOOK)  ? 32 : 17);
324             lpnm->iSmCaptionHeight = lpnm->iSmCaptionWidth;
325             SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0, (LPVOID)&(lpnm->lfSmCaptionFont), 0 );
326
327             /* menus, FIXME: names of wine.conf entrys are bogus */
328
329             lpnm->iMenuWidth = GetProfileIntA( "Desktop", "MenuWidth", 13 );    /* size of the menu buttons*/
330             lpnm->iMenuHeight = GetProfileIntA( "Desktop", "MenuHeight", 
331                                                 (TWEAK_WineLook > WIN31_LOOK) ? 13 : 27 );
332
333             GetProfileStringA( "Desktop", "MenuFont", 
334                                (TWEAK_WineLook > WIN31_LOOK) ? "MS Sans Serif": "System", 
335                                lpLogFont->lfFaceName, LF_FACESIZE );
336
337             lpLogFont->lfHeight = -GetProfileIntA( "Desktop", "MenuFontSize", 13 );
338             lpLogFont->lfWidth = 0;
339             lpLogFont->lfEscapement = lpLogFont->lfOrientation = 0;
340             lpLogFont->lfWeight = (TWEAK_WineLook > WIN31_LOOK) ? FW_NORMAL : FW_BOLD;
341             lpLogFont->lfItalic = FALSE;
342             lpLogFont->lfStrikeOut = FALSE;
343             lpLogFont->lfUnderline = FALSE;
344             lpLogFont->lfCharSet = ANSI_CHARSET;
345             lpLogFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
346             lpLogFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
347             lpLogFont->lfPitchAndFamily = DEFAULT_PITCH | FF_SWISS;
348
349             SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0,
350                                    (LPVOID)&(lpnm->lfStatusFont), 0 );
351             SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0,
352                                    (LPVOID)&(lpnm->lfMessageFont), 0 );
353         }
354         else
355         {
356             WARN("size mismatch !! (is %d; should be %d)\n", lpnm->cbSize, sizeof(NONCLIENTMETRICSA));
357             /* FIXME: SetLastError? */
358             ret = FALSE;
359         }
360         break;
361     }
362     WINE_SPI_FIXME(SPI_SETNONCLIENTMETRICS);    /*     42  WINVER >= 0x400 */
363
364     WINE_SPI_FIXME(SPI_GETMINIMIZEDMETRICS);    /*     43  WINVER >= 0x400 */
365     WINE_SPI_FIXME(SPI_SETMINIMIZEDMETRICS);    /*     44  WINVER >= 0x400 */
366
367     case SPI_GETICONMETRICS:                    /*     45  WINVER >= 0x400 */
368     {
369         LPICONMETRICSA lpIcon = pvParam;
370         if(lpIcon && lpIcon->cbSize == sizeof(*lpIcon))
371         {
372             SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0,
373                                    &lpIcon->iHorzSpacing, FALSE );
374             SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0,
375                                    &lpIcon->iVertSpacing, FALSE );
376             SystemParametersInfoA( SPI_GETICONTITLEWRAP, 0,
377                                    &lpIcon->iTitleWrap, FALSE );
378             SystemParametersInfoA( SPI_GETICONTITLELOGFONT, 0,
379                                    &lpIcon->lfFont, FALSE );
380         }
381         else
382         {
383             ret = FALSE;
384         }
385         break;
386     }
387     WINE_SPI_FIXME(SPI_SETICONMETRICS);         /*     46  WINVER >= 0x400 */
388
389     WINE_SPI_FIXME(SPI_SETWORKAREA);            /*     47  WINVER >= 0x400 */
390     case SPI_GETWORKAREA:                       /*     48  WINVER >= 0x400 */
391         SetRect( (RECT *)pvParam, 0, 0,
392                  GetSystemMetrics( SM_CXSCREEN ),
393                  GetSystemMetrics( SM_CYSCREEN ) );
394         break;
395     
396     WINE_SPI_FIXME(SPI_SETPENWINDOWS);          /*     49  WINVER >= 0x400 */
397
398     WINE_SPI_FIXME(SPI_GETFILTERKEYS);          /*     50 */
399     WINE_SPI_FIXME(SPI_SETFILTERKEYS);          /*     51 */
400     WINE_SPI_FIXME(SPI_GETTOGGLEKEYS);          /*     52 */
401     WINE_SPI_FIXME(SPI_SETTOGGLEKEYS);          /*     53 */
402     WINE_SPI_FIXME(SPI_GETMOUSEKEYS);           /*     54 */
403     WINE_SPI_FIXME(SPI_SETMOUSEKEYS);           /*     55 */
404     WINE_SPI_FIXME(SPI_GETSHOWSOUNDS);          /*     56 */
405     WINE_SPI_FIXME(SPI_SETSHOWSOUNDS);          /*     57 */
406     WINE_SPI_FIXME(SPI_GETSTICKYKEYS);          /*     58 */
407     WINE_SPI_FIXME(SPI_SETSTICKYKEYS);          /*     59 */
408     WINE_SPI_FIXME(SPI_GETACCESSTIMEOUT);       /*     60 */
409     WINE_SPI_FIXME(SPI_SETACCESSTIMEOUT);       /*     61 */
410
411     WINE_SPI_FIXME(SPI_GETSERIALKEYS);          /*     62  WINVER >= 0x400 */
412     WINE_SPI_FIXME(SPI_SETSERIALKEYS);          /*     63  WINVER >= 0x400 */
413
414     WINE_SPI_FIXME(SPI_GETSOUNDSENTRY);         /*     64 */
415     WINE_SPI_FIXME(SPI_SETSOUNDSENTRY);         /*     65 */
416     
417     case SPI_GETHIGHCONTRAST:                   /*     66  WINVER >= 0x400 */
418     {
419         LPHIGHCONTRASTA lpHighContrastA = (LPHIGHCONTRASTA)pvParam;
420         WARN("SPI_GETHIGHCONTRAST not fully implemented\n");
421         if (lpHighContrastA->cbSize == sizeof(HIGHCONTRASTA))
422         {
423             /* Indicate that there is no high contrast available */
424             lpHighContrastA->dwFlags = 0;
425             lpHighContrastA->lpszDefaultScheme = NULL;
426         }
427         else
428         {
429             ret = FALSE;
430         }
431         break;
432     }
433     WINE_SPI_FIXME(SPI_SETHIGHCONTRAST);        /*     67  WINVER >= 0x400 */
434
435     WINE_SPI_FIXME(SPI_GETKEYBOARDPREF);        /*     68  WINVER >= 0x400 */
436     WINE_SPI_FIXME(SPI_SETKEYBOARDPREF);        /*     69  WINVER >= 0x400 */
437
438     WINE_SPI_FIXME(SPI_GETSCREENREADER);        /*     70  WINVER >= 0x400 */
439     WINE_SPI_FIXME(SPI_SETSCREENREADER);        /*     71  WINVER >= 0x400 */
440
441     case SPI_GETANIMATION:                      /*     72  WINVER >= 0x400 */
442     {
443         LPANIMATIONINFO lpAnimInfo = (LPANIMATIONINFO)pvParam;
444  
445         /* Tell it "disabled" */
446         if (lpAnimInfo->cbSize == sizeof(ANIMATIONINFO))
447             lpAnimInfo->iMinAnimate = 0; /* Minimise and restore animation is disabled (nonzero == enabled) */
448         else
449             ret = FALSE;
450         break;
451     }
452     WINE_SPI_WARN(SPI_SETANIMATION);            /*     73  WINVER >= 0x400 */
453
454     WINE_SPI_FIXME(SPI_GETFONTSMOOTHING);       /*     74  WINVER >= 0x400 */
455     WINE_SPI_FIXME(SPI_SETFONTSMOOTHING);       /*     75  WINVER >= 0x400 */
456
457     WINE_SPI_FIXME(SPI_SETDRAGWIDTH);           /*     76  WINVER >= 0x400 */
458     WINE_SPI_FIXME(SPI_SETDRAGHEIGHT);          /*     77  WINVER >= 0x400 */
459
460     WINE_SPI_FIXME(SPI_SETHANDHELD);            /*     78  WINVER >= 0x400 */
461
462     WINE_SPI_FIXME(SPI_GETLOWPOWERTIMEOUT);     /*     79  WINVER >= 0x400 */
463     WINE_SPI_FIXME(SPI_GETPOWEROFFTIMEOUT);     /*     80  WINVER >= 0x400 */
464     WINE_SPI_FIXME(SPI_SETLOWPOWERTIMEOUT);     /*     81  WINVER >= 0x400 */
465     WINE_SPI_FIXME(SPI_SETPOWEROFFTIMEOUT);     /*     82  WINVER >= 0x400 */
466     WINE_SPI_FIXME(SPI_GETLOWPOWERACTIVE);      /*     83  WINVER >= 0x400 */
467     WINE_SPI_FIXME(SPI_GETPOWEROFFACTIVE);      /*     84  WINVER >= 0x400 */
468     WINE_SPI_FIXME(SPI_SETLOWPOWERACTIVE);      /*     85  WINVER >= 0x400 */
469     WINE_SPI_FIXME(SPI_SETPOWEROFFACTIVE);      /*     86  WINVER >= 0x400 */
470     
471     WINE_SPI_FIXME(SPI_SETCURSORS);             /*     87  WINVER >= 0x400 */
472     WINE_SPI_FIXME(SPI_SETICONS);               /*     88  WINVER >= 0x400 */
473
474     WINE_SPI_FIXME(SPI_GETDEFAULTINPUTLANG);    /*     89  WINVER >= 0x400 */
475     WINE_SPI_FIXME(SPI_SETDEFAULTINPUTLANG);    /*     90  WINVER >= 0x400 */
476
477     WINE_SPI_FIXME(SPI_SETLANGTOGGLE);          /*     91  WINVER >= 0x400 */
478
479     case SPI_GETWINDOWSEXTENSION:               /*     92  WINVER >= 0x400 */
480         WARN("pretend no support for Win9x Plus! for now.\n");
481         ret = FALSE; /* yes, this is the result value */
482         break;
483
484     WINE_SPI_FIXME(SPI_SETMOUSETRAILS);         /*     93  WINVER >= 0x400 */
485     WINE_SPI_FIXME(SPI_GETMOUSETRAILS);         /*     94  WINVER >= 0x400 */
486         
487     WINE_SPI_FIXME(SPI_SETSCREENSAVERRUNNING);  /*     97  WINVER >= 0x400 */
488     /* SPI_SCREENSAVERRUNNING is an alias for SPI_SETSCREENSAVERRUNNING */
489
490     case SPI_GETMOUSEHOVERWIDTH:                /*     98  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
491         *(UINT *)pvParam = 4;
492         break;
493     WINE_SPI_FIXME(SPI_SETMOUSEHOVERWIDTH);     /*     99  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
494
495     case SPI_GETMOUSEHOVERHEIGHT:               /*    100  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
496         *(UINT *)pvParam = 4;
497         break;
498     WINE_SPI_FIXME(SPI_SETMOUSEHOVERHEIGHT);    /*    101  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
499
500     case SPI_GETMOUSEHOVERTIME:                 /*    102  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
501         *(UINT *)pvParam = 400; /* default for menu dropdowns */
502         break;
503     WINE_SPI_FIXME(SPI_SETMOUSEHOVERTIME);      /*    103  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
504               
505     case SPI_GETWHEELSCROLLLINES:               /*    104  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
506         *(UINT *)pvParam = 3; /* default for num scroll lines */  
507         break;
508     WINE_SPI_FIXME(SPI_SETWHEELSCROLLLINES);    /*    105  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
509
510     WINE_SPI_FIXME(SPI_GETSHOWIMEUI);           /*    110  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
511     WINE_SPI_FIXME(SPI_SETSHOWIMEUI);           /*    111  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
512
513     default:
514         FIXME( "Unknown action: %u\n", uiAction );
515         SetLastError( ERROR_INVALID_SPI_VALUE );
516         ret = FALSE;
517         break;
518     }
519
520     return ret;
521     
522 #undef WINE_SPI_FIXME
523 #undef WINE_SPI_WARN
524 }
525
526
527 /***********************************************************************
528  *              SystemParametersInfo (USER.483)
529  */
530 BOOL16 WINAPI SystemParametersInfo16( UINT16 uAction, UINT16 uParam,
531                                       LPVOID lpvParam, UINT16 fuWinIni )
532 {
533     BOOL16 ret;
534
535     TRACE("(%u, %u, %p, %u)\n", uAction, uParam, lpvParam, fuWinIni);
536     
537     switch (uAction)
538     {
539     case SPI_GETBEEP:                           /*      1 */
540     case SPI_GETSCREENSAVEACTIVE:               /*     16 */
541     case SPI_GETICONTITLEWRAP:                  /*     25 */
542     case SPI_GETMENUDROPALIGNMENT:              /*     27 */
543     case SPI_GETFASTTASKSWITCH:                 /*     35 */
544     case SPI_GETDRAGFULLWINDOWS:                /*     38  WINVER >= 0x0400 */
545     {
546         BOOL tmp;
547         ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
548         if (ret && lpvParam)
549             *(BOOL16 *)lpvParam = tmp;
550         break;
551     }
552
553     case SPI_GETBORDER:                         /*      5 */
554     case SPI_ICONHORIZONTALSPACING:             /*     13 */
555     case SPI_GETSCREENSAVETIMEOUT:              /*     14 */
556     case SPI_GETGRIDGRANULARITY:                /*     18 */
557     case SPI_GETKEYBOARDDELAY:                  /*     22 */
558     case SPI_ICONVERTICALSPACING:               /*     24 */
559     {
560         INT tmp;
561         ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
562         if (ret && lpvParam)
563             *(INT16 *)lpvParam = tmp;
564         break;
565     }
566
567     case SPI_GETKEYBOARDSPEED:                  /*     10 */
568     {
569         DWORD tmp;
570         ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
571         if (ret && lpvParam)
572             *(WORD *)lpvParam = tmp;
573         break;
574     }
575
576     case SPI_GETICONTITLELOGFONT:               /*     31 */
577     {
578         LOGFONTA tmp;
579         ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
580         if (ret && lpvParam)
581             SYSPARAMS_LogFont32ATo16( &tmp, (LPLOGFONT16)lpvParam );
582         break;
583     }
584
585     case SPI_GETNONCLIENTMETRICS:               /*     41  WINVER >= 0x400 */
586     {
587         NONCLIENTMETRICSA tmp;
588         LPNONCLIENTMETRICS16 lpnm16 = (LPNONCLIENTMETRICS16)lpvParam;
589         if (lpnm16 && lpnm16->cbSize == sizeof(NONCLIENTMETRICS16))
590         {
591             tmp.cbSize = sizeof(NONCLIENTMETRICSA);
592             ret = SystemParametersInfoA( uAction, uParam, &tmp, fuWinIni );
593             if (ret)
594                 SYSPARAMS_NonClientMetrics32ATo16( &tmp, lpnm16 );
595         }
596         else /* winfile 95 sets cbSize to 340 */
597             ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
598         break;
599     }
600     
601     case SPI_GETWORKAREA:                       /*     48  WINVER >= 0x400 */
602     {
603         RECT tmp;
604         ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
605         if (ret && lpvParam)
606             CONV_RECT32TO16( &tmp, (RECT16 *)lpvParam );
607         break;
608     }
609         
610     case SPI_GETMOUSEHOVERWIDTH:                /*     98  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
611     case SPI_GETMOUSEHOVERHEIGHT:               /*    100  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
612     case SPI_GETMOUSEHOVERTIME:                 /*    102  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
613     {
614         UINT tmp;
615         ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
616         if (ret && lpvParam)
617             *(UINT16 *)lpvParam = tmp;
618         break;
619     }
620
621     default:
622         ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
623     }
624
625     return ret;
626 }
627
628 /***********************************************************************
629  *              SystemParametersInfoW (USER32.@)
630  */
631 BOOL WINAPI SystemParametersInfoW( UINT uiAction, UINT uiParam,
632                                    PVOID pvParam, UINT fuWinIni )
633 {
634     BOOL ret;
635
636     TRACE("(%u, %u, %p, %u)\n", uiAction, uiParam, pvParam, fuWinIni);
637     
638     switch (uiAction)
639     {
640     case SPI_SETDESKWALLPAPER:                  /*     20 */
641     case SPI_SETDESKPATTERN:                    /*     21 */
642     {
643         char buffer[256];
644         if (pvParam)
645             if (!WideCharToMultiByte( CP_ACP, 0, (LPWSTR)pvParam, -1,
646                                       buffer, sizeof(buffer), NULL, NULL ))
647                 buffer[sizeof(buffer)-1] = 0;
648         ret = SystemParametersInfoA( uiAction, uiParam, pvParam ? buffer : NULL, fuWinIni );
649         break;
650     }
651
652     case SPI_GETICONTITLELOGFONT:               /*     31 */
653     {
654         LOGFONTA tmp;
655         ret = SystemParametersInfoA( uiAction, uiParam, pvParam ? &tmp : NULL, fuWinIni );
656         if (ret && pvParam)
657             SYSPARAMS_LogFont32ATo32W( &tmp, (LPLOGFONTW)pvParam );
658         break;
659     }
660
661     case SPI_GETNONCLIENTMETRICS:               /*     41  WINVER >= 0x400 */
662     {
663         NONCLIENTMETRICSA tmp;
664         LPNONCLIENTMETRICSW lpnmW = (LPNONCLIENTMETRICSW)pvParam;
665         if (lpnmW && lpnmW->cbSize == sizeof(NONCLIENTMETRICSW))
666         {
667             tmp.cbSize = sizeof(NONCLIENTMETRICSA);
668             ret = SystemParametersInfoA( uiAction, uiParam, &tmp, fuWinIni );
669             if (ret)
670                 SYSPARAMS_NonClientMetrics32ATo32W( &tmp, lpnmW );
671         }
672         else
673             ret = FALSE;
674         break;
675     }
676
677     case SPI_GETICONMETRICS:                    /*     45  WINVER >= 0x400 */
678     {
679         ICONMETRICSA tmp;
680         LPICONMETRICSW lpimW = (LPICONMETRICSW)pvParam;
681         if (lpimW && lpimW->cbSize == sizeof(ICONMETRICSW))
682         {
683             tmp.cbSize = sizeof(ICONMETRICSA);
684             ret = SystemParametersInfoA( uiAction, uiParam, &tmp, fuWinIni );
685             if (ret)
686             {
687                 lpimW->iHorzSpacing = tmp.iHorzSpacing;
688                 lpimW->iVertSpacing = tmp.iVertSpacing;
689                 lpimW->iTitleWrap   = tmp.iTitleWrap;
690                 SYSPARAMS_LogFont32ATo32W( &tmp.lfFont, &lpimW->lfFont );
691             }
692         }
693         else
694             ret = FALSE;
695         break;
696     }
697
698     case SPI_GETHIGHCONTRAST:                   /*     66  WINVER >= 0x400 */
699     {
700         HIGHCONTRASTA tmp;
701         LPHIGHCONTRASTW lphcW = (LPHIGHCONTRASTW)pvParam;
702         if (lphcW && lphcW->cbSize == sizeof(HIGHCONTRASTW))
703         {
704             tmp.cbSize = sizeof(HIGHCONTRASTA);
705             ret = SystemParametersInfoA( uiAction, uiParam, &tmp, fuWinIni );
706             if (ret)
707             {
708                 lphcW->dwFlags = tmp.dwFlags;
709                 lphcW->lpszDefaultScheme = NULL;  /* FIXME? */
710             }
711         }
712         else
713             ret = FALSE;
714         break;
715     }
716     
717     default:
718         ret = SystemParametersInfoA( uiAction, uiParam, pvParam, fuWinIni );
719     }
720
721     return ret;
722 }