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