Added basic support for SPI_GETSCREENREADER.
[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     case SPI_GETSCREENREADER:
441     {
442        LPBOOL   bool = (LPBOOL)pvParam;
443        *bool = FALSE;
444        break;
445     }
446
447     WINE_SPI_FIXME(SPI_SETSCREENREADER);        /*     71  WINVER >= 0x400 */
448
449     case SPI_GETANIMATION:                      /*     72  WINVER >= 0x400 */
450     {
451         LPANIMATIONINFO lpAnimInfo = (LPANIMATIONINFO)pvParam;
452  
453         /* Tell it "disabled" */
454         if (lpAnimInfo->cbSize == sizeof(ANIMATIONINFO))
455             lpAnimInfo->iMinAnimate = 0; /* Minimise and restore animation is disabled (nonzero == enabled) */
456         else
457             ret = FALSE;
458         break;
459     }
460     WINE_SPI_WARN(SPI_SETANIMATION);            /*     73  WINVER >= 0x400 */
461
462     WINE_SPI_FIXME(SPI_GETFONTSMOOTHING);       /*     74  WINVER >= 0x400 */
463     WINE_SPI_FIXME(SPI_SETFONTSMOOTHING);       /*     75  WINVER >= 0x400 */
464
465     WINE_SPI_FIXME(SPI_SETDRAGWIDTH);           /*     76  WINVER >= 0x400 */
466     WINE_SPI_FIXME(SPI_SETDRAGHEIGHT);          /*     77  WINVER >= 0x400 */
467
468     WINE_SPI_FIXME(SPI_SETHANDHELD);            /*     78  WINVER >= 0x400 */
469
470     WINE_SPI_FIXME(SPI_GETLOWPOWERTIMEOUT);     /*     79  WINVER >= 0x400 */
471     WINE_SPI_FIXME(SPI_GETPOWEROFFTIMEOUT);     /*     80  WINVER >= 0x400 */
472     WINE_SPI_FIXME(SPI_SETLOWPOWERTIMEOUT);     /*     81  WINVER >= 0x400 */
473     WINE_SPI_FIXME(SPI_SETPOWEROFFTIMEOUT);     /*     82  WINVER >= 0x400 */
474     WINE_SPI_FIXME(SPI_GETLOWPOWERACTIVE);      /*     83  WINVER >= 0x400 */
475     WINE_SPI_FIXME(SPI_GETPOWEROFFACTIVE);      /*     84  WINVER >= 0x400 */
476     WINE_SPI_FIXME(SPI_SETLOWPOWERACTIVE);      /*     85  WINVER >= 0x400 */
477     WINE_SPI_FIXME(SPI_SETPOWEROFFACTIVE);      /*     86  WINVER >= 0x400 */
478     
479     WINE_SPI_FIXME(SPI_SETCURSORS);             /*     87  WINVER >= 0x400 */
480     WINE_SPI_FIXME(SPI_SETICONS);               /*     88  WINVER >= 0x400 */
481
482     WINE_SPI_FIXME(SPI_GETDEFAULTINPUTLANG);    /*     89  WINVER >= 0x400 */
483     WINE_SPI_FIXME(SPI_SETDEFAULTINPUTLANG);    /*     90  WINVER >= 0x400 */
484
485     WINE_SPI_FIXME(SPI_SETLANGTOGGLE);          /*     91  WINVER >= 0x400 */
486
487     case SPI_GETWINDOWSEXTENSION:               /*     92  WINVER >= 0x400 */
488         WARN("pretend no support for Win9x Plus! for now.\n");
489         ret = FALSE; /* yes, this is the result value */
490         break;
491
492     WINE_SPI_FIXME(SPI_SETMOUSETRAILS);         /*     93  WINVER >= 0x400 */
493     WINE_SPI_FIXME(SPI_GETMOUSETRAILS);         /*     94  WINVER >= 0x400 */
494         
495     WINE_SPI_FIXME(SPI_SETSCREENSAVERRUNNING);  /*     97  WINVER >= 0x400 */
496     /* SPI_SCREENSAVERRUNNING is an alias for SPI_SETSCREENSAVERRUNNING */
497
498     case SPI_GETMOUSEHOVERWIDTH:                /*     98  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
499         *(UINT *)pvParam = 4;
500         break;
501     WINE_SPI_FIXME(SPI_SETMOUSEHOVERWIDTH);     /*     99  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
502
503     case SPI_GETMOUSEHOVERHEIGHT:               /*    100  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
504         *(UINT *)pvParam = 4;
505         break;
506     WINE_SPI_FIXME(SPI_SETMOUSEHOVERHEIGHT);    /*    101  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
507
508     case SPI_GETMOUSEHOVERTIME:                 /*    102  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
509         *(UINT *)pvParam = 400; /* default for menu dropdowns */
510         break;
511     WINE_SPI_FIXME(SPI_SETMOUSEHOVERTIME);      /*    103  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
512               
513     case SPI_GETWHEELSCROLLLINES:               /*    104  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
514         *(UINT *)pvParam = 3; /* default for num scroll lines */  
515         break;
516
517     WINE_SPI_FIXME(SPI_SETWHEELSCROLLLINES);    /*    105  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
518
519     case SPI_GETMENUSHOWDELAY:                  /*    106  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
520         *(UINT *)pvParam = 400; /* Tested against Windows NT 4.0 and Windows 2000 */
521         break;
522
523     WINE_SPI_FIXME(SPI_GETSHOWIMEUI);           /*    110  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
524     WINE_SPI_FIXME(SPI_SETSHOWIMEUI);           /*    111  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
525
526     default:
527         FIXME( "Unknown action: %u\n", uiAction );
528         SetLastError( ERROR_INVALID_SPI_VALUE );
529         ret = FALSE;
530         break;
531     }
532
533     return ret;
534     
535 #undef WINE_SPI_FIXME
536 #undef WINE_SPI_WARN
537 }
538
539
540 /***********************************************************************
541  *              SystemParametersInfo (USER.483)
542  */
543 BOOL16 WINAPI SystemParametersInfo16( UINT16 uAction, UINT16 uParam,
544                                       LPVOID lpvParam, UINT16 fuWinIni )
545 {
546     BOOL16 ret;
547
548     TRACE("(%u, %u, %p, %u)\n", uAction, uParam, lpvParam, fuWinIni);
549     
550     switch (uAction)
551     {
552     case SPI_GETBEEP:                           /*      1 */
553     case SPI_GETSCREENSAVEACTIVE:               /*     16 */
554     case SPI_GETICONTITLEWRAP:                  /*     25 */
555     case SPI_GETMENUDROPALIGNMENT:              /*     27 */
556     case SPI_GETFASTTASKSWITCH:                 /*     35 */
557     case SPI_GETDRAGFULLWINDOWS:                /*     38  WINVER >= 0x0400 */
558     {
559         BOOL tmp;
560         ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
561         if (ret && lpvParam)
562             *(BOOL16 *)lpvParam = tmp;
563         break;
564     }
565
566     case SPI_GETBORDER:                         /*      5 */
567     case SPI_ICONHORIZONTALSPACING:             /*     13 */
568     case SPI_GETSCREENSAVETIMEOUT:              /*     14 */
569     case SPI_GETGRIDGRANULARITY:                /*     18 */
570     case SPI_GETKEYBOARDDELAY:                  /*     22 */
571     case SPI_ICONVERTICALSPACING:               /*     24 */
572     {
573         INT tmp;
574         ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
575         if (ret && lpvParam)
576             *(INT16 *)lpvParam = tmp;
577         break;
578     }
579
580     case SPI_GETKEYBOARDSPEED:                  /*     10 */
581     {
582         DWORD tmp;
583         ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
584         if (ret && lpvParam)
585             *(WORD *)lpvParam = tmp;
586         break;
587     }
588
589     case SPI_GETICONTITLELOGFONT:               /*     31 */
590     {
591         LOGFONTA tmp;
592         ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
593         if (ret && lpvParam)
594             SYSPARAMS_LogFont32ATo16( &tmp, (LPLOGFONT16)lpvParam );
595         break;
596     }
597
598     case SPI_GETNONCLIENTMETRICS:               /*     41  WINVER >= 0x400 */
599     {
600         NONCLIENTMETRICSA tmp;
601         LPNONCLIENTMETRICS16 lpnm16 = (LPNONCLIENTMETRICS16)lpvParam;
602         if (lpnm16 && lpnm16->cbSize == sizeof(NONCLIENTMETRICS16))
603         {
604             tmp.cbSize = sizeof(NONCLIENTMETRICSA);
605             ret = SystemParametersInfoA( uAction, uParam, &tmp, fuWinIni );
606             if (ret)
607                 SYSPARAMS_NonClientMetrics32ATo16( &tmp, lpnm16 );
608         }
609         else /* winfile 95 sets cbSize to 340 */
610             ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
611         break;
612     }
613     
614     case SPI_GETWORKAREA:                       /*     48  WINVER >= 0x400 */
615     {
616         RECT tmp;
617         ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
618         if (ret && lpvParam)
619             CONV_RECT32TO16( &tmp, (RECT16 *)lpvParam );
620         break;
621     }
622         
623     case SPI_GETMOUSEHOVERWIDTH:                /*     98  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
624     case SPI_GETMOUSEHOVERHEIGHT:               /*    100  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
625     case SPI_GETMOUSEHOVERTIME:                 /*    102  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
626     {
627         UINT tmp;
628         ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
629         if (ret && lpvParam)
630             *(UINT16 *)lpvParam = tmp;
631         break;
632     }
633
634     default:
635         ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
636     }
637
638     return ret;
639 }
640
641 /***********************************************************************
642  *              SystemParametersInfoW (USER32.@)
643  */
644 BOOL WINAPI SystemParametersInfoW( UINT uiAction, UINT uiParam,
645                                    PVOID pvParam, UINT fuWinIni )
646 {
647     BOOL ret;
648
649     TRACE("(%u, %u, %p, %u)\n", uiAction, uiParam, pvParam, fuWinIni);
650     
651     switch (uiAction)
652     {
653     case SPI_SETDESKWALLPAPER:                  /*     20 */
654     case SPI_SETDESKPATTERN:                    /*     21 */
655     {
656         char buffer[256];
657         if (pvParam)
658             if (!WideCharToMultiByte( CP_ACP, 0, (LPWSTR)pvParam, -1,
659                                       buffer, sizeof(buffer), NULL, NULL ))
660                 buffer[sizeof(buffer)-1] = 0;
661         ret = SystemParametersInfoA( uiAction, uiParam, pvParam ? buffer : NULL, fuWinIni );
662         break;
663     }
664
665     case SPI_GETICONTITLELOGFONT:               /*     31 */
666     {
667         LOGFONTA tmp;
668         ret = SystemParametersInfoA( uiAction, uiParam, pvParam ? &tmp : NULL, fuWinIni );
669         if (ret && pvParam)
670             SYSPARAMS_LogFont32ATo32W( &tmp, (LPLOGFONTW)pvParam );
671         break;
672     }
673
674     case SPI_GETNONCLIENTMETRICS:               /*     41  WINVER >= 0x400 */
675     {
676         NONCLIENTMETRICSA tmp;
677         LPNONCLIENTMETRICSW lpnmW = (LPNONCLIENTMETRICSW)pvParam;
678         if (lpnmW && lpnmW->cbSize == sizeof(NONCLIENTMETRICSW))
679         {
680             tmp.cbSize = sizeof(NONCLIENTMETRICSA);
681             ret = SystemParametersInfoA( uiAction, uiParam, &tmp, fuWinIni );
682             if (ret)
683                 SYSPARAMS_NonClientMetrics32ATo32W( &tmp, lpnmW );
684         }
685         else
686             ret = FALSE;
687         break;
688     }
689
690     case SPI_GETICONMETRICS:                    /*     45  WINVER >= 0x400 */
691     {
692         ICONMETRICSA tmp;
693         LPICONMETRICSW lpimW = (LPICONMETRICSW)pvParam;
694         if (lpimW && lpimW->cbSize == sizeof(ICONMETRICSW))
695         {
696             tmp.cbSize = sizeof(ICONMETRICSA);
697             ret = SystemParametersInfoA( uiAction, uiParam, &tmp, fuWinIni );
698             if (ret)
699             {
700                 lpimW->iHorzSpacing = tmp.iHorzSpacing;
701                 lpimW->iVertSpacing = tmp.iVertSpacing;
702                 lpimW->iTitleWrap   = tmp.iTitleWrap;
703                 SYSPARAMS_LogFont32ATo32W( &tmp.lfFont, &lpimW->lfFont );
704             }
705         }
706         else
707             ret = FALSE;
708         break;
709     }
710
711     case SPI_GETHIGHCONTRAST:                   /*     66  WINVER >= 0x400 */
712     {
713         HIGHCONTRASTA tmp;
714         LPHIGHCONTRASTW lphcW = (LPHIGHCONTRASTW)pvParam;
715         if (lphcW && lphcW->cbSize == sizeof(HIGHCONTRASTW))
716         {
717             tmp.cbSize = sizeof(HIGHCONTRASTA);
718             ret = SystemParametersInfoA( uiAction, uiParam, &tmp, fuWinIni );
719             if (ret)
720             {
721                 lphcW->dwFlags = tmp.dwFlags;
722                 lphcW->lpszDefaultScheme = NULL;  /* FIXME? */
723             }
724         }
725         else
726             ret = FALSE;
727         break;
728     }
729     
730     default:
731         ret = SystemParametersInfoA( uiAction, uiParam, pvParam, fuWinIni );
732     }
733
734     return ret;
735 }