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