Added offsetof (for the MFC).
[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
509     WINE_SPI_FIXME(SPI_SETWHEELSCROLLLINES);    /*    105  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
510
511     case SPI_GETMENUSHOWDELAY:                  /*    106  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
512         *(UINT *)pvParam = 400; /* Tested against Windows NT 4.0 and Windows 2000 */
513         break;
514
515     WINE_SPI_FIXME(SPI_GETSHOWIMEUI);           /*    110  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
516     WINE_SPI_FIXME(SPI_SETSHOWIMEUI);           /*    111  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
517
518     default:
519         FIXME( "Unknown action: %u\n", uiAction );
520         SetLastError( ERROR_INVALID_SPI_VALUE );
521         ret = FALSE;
522         break;
523     }
524
525     return ret;
526     
527 #undef WINE_SPI_FIXME
528 #undef WINE_SPI_WARN
529 }
530
531
532 /***********************************************************************
533  *              SystemParametersInfo (USER.483)
534  */
535 BOOL16 WINAPI SystemParametersInfo16( UINT16 uAction, UINT16 uParam,
536                                       LPVOID lpvParam, UINT16 fuWinIni )
537 {
538     BOOL16 ret;
539
540     TRACE("(%u, %u, %p, %u)\n", uAction, uParam, lpvParam, fuWinIni);
541     
542     switch (uAction)
543     {
544     case SPI_GETBEEP:                           /*      1 */
545     case SPI_GETSCREENSAVEACTIVE:               /*     16 */
546     case SPI_GETICONTITLEWRAP:                  /*     25 */
547     case SPI_GETMENUDROPALIGNMENT:              /*     27 */
548     case SPI_GETFASTTASKSWITCH:                 /*     35 */
549     case SPI_GETDRAGFULLWINDOWS:                /*     38  WINVER >= 0x0400 */
550     {
551         BOOL tmp;
552         ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
553         if (ret && lpvParam)
554             *(BOOL16 *)lpvParam = tmp;
555         break;
556     }
557
558     case SPI_GETBORDER:                         /*      5 */
559     case SPI_ICONHORIZONTALSPACING:             /*     13 */
560     case SPI_GETSCREENSAVETIMEOUT:              /*     14 */
561     case SPI_GETGRIDGRANULARITY:                /*     18 */
562     case SPI_GETKEYBOARDDELAY:                  /*     22 */
563     case SPI_ICONVERTICALSPACING:               /*     24 */
564     {
565         INT tmp;
566         ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
567         if (ret && lpvParam)
568             *(INT16 *)lpvParam = tmp;
569         break;
570     }
571
572     case SPI_GETKEYBOARDSPEED:                  /*     10 */
573     {
574         DWORD tmp;
575         ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
576         if (ret && lpvParam)
577             *(WORD *)lpvParam = tmp;
578         break;
579     }
580
581     case SPI_GETICONTITLELOGFONT:               /*     31 */
582     {
583         LOGFONTA tmp;
584         ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
585         if (ret && lpvParam)
586             SYSPARAMS_LogFont32ATo16( &tmp, (LPLOGFONT16)lpvParam );
587         break;
588     }
589
590     case SPI_GETNONCLIENTMETRICS:               /*     41  WINVER >= 0x400 */
591     {
592         NONCLIENTMETRICSA tmp;
593         LPNONCLIENTMETRICS16 lpnm16 = (LPNONCLIENTMETRICS16)lpvParam;
594         if (lpnm16 && lpnm16->cbSize == sizeof(NONCLIENTMETRICS16))
595         {
596             tmp.cbSize = sizeof(NONCLIENTMETRICSA);
597             ret = SystemParametersInfoA( uAction, uParam, &tmp, fuWinIni );
598             if (ret)
599                 SYSPARAMS_NonClientMetrics32ATo16( &tmp, lpnm16 );
600         }
601         else /* winfile 95 sets cbSize to 340 */
602             ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
603         break;
604     }
605     
606     case SPI_GETWORKAREA:                       /*     48  WINVER >= 0x400 */
607     {
608         RECT tmp;
609         ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
610         if (ret && lpvParam)
611             CONV_RECT32TO16( &tmp, (RECT16 *)lpvParam );
612         break;
613     }
614         
615     case SPI_GETMOUSEHOVERWIDTH:                /*     98  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
616     case SPI_GETMOUSEHOVERHEIGHT:               /*    100  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
617     case SPI_GETMOUSEHOVERTIME:                 /*    102  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
618     {
619         UINT tmp;
620         ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
621         if (ret && lpvParam)
622             *(UINT16 *)lpvParam = tmp;
623         break;
624     }
625
626     default:
627         ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
628     }
629
630     return ret;
631 }
632
633 /***********************************************************************
634  *              SystemParametersInfoW (USER32.@)
635  */
636 BOOL WINAPI SystemParametersInfoW( UINT uiAction, UINT uiParam,
637                                    PVOID pvParam, UINT fuWinIni )
638 {
639     BOOL ret;
640
641     TRACE("(%u, %u, %p, %u)\n", uiAction, uiParam, pvParam, fuWinIni);
642     
643     switch (uiAction)
644     {
645     case SPI_SETDESKWALLPAPER:                  /*     20 */
646     case SPI_SETDESKPATTERN:                    /*     21 */
647     {
648         char buffer[256];
649         if (pvParam)
650             if (!WideCharToMultiByte( CP_ACP, 0, (LPWSTR)pvParam, -1,
651                                       buffer, sizeof(buffer), NULL, NULL ))
652                 buffer[sizeof(buffer)-1] = 0;
653         ret = SystemParametersInfoA( uiAction, uiParam, pvParam ? buffer : NULL, fuWinIni );
654         break;
655     }
656
657     case SPI_GETICONTITLELOGFONT:               /*     31 */
658     {
659         LOGFONTA tmp;
660         ret = SystemParametersInfoA( uiAction, uiParam, pvParam ? &tmp : NULL, fuWinIni );
661         if (ret && pvParam)
662             SYSPARAMS_LogFont32ATo32W( &tmp, (LPLOGFONTW)pvParam );
663         break;
664     }
665
666     case SPI_GETNONCLIENTMETRICS:               /*     41  WINVER >= 0x400 */
667     {
668         NONCLIENTMETRICSA tmp;
669         LPNONCLIENTMETRICSW lpnmW = (LPNONCLIENTMETRICSW)pvParam;
670         if (lpnmW && lpnmW->cbSize == sizeof(NONCLIENTMETRICSW))
671         {
672             tmp.cbSize = sizeof(NONCLIENTMETRICSA);
673             ret = SystemParametersInfoA( uiAction, uiParam, &tmp, fuWinIni );
674             if (ret)
675                 SYSPARAMS_NonClientMetrics32ATo32W( &tmp, lpnmW );
676         }
677         else
678             ret = FALSE;
679         break;
680     }
681
682     case SPI_GETICONMETRICS:                    /*     45  WINVER >= 0x400 */
683     {
684         ICONMETRICSA tmp;
685         LPICONMETRICSW lpimW = (LPICONMETRICSW)pvParam;
686         if (lpimW && lpimW->cbSize == sizeof(ICONMETRICSW))
687         {
688             tmp.cbSize = sizeof(ICONMETRICSA);
689             ret = SystemParametersInfoA( uiAction, uiParam, &tmp, fuWinIni );
690             if (ret)
691             {
692                 lpimW->iHorzSpacing = tmp.iHorzSpacing;
693                 lpimW->iVertSpacing = tmp.iVertSpacing;
694                 lpimW->iTitleWrap   = tmp.iTitleWrap;
695                 SYSPARAMS_LogFont32ATo32W( &tmp.lfFont, &lpimW->lfFont );
696             }
697         }
698         else
699             ret = FALSE;
700         break;
701     }
702
703     case SPI_GETHIGHCONTRAST:                   /*     66  WINVER >= 0x400 */
704     {
705         HIGHCONTRASTA tmp;
706         LPHIGHCONTRASTW lphcW = (LPHIGHCONTRASTW)pvParam;
707         if (lphcW && lphcW->cbSize == sizeof(HIGHCONTRASTW))
708         {
709             tmp.cbSize = sizeof(HIGHCONTRASTA);
710             ret = SystemParametersInfoA( uiAction, uiParam, &tmp, fuWinIni );
711             if (ret)
712             {
713                 lphcW->dwFlags = tmp.dwFlags;
714                 lphcW->lpszDefaultScheme = NULL;  /* FIXME? */
715             }
716         }
717         else
718             ret = FALSE;
719         break;
720     }
721     
722     default:
723         ret = SystemParametersInfoA( uiAction, uiParam, pvParam, fuWinIni );
724     }
725
726     return ret;
727 }