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