Fixed a few prototypes in the USER driver.
[wine] / dlls / user / sysparams.c
1 /*
2  * System parameters functions
3  *
4  * Copyright 1994 Alexandre Julliard
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "config.h"
22
23 #include <assert.h>
24 #include <stdarg.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winnls.h"
31 #include "wingdi.h"
32 #include "winreg.h"
33 #include "wine/winuser16.h"
34 #include "winerror.h"
35
36 #include "controls.h"
37 #include "user_private.h"
38 #include "wine/unicode.h"
39 #include "wine/debug.h"
40
41 WINE_DEFAULT_DEBUG_CHANNEL(system);
42
43 /* System parameter indexes */
44 enum spi_index
45 {
46     SPI_SETBEEP_IDX,
47     SPI_SETMOUSE_IDX,
48     SPI_SETBORDER_IDX,
49     SPI_SETKEYBOARDSPEED_IDX,
50     SPI_ICONHORIZONTALSPACING_IDX,
51     SPI_SETSCREENSAVETIMEOUT_IDX,
52     SPI_SETGRIDGRANULARITY_IDX,
53     SPI_SETKEYBOARDDELAY_IDX,
54     SPI_ICONVERTICALSPACING_IDX,
55     SPI_SETICONTITLEWRAP_IDX,
56     SPI_SETMENUDROPALIGNMENT_IDX,
57     SPI_SETDOUBLECLKWIDTH_IDX,
58     SPI_SETDOUBLECLKHEIGHT_IDX,
59     SPI_SETDOUBLECLICKTIME_IDX,
60     SPI_SETMOUSEBUTTONSWAP_IDX,
61     SPI_SETDRAGFULLWINDOWS_IDX,
62     SPI_SETWORKAREA_IDX,
63     SPI_SETSHOWSOUNDS_IDX,
64     SPI_SETKEYBOARDPREF_IDX,
65     SPI_SETSCREENREADER_IDX,
66     SPI_SETSCREENSAVERRUNNING_IDX,
67     SPI_SETFONTSMOOTHING_IDX,
68     SPI_SETLISTBOXSMOOTHSCROLLING_IDX,
69     SPI_SETMOUSEHOVERWIDTH_IDX,
70     SPI_SETMOUSEHOVERHEIGHT_IDX,
71     SPI_SETMOUSEHOVERTIME_IDX,
72     SPI_SETMOUSESCROLLLINES_IDX,
73     SPI_SETMENUSHOWDELAY_IDX,
74     SPI_SETICONTITLELOGFONT_IDX,
75     SPI_SETLOWPOWERACTIVE_IDX,
76     SPI_SETPOWEROFFACTIVE_IDX,
77     SPI_USERPREFERENCEMASK_IDX,
78     SPI_NONCLIENTMETRICS_IDX,
79     SPI_INDEX_COUNT
80 };
81
82 static const char * const DefSysColors[] =
83 {
84     "Scrollbar", "192 192 192",              /* COLOR_SCROLLBAR */
85     "Background", "0 128 128",               /* COLOR_BACKGROUND */
86     "ActiveTitle", "0 0 128",                /* COLOR_ACTIVECAPTION */
87     "InactiveTitle", "128 128 128",          /* COLOR_INACTIVECAPTION */
88     "Menu", "192 192 192",                   /* COLOR_MENU */
89     "Window", "255 255 255",                 /* COLOR_WINDOW */
90     "WindowFrame", "0 0 0",                  /* COLOR_WINDOWFRAME */
91     "MenuText", "0 0 0",                     /* COLOR_MENUTEXT */
92     "WindowText", "0 0 0",                   /* COLOR_WINDOWTEXT */
93     "TitleText", "255 255 255",              /* COLOR_CAPTIONTEXT */
94     "ActiveBorder", "192 192 192",           /* COLOR_ACTIVEBORDER */
95     "InactiveBorder", "192 192 192",         /* COLOR_INACTIVEBORDER */
96     "AppWorkSpace", "128 128 128",           /* COLOR_APPWORKSPACE */
97     "Hilight", "0 0 128",                    /* COLOR_HIGHLIGHT */
98     "HilightText", "255 255 255",            /* COLOR_HIGHLIGHTTEXT */
99     "ButtonFace", "192 192 192",             /* COLOR_BTNFACE */
100     "ButtonShadow", "128 128 128",           /* COLOR_BTNSHADOW */
101     "GrayText", "128 128 128",               /* COLOR_GRAYTEXT */
102     "ButtonText", "0 0 0",                   /* COLOR_BTNTEXT */
103     "InactiveTitleText", "192 192 192",      /* COLOR_INACTIVECAPTIONTEXT */
104     "ButtonHilight", "255 255 255",          /* COLOR_BTNHIGHLIGHT */
105     "ButtonDkShadow", "0 0 0",               /* COLOR_3DDKSHADOW */
106     "ButtonLight", "224 224 224",            /* COLOR_3DLIGHT */
107     "InfoText", "0 0 0",                     /* COLOR_INFOTEXT */
108     "InfoWindow", "255 255 225",             /* COLOR_INFOBK */
109     "ButtonAlternateFace", "180 180 180",    /* COLOR_ALTERNATEBTNFACE */
110     "HotTrackingColor", "0 0 255",           /* COLOR_HOTLIGHT */
111     "GradientActiveTitle", "16 132 208",     /* COLOR_GRADIENTACTIVECAPTION */
112     "GradientInactiveTitle", "181 181 181",  /* COLOR_GRADIENTINACTIVECAPTION */
113     "MenuHilight", "0 0 0",                  /* COLOR_MENUHILIGHT */
114     "MenuBar", "192 192 192"                 /* COLOR_MENUBAR */
115 };
116
117 /**
118  * Names of the registry subkeys of HKEY_CURRENT_USER key and value names
119  * for the system parameters.
120  * Names of the keys are created by adding string "_REGKEY" to
121  * "SET" action names, value names are created by adding "_REG_NAME"
122  * to the "SET" action name.
123  */
124 static const WCHAR SPI_SETBEEP_REGKEY[]=                      {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','S','o','u','n','d',0};
125 static const WCHAR SPI_SETBEEP_VALNAME[]=                     {'B','e','e','p',0};
126 static const WCHAR SPI_SETMOUSE_REGKEY[]=                     {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','M','o','u','s','e',0};
127 static const WCHAR SPI_SETMOUSE_VALNAME1[]=                   {'M','o','u','s','e','T','h','r','e','s','h','o','l','d','1',0};
128 static const WCHAR SPI_SETMOUSE_VALNAME2[]=                   {'M','o','u','s','e','T','h','r','e','s','h','o','l','d','2',0};
129 static const WCHAR SPI_SETMOUSE_VALNAME3[]=                   {'M','o','u','s','e','S','p','e','e','d',0};
130 static const WCHAR SPI_SETBORDER_REGKEY[]=                    {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','D','e','s','k','t','o','p','\\',
131                                                                'W','i','n','d','o','w','M','e','t','r','i','c','s',0};
132 static const WCHAR SPI_SETBORDER_VALNAME[]=                   {'B','o','r','d','e','r','W','i','d','t','h',0};
133 static const WCHAR SPI_SETKEYBOARDSPEED_REGKEY[]=             {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','K','e','y','b','o','a','r','d',0};
134 static const WCHAR SPI_SETKEYBOARDSPEED_VALNAME[]=            {'K','e','y','b','o','a','r','d','S','p','e','e','d',0};
135 static const WCHAR SPI_ICONHORIZONTALSPACING_REGKEY[]=        {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','D','e','s','k','t','o','p','\\',
136                                                                'W','i','n','d','o','w','M','e','t','r','i','c','s',0};
137 static const WCHAR SPI_ICONHORIZONTALSPACING_VALNAME[]=       {'I','c','o','n','S','p','a','c','i','n','g',0};
138 static const WCHAR SPI_SETSCREENSAVETIMEOUT_REGKEY[]=         {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','D','e','s','k','t','o','p',0};
139 static const WCHAR SPI_SETSCREENSAVETIMEOUT_VALNAME[]=        {'S','c','r','e','e','n','S','a','v','e','T','i','m','e','O','u','t',0};
140 static const WCHAR SPI_SETSCREENSAVEACTIVE_REGKEY[]=          {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','D','e','s','k','t','o','p',0};
141 static const WCHAR SPI_SETSCREENSAVEACTIVE_VALNAME[]=         {'S','c','r','e','e','n','S','a','v','e','A','c','t','i','v','e',0};
142 static const WCHAR SPI_SETGRIDGRANULARITY_REGKEY[]=           {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','D','e','s','k','t','o','p',0};
143 static const WCHAR SPI_SETGRIDGRANULARITY_VALNAME[]=          {'G','r','i','d','G','r','a','n','u','l','a','r','i','t','y',0};
144 static const WCHAR SPI_SETKEYBOARDDELAY_REGKEY[]=             {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','K','e','y','b','o','a','r','d',0};
145 static const WCHAR SPI_SETKEYBOARDDELAY_VALNAME[]=            {'K','e','y','b','o','a','r','d','D','e','l','a','y',0};
146 static const WCHAR SPI_ICONVERTICALSPACING_REGKEY[]=          {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','D','e','s','k','t','o','p','\\',
147                                                                'W','i','n','d','o','w','M','e','t','r','i','c','s',0};
148 static const WCHAR SPI_ICONVERTICALSPACING_VALNAME[]=         {'I','c','o','n','V','e','r','t','i','c','a','l','S','p','a','c','i','n','g',0};
149 static const WCHAR SPI_SETICONTITLEWRAP_REGKEY1[]=            {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','D','e','s','k','t','o','p','\\',
150                                                                'W','i','n','d','o','w','M','e','t','r','i','c','s',0};
151 static const WCHAR SPI_SETICONTITLEWRAP_REGKEY2[]=            {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','D','e','s','k','t','o','p',0};
152 static const WCHAR SPI_SETICONTITLEWRAP_VALNAME[]=            {'I','c','o','n','T','i','t','l','e','W','r','a','p',0};
153 static const WCHAR SPI_SETICONTITLELOGFONT_REGKEY[]=          {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','D','e','s','k','t','o','p','\\',
154                                                                'W','i','n','d','o','w','M','e','t','r','i','c','s',0};
155 static const WCHAR SPI_SETICONTITLELOGFONT_VALNAME[]=         {'I','c','o','n','F','o','n','t',0};
156 static const WCHAR SPI_SETMENUDROPALIGNMENT_REGKEY1[]=        {'S','o','f','t','w','a','r','e','\\',
157                                                                'M','i','c','r','o','s','o','f','t','\\',
158                                                                'W','i','n','d','o','w','s',' ','N','T','\\',
159                                                                'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
160                                                                'W','i','n','d','o','w','s',0};
161 static const WCHAR SPI_SETMENUDROPALIGNMENT_REGKEY2[]=        {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','D','e','s','k','t','o','p',0};
162 static const WCHAR SPI_SETMENUDROPALIGNMENT_VALNAME[]=        {'M','e','n','u','D','r','o','p','A','l','i','g','n','m','e','n','t',0};
163 static const WCHAR SPI_SETDOUBLECLKWIDTH_REGKEY1[]=           {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','M','o','u','s','e',0};
164 static const WCHAR SPI_SETDOUBLECLKWIDTH_REGKEY2[]=           {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','D','e','s','k','t','o','p',0};
165 static const WCHAR SPI_SETDOUBLECLKWIDTH_VALNAME[]=           {'D','o','u','b','l','e','C','l','i','c','k','W','i','d','t','h',0};
166 static const WCHAR SPI_SETDOUBLECLKHEIGHT_REGKEY1[]=          {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','M','o','u','s','e',0};
167 static const WCHAR SPI_SETDOUBLECLKHEIGHT_REGKEY2[]=          {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','D','e','s','k','t','o','p',0};
168 static const WCHAR SPI_SETDOUBLECLKHEIGHT_VALNAME[]=          {'D','o','u','b','l','e','C','l','i','c','k','H','e','i','g','h','t',0};
169 static const WCHAR SPI_SETDOUBLECLICKTIME_REGKEY[]=           {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','M','o','u','s','e',0};
170 static const WCHAR SPI_SETDOUBLECLICKTIME_VALNAME[]=          {'D','o','u','b','l','e','C','l','i','c','k','S','p','e','e','d',0};
171 static const WCHAR SPI_SETMOUSEBUTTONSWAP_REGKEY[]=           {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','M','o','u','s','e',0};
172 static const WCHAR SPI_SETMOUSEBUTTONSWAP_VALNAME[]=          {'S','w','a','p','M','o','u','s','e','B','u','t','t','o','n','s',0};
173 static const WCHAR SPI_SETDRAGFULLWINDOWS_REGKEY[]=           {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','D','e','s','k','t','o','p',0};
174 static const WCHAR SPI_SETDRAGFULLWINDOWS_VALNAME[]=          {'D','r','a','g','F','u','l','l','W','i','n','d','o','w','s',0};
175 static const WCHAR SPI_SETSHOWSOUNDS_REGKEY[]=                {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\',
176                                                                'A','c','c','e','s','s','i','b','i','l','i','t','y','\\',
177                                                                'S','h','o','w','S','o','u','n','d','s',0};
178 static const WCHAR SPI_SETSHOWSOUNDS_VALNAME[]=               {'O','n',0};
179 static const WCHAR SPI_SETKEYBOARDPREF_REGKEY[]=              {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\',
180                                                                'A','c','c','e','s','s','i','b','i','l','i','t','y','\\',
181                                                                'K','e','y','b','o','a','r','d',' ','P','r','e','f','e','r','e','n','c','e',0};
182 static const WCHAR SPI_SETKEYBOARDPREF_VALNAME[]=             {'O','n',0};
183 static const WCHAR SPI_SETSCREENREADER_REGKEY[]=              {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\',
184                                                                'A','c','c','e','s','s','i','b','i','l','i','t','y','\\',
185                                                                'B','l','i','n','d',' ','A','c','c','e','s','s',0};
186 static const WCHAR SPI_SETSCREENREADER_VALNAME[]=             {'O','n',0};
187 static const WCHAR SPI_SETDESKWALLPAPER_REGKEY[]=             {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','D','e','s','k','t','o','p',0};
188 static const WCHAR SPI_SETDESKWALLPAPER_VALNAME[]=            {'W','a','l','l','p','a','p','e','r',0};
189 static const WCHAR SPI_SETFONTSMOOTHING_REGKEY[]=             {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','D','e','s','k','t','o','p',0};
190 static const WCHAR SPI_SETFONTSMOOTHING_VALNAME[]=            {'F','o','n','t','S','m','o','o','t','h','i','n','g',0};
191 static const WCHAR SPI_SETLOWPOWERACTIVE_REGKEY[]=            {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','D','e','s','k','t','o','p',0};
192 static const WCHAR SPI_SETLOWPOWERACTIVE_VALNAME[]=           {'L','o','w','P','o','w','e','r','A','c','t','i','v','e',0};
193 static const WCHAR SPI_SETPOWEROFFACTIVE_REGKEY[]=            {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','D','e','s','k','t','o','p',0};
194 static const WCHAR SPI_SETPOWEROFFACTIVE_VALNAME[]=           {'P','o','w','e','r','O','f','f','A','c','t','i','v','e',0};
195 static const WCHAR SPI_USERPREFERENCEMASK_REGKEY[]=           {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','D','e','s','k','t','o','p',0};
196 static const WCHAR SPI_USERPREFERENCEMASK_VALNAME[]=          {'U','s','e','r','P','r','e','f','e','r','e','n','c','e','m','a','s','k',0};
197 static const WCHAR SPI_SETLISTBOXSMOOTHSCROLLING_REGKEY[]=    {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','D','e','s','k','t','o','p',0};
198 static const WCHAR SPI_SETLISTBOXSMOOTHSCROLLING_VALNAME[]=   {'S','m','o','o','t','h','S','c','r','o','l','l',0};
199 static const WCHAR SPI_SETMOUSEHOVERWIDTH_REGKEY[]=           {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','M','o','u','s','e',0};
200 static const WCHAR SPI_SETMOUSEHOVERWIDTH_VALNAME[]=          {'M','o','u','s','e','H','o','v','e','r','W','i','d','t','h',0};
201 static const WCHAR SPI_SETMOUSEHOVERHEIGHT_REGKEY[]=          {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','M','o','u','s','e',0};
202 static const WCHAR SPI_SETMOUSEHOVERHEIGHT_VALNAME[]=         {'M','o','u','s','e','H','o','v','e','r','H','e','i','g','h','t',0};
203 static const WCHAR SPI_SETMOUSEHOVERTIME_REGKEY[]=            {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','M','o','u','s','e',0};
204 static const WCHAR SPI_SETMOUSEHOVERTIME_VALNAME[]=           {'M','o','u','s','e','H','o','v','e','r','T','i','m','e',0};
205 static const WCHAR SPI_SETMOUSESCROLLLINES_REGKEY[]=          {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','D','e','s','k','t','o','p',0};
206 static const WCHAR SPI_SETMOUSESCROLLLINES_VALNAME[]=         {'W','h','e','e','l','S','c','r','o','l','l','L','i','n','e','s',0};
207 static const WCHAR SPI_SETMENUSHOWDELAY_REGKEY[]=             {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','D','e','s','k','t','o','p',0};
208 static const WCHAR SPI_SETMENUSHOWDELAY_VALNAME[]=            {'M','e','n','u','S','h','o','w','D','e','l','a','y',0};
209
210 /* FIXME - real values */
211 static const WCHAR SPI_SETSCREENSAVERRUNNING_REGKEY[]=   {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','D','e','s','k','t','o','p',0};
212 static const WCHAR SPI_SETSCREENSAVERRUNNING_VALNAME[]=  {'W','I','N','E','_','S','c','r','e','e','n','S','a','v','e','r','R','u','n','n','i','n','g',0};
213
214 static const WCHAR METRICS_REGKEY[]=                  {'C','o','n','t','r','o','l',' ','P','a','n','e','l','\\','D','e','s','k','t','o','p','\\',
215                                                        'W','i','n','d','o','w','M','e','t','r','i','c','s',0};
216 static const WCHAR METRICS_SCROLLWIDTH_VALNAME[]=     {'S','c','r','o','l','l','W','i','d','t','h',0};
217 static const WCHAR METRICS_SCROLLHEIGHT_VALNAME[]=    {'S','c','r','o','l','l','H','e','i','g','h','t',0};
218 static const WCHAR METRICS_CAPTIONWIDTH_VALNAME[]=    {'C','a','p','t','i','o','n','W','i','d','t','h',0};
219 static const WCHAR METRICS_CAPTIONHEIGHT_VALNAME[]=   {'C','a','p','t','i','o','n','H','e','i','g','h','t',0};
220 static const WCHAR METRICS_SMCAPTIONWIDTH_VALNAME[]=  {'S','m','C','a','p','t','i','o','n','W','i','d','t','h',0};
221 static const WCHAR METRICS_SMCAPTIONHEIGHT_VALNAME[]= {'S','m','C','a','p','t','i','o','n','H','e','i','g','h','t',0};
222 static const WCHAR METRICS_MENUWIDTH_VALNAME[]=       {'M','e','n','u','W','i','d','t','h',0};
223 static const WCHAR METRICS_MENUHEIGHT_VALNAME[]=      {'M','e','n','u','H','e','i','g','h','t',0};
224 static const WCHAR METRICS_ICONSIZE_VALNAME[]=        {'S','h','e','l','l',' ','I','c','o','n',' ','S','i','z','e',0};
225 static const WCHAR METRICS_BORDERWIDTH_VALNAME[]=     {'B','o','r','d','e','r','W','i','d','t','h',0};
226 static const WCHAR METRICS_CAPTIONLOGFONT_VALNAME[]=  {'C','a','p','t','i','o','n','F','o','n','t',0};
227 static const WCHAR METRICS_SMCAPTIONLOGFONT_VALNAME[]={'S','m','C','a','p','t','i','o','n','F','o','n','t',0};
228 static const WCHAR METRICS_MENULOGFONT_VALNAME[]=     {'M','e','n','u','F','o','n','t',0};
229 static const WCHAR METRICS_MESSAGELOGFONT_VALNAME[]=  {'M','e','s','s','a','g','e','F','o','n','t',0};
230 static const WCHAR METRICS_STATUSLOGFONT_VALNAME[]=   {'S','t','a','t','u','s','F','o','n','t',0};
231
232 /* volatile registry branch under CURRENT_USER_REGKEY for temporary values storage */
233 static const WCHAR WINE_CURRENT_USER_REGKEY[] = {'S','o','f','t','w','a','r','e','\\',
234                                                  'W','i','n','e','\\',
235                                                  'T','e','m','p','o','r','a','r','y',' ',
236                                                  'S','y','s','t','e','m',' ',
237                                                  'P','a','r','a','m','e','t','e','r','s',0};
238
239
240 static const WCHAR Yes[]=                                    {'Y','e','s',0};
241 static const WCHAR No[]=                                     {'N','o',0};
242 static const WCHAR Desktop[]=                                {'D','e','s','k','t','o','p',0};
243 static const WCHAR Pattern[]=                                {'P','a','t','t','e','r','n',0};
244 static const WCHAR MenuFont[]=                               {'M','e','n','u','F','o','n','t',0};
245 static const WCHAR MenuFontSize[]=                           {'M','e','n','u','F','o','n','t','S','i','z','e',0};
246 static const WCHAR StatusFont[]=                             {'S','t','a','t','u','s','F','o','n','t',0};
247 static const WCHAR StatusFontSize[]=                         {'S','t','a','t','u','s','F','o','n','t','S','i','z','e',0};
248 static const WCHAR MessageFont[]=                            {'M','e','s','s','a','g','e','F','o','n','t',0};
249 static const WCHAR MessageFontSize[]=                        {'M','e','s','s','a','g','e','F','o','n','t','S','i','z','e',0};
250 static const WCHAR System[]=                                 {'S','y','s','t','e','m',0};
251 static const WCHAR IconTitleSize[]=                          {'I','c','o','n','T','i','t','l','e','S','i','z','e',0};
252 static const WCHAR IconTitleFaceName[]=                      {'I','c','o','n','T','i','t','l','e','F','a','c','e','N','a','m','e',0};
253 static const WCHAR defPattern[]=                             {'1','7','0',' ','8','5',' ','1','7','0',' ','8','5',' ','1','7','0',' ','8','5',
254                                                               ' ','1','7','0',' ','8','5',0};
255 static const WCHAR CSu[]=                                    {'%','u',0};
256 static const WCHAR CSd[]=                                    {'%','d',0};
257
258 /* Indicators whether system parameter value is loaded */
259 static char spi_loaded[SPI_INDEX_COUNT];
260
261 static BOOL notify_change = TRUE;
262
263 /* System parameters storage */
264 static BOOL beep_active = TRUE;
265 static int mouse_threshold1 = 6;
266 static int mouse_threshold2 = 10;
267 static int mouse_speed = 1;
268 static UINT border = 1;
269 static UINT keyboard_speed = 31;
270 static UINT screensave_timeout = 300;
271 static UINT grid_granularity = 0;
272 static UINT keyboard_delay = 1;
273 static UINT double_click_width = 4;
274 static UINT double_click_height = 4;
275 static UINT double_click_time = 500;
276 static BOOL drag_full_windows = FALSE;
277 static RECT work_area;
278 static BOOL keyboard_pref = TRUE;
279 static BOOL screen_reader = FALSE;
280 static UINT mouse_hover_width = 4;
281 static UINT mouse_hover_height = 4;
282 static UINT mouse_hover_time = 400;
283 static UINT mouse_scroll_lines = 3;
284 static UINT menu_show_delay = 400;
285 static UINT menu_drop_alignment = 0;
286 static BOOL screensaver_running = FALSE;
287 static UINT font_smoothing = 0;  /* 0x01 for 95/98/NT, 0x02 for 98/ME/2k/XP */
288 static BOOL lowpoweractive = FALSE;
289 static BOOL poweroffactive = FALSE;
290 static BOOL show_sounds = FALSE;
291 static BOOL swap_buttons = FALSE;
292 static BOOL listbox_smoothscrolling = FALSE;
293 static BYTE user_prefs[4];
294
295 static MINIMIZEDMETRICS minimized_metrics =
296 {
297     sizeof(MINIMIZEDMETRICS),
298     154,      /* iWidth */
299     0,        /* iHorzGap */
300     0,        /* iVertGap */
301     ARW_HIDE  /* iArrange */
302 };
303
304 static ICONMETRICSW icon_metrics =
305 {
306     sizeof(ICONMETRICSW),
307     75,   /* iHorzSpacing */
308     75,   /* iVertSpacing */
309     TRUE, /* iTitleWrap */
310     { -11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
311       OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH }   /* lfFont */
312 };
313
314 static NONCLIENTMETRICSW nonclient_metrics =
315 {
316     sizeof(NONCLIENTMETRICSW),
317     1,     /* iBorderWidth */
318     16,    /* iScrollWidth */
319     16,    /* iScrollHeight */
320     18,    /* iCaptionWidth */
321     18,    /* iCaptionHeight */
322     { 0 }, /* lfCaptionFont */
323     13,    /* iSmCaptionWidth */
324     15,    /* iSmCaptionHeight */
325     { 0 }, /* lfSmCaptionFont */
326     18,    /* iMenuWidth */
327     18,    /* iMenuHeight */
328     { 0 }, /* lfMenuFont */
329     { 0 }, /* lfStatusFont */
330     { 0 }  /* lfMessageFont */
331 };
332
333 static SIZE icon_size = { 32, 32 };
334 static SIZE scroll_height = { 16, 16 };
335
336 #define NUM_SYS_COLORS     (COLOR_MENUBAR+1)
337
338 static COLORREF SysColors[NUM_SYS_COLORS];
339 static HBRUSH SysColorBrushes[NUM_SYS_COLORS];
340 static HPEN   SysColorPens[NUM_SYS_COLORS];
341
342 static const WORD wPattern55AA[] = { 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa };
343
344 HBRUSH SYSCOLOR_55AABrush = 0;
345
346 extern void __wine_make_gdi_object_system( HGDIOBJ handle, BOOL set );
347
348
349 /* This function is a copy of the one in objects/font.c */
350 static void SYSPARAMS_LogFont32ATo16( const LOGFONTA* font32, LPLOGFONT16 font16 )
351 {
352     font16->lfHeight = font32->lfHeight;
353     font16->lfWidth = font32->lfWidth;
354     font16->lfEscapement = font32->lfEscapement;
355     font16->lfOrientation = font32->lfOrientation;
356     font16->lfWeight = font32->lfWeight;
357     font16->lfItalic = font32->lfItalic;
358     font16->lfUnderline = font32->lfUnderline;
359     font16->lfStrikeOut = font32->lfStrikeOut;
360     font16->lfCharSet = font32->lfCharSet;
361     font16->lfOutPrecision = font32->lfOutPrecision;
362     font16->lfClipPrecision = font32->lfClipPrecision;
363     font16->lfQuality = font32->lfQuality;
364     font16->lfPitchAndFamily = font32->lfPitchAndFamily;
365     lstrcpynA( font16->lfFaceName, font32->lfFaceName, LF_FACESIZE );
366 }
367
368 static void SYSPARAMS_LogFont16To32W( const LOGFONT16 *font16, LPLOGFONTW font32 )
369 {
370     font32->lfHeight = font16->lfHeight;
371     font32->lfWidth = font16->lfWidth;
372     font32->lfEscapement = font16->lfEscapement;
373     font32->lfOrientation = font16->lfOrientation;
374     font32->lfWeight = font16->lfWeight;
375     font32->lfItalic = font16->lfItalic;
376     font32->lfUnderline = font16->lfUnderline;
377     font32->lfStrikeOut = font16->lfStrikeOut;
378     font32->lfCharSet = font16->lfCharSet;
379     font32->lfOutPrecision = font16->lfOutPrecision;
380     font32->lfClipPrecision = font16->lfClipPrecision;
381     font32->lfQuality = font16->lfQuality;
382     font32->lfPitchAndFamily = font16->lfPitchAndFamily;
383     MultiByteToWideChar( CP_ACP, 0, font16->lfFaceName, -1, font32->lfFaceName, LF_FACESIZE );
384     font32->lfFaceName[LF_FACESIZE-1] = 0;
385 }
386
387 static void SYSPARAMS_LogFont32WTo32A( const LOGFONTW* font32W, LPLOGFONTA font32A )
388 {
389     font32A->lfHeight = font32W->lfHeight;
390     font32A->lfWidth = font32W->lfWidth;
391     font32A->lfEscapement = font32W->lfEscapement;
392     font32A->lfOrientation = font32W->lfOrientation;
393     font32A->lfWeight = font32W->lfWeight;
394     font32A->lfItalic = font32W->lfItalic;
395     font32A->lfUnderline = font32W->lfUnderline;
396     font32A->lfStrikeOut = font32W->lfStrikeOut;
397     font32A->lfCharSet = font32W->lfCharSet;
398     font32A->lfOutPrecision = font32W->lfOutPrecision;
399     font32A->lfClipPrecision = font32W->lfClipPrecision;
400     font32A->lfQuality = font32W->lfQuality;
401     font32A->lfPitchAndFamily = font32W->lfPitchAndFamily;
402     WideCharToMultiByte( CP_ACP, 0, font32W->lfFaceName, -1, font32A->lfFaceName, LF_FACESIZE, NULL, NULL );
403     font32A->lfFaceName[LF_FACESIZE-1] = 0;
404 }
405
406 static void SYSPARAMS_NonClientMetrics32ATo16( const NONCLIENTMETRICSA* lpnm32, LPNONCLIENTMETRICS16 lpnm16 )
407 {
408     lpnm16->iBorderWidth        = lpnm32->iBorderWidth;
409     lpnm16->iScrollWidth        = lpnm32->iScrollWidth;
410     lpnm16->iScrollHeight       = lpnm32->iScrollHeight;
411     lpnm16->iCaptionWidth       = lpnm32->iCaptionWidth;
412     lpnm16->iCaptionHeight      = lpnm32->iCaptionHeight;
413     SYSPARAMS_LogFont32ATo16( &lpnm32->lfCaptionFont,   &lpnm16->lfCaptionFont );
414     lpnm16->iSmCaptionWidth     = lpnm32->iSmCaptionWidth;
415     lpnm16->iSmCaptionHeight    = lpnm32->iSmCaptionHeight;
416     SYSPARAMS_LogFont32ATo16( &lpnm32->lfSmCaptionFont, &lpnm16->lfSmCaptionFont );
417     lpnm16->iMenuWidth          = lpnm32->iMenuWidth;
418     lpnm16->iMenuHeight         = lpnm32->iMenuHeight;
419     SYSPARAMS_LogFont32ATo16( &lpnm32->lfMenuFont,      &lpnm16->lfMenuFont );
420     SYSPARAMS_LogFont32ATo16( &lpnm32->lfStatusFont,    &lpnm16->lfStatusFont );
421     SYSPARAMS_LogFont32ATo16( &lpnm32->lfMessageFont,   &lpnm16->lfMessageFont );
422 }
423
424 static void SYSPARAMS_NonClientMetrics32WTo32A( const NONCLIENTMETRICSW* lpnm32W, LPNONCLIENTMETRICSA lpnm32A )
425 {
426     lpnm32A->iBorderWidth       = lpnm32W->iBorderWidth;
427     lpnm32A->iScrollWidth       = lpnm32W->iScrollWidth;
428     lpnm32A->iScrollHeight      = lpnm32W->iScrollHeight;
429     lpnm32A->iCaptionWidth      = lpnm32W->iCaptionWidth;
430     lpnm32A->iCaptionHeight     = lpnm32W->iCaptionHeight;
431     SYSPARAMS_LogFont32WTo32A(  &lpnm32W->lfCaptionFont,        &lpnm32A->lfCaptionFont );
432     lpnm32A->iSmCaptionWidth    = lpnm32W->iSmCaptionWidth;
433     lpnm32A->iSmCaptionHeight   = lpnm32W->iSmCaptionHeight;
434     SYSPARAMS_LogFont32WTo32A( &lpnm32W->lfSmCaptionFont,       &lpnm32A->lfSmCaptionFont );
435     lpnm32A->iMenuWidth         = lpnm32W->iMenuWidth;
436     lpnm32A->iMenuHeight        = lpnm32W->iMenuHeight;
437     SYSPARAMS_LogFont32WTo32A( &lpnm32W->lfMenuFont,            &lpnm32A->lfMenuFont );
438     SYSPARAMS_LogFont32WTo32A( &lpnm32W->lfStatusFont,          &lpnm32A->lfStatusFont );
439     SYSPARAMS_LogFont32WTo32A( &lpnm32W->lfMessageFont,         &lpnm32A->lfMessageFont );
440 }
441
442
443 /***********************************************************************
444  *           get_volatile_regkey
445  *
446  * Return a handle to the volatile registry key used to store
447  * non-permanently modified parameters.
448  */
449 static HKEY get_volatile_regkey(void)
450 {
451     static HKEY volatile_key;
452
453     if (!volatile_key)
454     {
455         /* @@ Wine registry key: HKCU\Software\Wine\Temporary System Parameters */
456         if (RegCreateKeyExW( HKEY_CURRENT_USER, WINE_CURRENT_USER_REGKEY,
457                              0, 0, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, 0,
458                              &volatile_key, 0 ) != ERROR_SUCCESS)
459             ERR("Can't create wine configuration registry branch\n");
460     }
461     return volatile_key;
462 }
463
464 /***********************************************************************
465  *           SYSPARAMS_NotifyChange
466  *
467  * Sends notification about system parameter update.
468  */
469 static void SYSPARAMS_NotifyChange( UINT uiAction, UINT fWinIni )
470 {
471     static const WCHAR emptyW[1];
472
473     if (notify_change)
474     {
475         if (fWinIni & SPIF_UPDATEINIFILE)
476         {
477             if (fWinIni & (SPIF_SENDWININICHANGE | SPIF_SENDCHANGE))
478                 SendMessageTimeoutW(HWND_BROADCAST, WM_SETTINGCHANGE,
479                                     uiAction, (LPARAM) emptyW,
480                                     SMTO_ABORTIFHUNG, 2000, NULL );
481         }
482         else
483         {
484             /* FIXME notify other wine processes with internal message */
485         }
486     }
487 }
488
489
490 /***********************************************************************
491  * Loads system parameter from user profile.
492  */
493 static BOOL SYSPARAMS_LoadRaw( LPCWSTR lpRegKey, LPCWSTR lpValName, LPBYTE lpBuf, DWORD count )
494 {
495     BOOL ret = FALSE;
496     DWORD type;
497     HKEY hKey;
498
499     memset( lpBuf, 0, count );
500     if ((RegOpenKeyW( get_volatile_regkey(), lpRegKey, &hKey ) == ERROR_SUCCESS) ||
501         (RegOpenKeyW( HKEY_CURRENT_USER, lpRegKey, &hKey ) == ERROR_SUCCESS))
502     {
503         ret = !RegQueryValueExW( hKey, lpValName, NULL, &type, (LPBYTE)lpBuf, &count);
504         RegCloseKey( hKey );
505     }
506     return ret;
507 }
508
509 static BOOL SYSPARAMS_Load( LPCWSTR lpRegKey, LPCWSTR lpValName, LPWSTR lpBuf, DWORD count )
510 {
511   return SYSPARAMS_LoadRaw( lpRegKey, lpValName, (LPBYTE)lpBuf, count );
512 }
513
514 /***********************************************************************
515  * Saves system parameter to user profile.
516  */
517
518 /* Save data as-is */
519 static BOOL SYSPARAMS_SaveRaw( LPCWSTR lpRegKey, LPCWSTR lpValName, 
520                                const BYTE* lpValue, DWORD valueSize, 
521                                DWORD type, UINT fWinIni )
522 {
523     HKEY hKey;
524     HKEY hBaseKey;
525     DWORD dwOptions;
526     BOOL ret = FALSE;
527
528     if (fWinIni & SPIF_UPDATEINIFILE)
529     {
530         hBaseKey = HKEY_CURRENT_USER;
531         dwOptions = 0;
532     }
533     else
534     {
535         hBaseKey = get_volatile_regkey();
536         dwOptions = REG_OPTION_VOLATILE;
537     }
538
539     if (RegCreateKeyExW( hBaseKey, lpRegKey,
540                          0, 0, dwOptions, KEY_ALL_ACCESS,
541                          0, &hKey, 0 ) == ERROR_SUCCESS)
542     {
543         if (RegSetValueExW( hKey, lpValName, 0, type,
544                             lpValue, valueSize) == ERROR_SUCCESS)
545         {
546             ret = TRUE;
547             if (hBaseKey == HKEY_CURRENT_USER)
548                 RegDeleteKeyW( get_volatile_regkey(), lpRegKey );
549         }
550         RegCloseKey( hKey );
551     }
552     return ret;
553 }
554
555 /* Convenience function to save strings */
556 static BOOL SYSPARAMS_Save( LPCWSTR lpRegKey, LPCWSTR lpValName, LPCWSTR lpValue,
557                             UINT fWinIni )
558 {
559     return SYSPARAMS_SaveRaw( lpRegKey, lpValName, (const BYTE*)lpValue, 
560         (strlenW(lpValue) + 1)*sizeof(WCHAR), REG_SZ, fWinIni );
561 }
562
563
564 static inline HDC get_display_dc(void)
565 {
566     static const WCHAR DISPLAY[] = {'D','I','S','P','L','A','Y',0};
567     static HDC display_dc;
568     if (!display_dc) display_dc = CreateICW( DISPLAY, NULL, NULL, NULL );
569     return display_dc;
570 }
571
572 static inline int get_display_dpi(void)
573 {
574     static int display_dpi;
575     if (!display_dpi) display_dpi = GetDeviceCaps( get_display_dc(), LOGPIXELSY );
576     return display_dpi;
577 }
578
579 /***********************************************************************
580  * SYSPARAMS_Twips2Pixels
581  *
582  * Convert a dimension value that was obtained from the registry.  These are
583  * quoted as being "twips" values if negative and pixels if positive.
584  * One inch is 1440 twips. So to convert, divide by 1440 to get inches and
585  * multiply that by the dots-per-inch to get the size in pixels. 
586  * See for example
587  *   MSDN Library - April 2001 -> Resource Kits ->
588  *       Windows 2000 Resource Kit Reference ->
589  *       Technical Reference to the Windows 2000 Registry ->
590  *       HKEY_CURRENT_USER -> Control Panel -> Desktop -> WindowMetrics
591  */
592 inline static int SYSPARAMS_Twips2Pixels(int x)
593 {
594     if (x < 0)
595         x = (-x * get_display_dpi() + 720) / 1440;
596     return x;
597 }
598
599 /***********************************************************************
600  * get_reg_metric
601  *
602  * Get a registry entry from the already open key.  This allows us to open the
603  * section once and read several values.
604  *
605  * Of course this function belongs somewhere more usable but here will do
606  * for now.
607  */
608 static int get_reg_metric( HKEY hkey, LPCWSTR lpValName, int default_value )
609 {
610     int value = default_value;
611     if (hkey)
612     {
613         WCHAR buffer[128];
614         DWORD type, count = sizeof(buffer);
615         if(!RegQueryValueExW( hkey, lpValName, NULL, &type, (LPBYTE)buffer, &count) )
616         {
617             if (type != REG_SZ)
618             {
619                 /* Are there any utilities for converting registry entries
620                  * between formats?
621                  */
622                 /* FIXME_(reg)("We need reg format converter\n"); */
623             }
624             else
625                 value = atoiW(buffer);
626         }
627     }
628     return SYSPARAMS_Twips2Pixels(value);
629 }
630
631
632 /*************************************************************************
633  *             SYSPARAMS_SetSysColor
634  */
635 static void SYSPARAMS_SetSysColor( int index, COLORREF color )
636 {
637     if (index < 0 || index >= NUM_SYS_COLORS) return;
638     SysColors[index] = color;
639     if (SysColorBrushes[index])
640     {
641         __wine_make_gdi_object_system( SysColorBrushes[index], FALSE);
642         DeleteObject( SysColorBrushes[index] );
643     }
644     SysColorBrushes[index] = CreateSolidBrush( color );
645     __wine_make_gdi_object_system( SysColorBrushes[index], TRUE);
646
647     if (SysColorPens[index])
648     {
649         __wine_make_gdi_object_system( SysColorPens[index], FALSE);
650         DeleteObject( SysColorPens[index] );
651     }
652     SysColorPens[index] = CreatePen( PS_SOLID, 1, color );
653     __wine_make_gdi_object_system( SysColorPens[index], TRUE);
654 }
655
656 /* load a uint parameter from the registry */
657 static BOOL get_uint_param( unsigned int idx, LPCWSTR regkey, LPCWSTR value,
658                             UINT *value_ptr, UINT *ret_ptr )
659 {
660     if (!ret_ptr) return FALSE;
661     if (!spi_loaded[idx])
662     {
663         WCHAR buf[10];
664
665         if (SYSPARAMS_Load( regkey, value, buf, sizeof(buf) )) *value_ptr = atoiW( buf );
666         spi_loaded[idx] = TRUE;
667     }
668     *ret_ptr = *value_ptr;
669     return TRUE;
670 }
671
672 /* load a twips parameter from the registry */
673 static BOOL get_twips_param( unsigned int idx, LPCWSTR regkey, LPCWSTR value,
674                              UINT *value_ptr, UINT *ret_ptr )
675 {
676     if (!ret_ptr) return FALSE;
677     if (!spi_loaded[idx])
678     {
679         WCHAR buf[10];
680
681         if (SYSPARAMS_Load( regkey, value, buf, sizeof(buf) ))
682             *value_ptr = SYSPARAMS_Twips2Pixels( atoiW(buf) );
683         spi_loaded[idx] = TRUE;
684     }
685     *ret_ptr = *value_ptr;
686     return TRUE;
687 }
688
689 /* load a boolean parameter from the registry */
690 static inline BOOL get_bool_param( unsigned int idx, LPCWSTR regkey, LPCWSTR value,
691                                    BOOL *value_ptr, BOOL *ret_ptr )
692 {
693     return get_uint_param( idx, regkey, value, (UINT *)value_ptr, (UINT *)ret_ptr );
694 }
695
696 /* set a uint parameter that is mirrored in two different registry locations */
697 static BOOL set_uint_param_mirrored( unsigned int idx, LPCWSTR regkey, LPCWSTR regkey_mirror,
698                                      LPCWSTR value, UINT *value_ptr, UINT new_val, UINT fWinIni )
699 {
700     WCHAR buf[10];
701
702     wsprintfW(buf, CSu, new_val);
703     if (!SYSPARAMS_Save( regkey, value, buf, fWinIni )) return FALSE;
704     if (regkey_mirror) SYSPARAMS_Save( regkey_mirror, value, buf, fWinIni );
705     *value_ptr = new_val;
706     spi_loaded[idx] = TRUE;
707     return TRUE;
708 }
709
710 /* set a uint parameter in the registry */
711 static inline BOOL set_uint_param( unsigned int idx, LPCWSTR regkey, LPCWSTR value,
712                                    UINT *value_ptr, UINT new_val, UINT fWinIni )
713 {
714     return set_uint_param_mirrored( idx, regkey, NULL, value, value_ptr, new_val, fWinIni );
715 }
716
717 /* set a boolean parameter that is mirrored in two different registry locations */
718 static inline BOOL set_bool_param_mirrored( unsigned int idx, LPCWSTR regkey, LPCWSTR regkey_mirror,
719                                             LPCWSTR value, BOOL *value_ptr, BOOL new_val, UINT fWinIni )
720 {
721     return set_uint_param_mirrored( idx, regkey, regkey_mirror, value,
722                                     (UINT *)value_ptr, new_val, fWinIni );
723 }
724
725 /* set a boolean parameter in the registry */
726 static inline BOOL set_bool_param( unsigned int idx, LPCWSTR regkey, LPCWSTR value,
727                                    BOOL *value_ptr, BOOL new_val, UINT fWinIni )
728 {
729     return set_uint_param( idx, regkey, value, (UINT *)value_ptr, new_val, fWinIni );
730 }
731
732 /* load a boolean parameter from the user preference key */
733 static BOOL get_user_pref_param( UINT offset, UINT mask, BOOL *ret_ptr )
734 {
735     if (!ret_ptr) return FALSE;
736
737     if (!spi_loaded[SPI_USERPREFERENCEMASK_IDX])
738     {
739         SYSPARAMS_LoadRaw( SPI_USERPREFERENCEMASK_REGKEY,
740                            SPI_USERPREFERENCEMASK_VALNAME,
741                            user_prefs, sizeof(user_prefs) );
742         spi_loaded[SPI_USERPREFERENCEMASK_IDX] = TRUE;
743     }
744     *ret_ptr = (user_prefs[offset] & mask) != 0;
745     return TRUE;
746 }
747
748 /* set a boolean parameter in the user preference key */
749 static BOOL set_user_pref_param( UINT offset, UINT mask, BOOL value, BOOL fWinIni )
750 {
751     SYSPARAMS_LoadRaw( SPI_USERPREFERENCEMASK_REGKEY,
752                        SPI_USERPREFERENCEMASK_VALNAME,
753                        user_prefs, sizeof(user_prefs) );
754     spi_loaded[SPI_USERPREFERENCEMASK_IDX] = TRUE;
755
756     if (value) user_prefs[offset] |= mask;
757     else user_prefs[offset] &= ~mask;
758
759     SYSPARAMS_SaveRaw( SPI_USERPREFERENCEMASK_REGKEY,
760                        SPI_USERPREFERENCEMASK_VALNAME,
761                        user_prefs, sizeof(user_prefs), REG_BINARY, fWinIni );
762     return TRUE;
763 }
764
765 /***********************************************************************
766  *           SYSPARAMS_Init
767  *
768  * Initialisation of the system metrics array.
769  */
770 void SYSPARAMS_Init(void)
771 {
772     HKEY hkey; /* key to the window metrics area of the registry */
773     int i, r, g, b;
774     char buffer[100];
775     HBITMAP h55AABitmap;
776
777     /* initialize system colors */
778
779     if (RegCreateKeyExA(HKEY_CURRENT_USER, "Control Panel\\Colors", 0, 0, 0, KEY_ALL_ACCESS, 0, &hkey, 0))
780         hkey = 0;
781     for (i = 0; i < NUM_SYS_COLORS; i++)
782     {
783         BOOL bOk = FALSE;
784
785         /* first try, registry */
786         if (hkey)
787         {
788             DWORD dwDataSize = sizeof(buffer);
789             if (!(RegQueryValueExA(hkey,DefSysColors[i*2], 0, 0, (LPBYTE) buffer, &dwDataSize)))
790                 if (sscanf( buffer, "%d %d %d", &r, &g, &b ) == 3) bOk = TRUE;
791         }
792
793         /* second try, win.ini */
794         if (!bOk)
795         {
796             GetProfileStringA( "colors", DefSysColors[i*2], DefSysColors[i*2+1], buffer, 100 );
797             if (sscanf( buffer, " %d %d %d", &r, &g, &b ) == 3) bOk = TRUE;
798         }
799
800         /* last chance, take the default */
801         if (!bOk)
802         {
803             int iNumColors = sscanf( DefSysColors[i*2+1], " %d %d %d", &r, &g, &b );
804             assert (iNumColors==3);
805         }
806
807         SYSPARAMS_SetSysColor( i, RGB(r,g,b) );
808     }
809     if (hkey) RegCloseKey( hkey );
810
811     /* create 55AA bitmap */
812
813     h55AABitmap = CreateBitmap( 8, 8, 1, 1, wPattern55AA );
814     SYSCOLOR_55AABrush = CreatePatternBrush( h55AABitmap );
815     __wine_make_gdi_object_system( SYSCOLOR_55AABrush, TRUE );
816 }
817
818
819 /***********************************************************************
820  *              reg_get_logfont
821  *
822  *  Tries to retrieve logfont info from the specified key and value
823  */
824 static BOOL reg_get_logfont(LPCWSTR key, LPCWSTR value, LOGFONTW *lf)
825 {
826     HKEY hkey;
827     LOGFONTW lfbuf;
828     DWORD type, size;
829     BOOL found = FALSE;
830     HKEY base_keys[2];
831     int i;
832
833     base_keys[0] = get_volatile_regkey();
834     base_keys[1] = HKEY_CURRENT_USER;
835
836     for(i = 0; i < 2 && !found; i++)
837     {
838         if(RegOpenKeyW(base_keys[i], key, &hkey) == ERROR_SUCCESS)
839         {
840             size = sizeof(lfbuf);
841             if(RegQueryValueExW(hkey, value, NULL, &type, (LPBYTE)&lfbuf, &size) == ERROR_SUCCESS &&
842                     type == REG_BINARY)
843             {
844                 if( size == sizeof(lfbuf))
845                 {
846                     found = TRUE;
847                     memcpy(lf, &lfbuf, size);
848                 } else if( size == sizeof( LOGFONT16))
849                 {    /* win9x-winME format */
850                     found = TRUE;
851                     SYSPARAMS_LogFont16To32W( (LOGFONT16*) &lfbuf, lf);
852                 } else
853                     WARN("Unknown format in key %s value %s, size is %ld\n",
854                             debugstr_w( key), debugstr_w( value), size);
855             }
856             RegCloseKey(hkey);
857         }
858     }
859     if( found && lf->lfHeight > 0) { 
860         /* positive height value means points ( inch/72 ) */
861         lf->lfHeight = -MulDiv( lf->lfHeight, get_display_dpi(), 72);
862     }
863     return found;
864 }
865
866 /* load all the non-client metrics */
867 static void load_nonclient_metrics(void)
868 {
869     HKEY hkey;
870
871     if (RegOpenKeyExW (HKEY_CURRENT_USER, METRICS_REGKEY,
872                        0, KEY_QUERY_VALUE, &hkey) != ERROR_SUCCESS) hkey = 0;
873
874     /* initialize geometry entries */
875     nonclient_metrics.iBorderWidth = 1;
876     nonclient_metrics.iScrollWidth = get_reg_metric(hkey, METRICS_SCROLLWIDTH_VALNAME, 16);
877     nonclient_metrics.iScrollHeight = nonclient_metrics.iScrollWidth;
878
879     /* size of the normal caption buttons */
880     nonclient_metrics.iCaptionHeight = get_reg_metric(hkey, METRICS_CAPTIONHEIGHT_VALNAME, 18);
881     nonclient_metrics.iCaptionWidth = get_reg_metric(hkey, METRICS_CAPTIONWIDTH_VALNAME, nonclient_metrics.iCaptionHeight);
882
883     /* caption font metrics */
884     if (!reg_get_logfont(METRICS_REGKEY, METRICS_CAPTIONLOGFONT_VALNAME, &nonclient_metrics.lfCaptionFont))
885     {
886         SystemParametersInfoW( SPI_GETICONTITLELOGFONT, 0, &nonclient_metrics.lfCaptionFont, 0 );
887         nonclient_metrics.lfCaptionFont.lfWeight = FW_BOLD;
888     }
889
890     /* size of the small caption buttons */
891     nonclient_metrics.iSmCaptionWidth = get_reg_metric(hkey, METRICS_SMCAPTIONWIDTH_VALNAME, 13);
892     nonclient_metrics.iSmCaptionHeight = get_reg_metric(hkey, METRICS_SMCAPTIONHEIGHT_VALNAME, 15);
893
894     /* small caption font metrics */
895     if (!reg_get_logfont(METRICS_REGKEY, METRICS_SMCAPTIONLOGFONT_VALNAME, &nonclient_metrics.lfSmCaptionFont))
896         SystemParametersInfoW( SPI_GETICONTITLELOGFONT, 0, &nonclient_metrics.lfSmCaptionFont, 0 );
897
898     /* menus, FIXME: names of wine.conf entries are bogus */
899
900     /* size of the menu (MDI) buttons */
901     nonclient_metrics.iMenuHeight = get_reg_metric(hkey, METRICS_MENUHEIGHT_VALNAME, 18);
902     nonclient_metrics.iMenuWidth = get_reg_metric(hkey, METRICS_MENUWIDTH_VALNAME, nonclient_metrics.iMenuHeight);
903
904     /* menu font metrics */
905     if (!reg_get_logfont(METRICS_REGKEY, METRICS_MENULOGFONT_VALNAME, &nonclient_metrics.lfMenuFont))
906     {
907         SystemParametersInfoW( SPI_GETICONTITLELOGFONT, 0, &nonclient_metrics.lfMenuFont, 0 );
908         GetProfileStringW( Desktop, MenuFont, nonclient_metrics.lfCaptionFont.lfFaceName,
909                            nonclient_metrics.lfMenuFont.lfFaceName, LF_FACESIZE );
910         nonclient_metrics.lfMenuFont.lfHeight = -GetProfileIntW( Desktop, MenuFontSize, 11 );
911         nonclient_metrics.lfMenuFont.lfWeight = FW_NORMAL;
912     }
913
914     /* status bar font metrics */
915     if (!reg_get_logfont(METRICS_REGKEY, METRICS_STATUSLOGFONT_VALNAME, &nonclient_metrics.lfStatusFont))
916     {
917         SystemParametersInfoW( SPI_GETICONTITLELOGFONT, 0, &nonclient_metrics.lfStatusFont, 0 );
918         GetProfileStringW( Desktop, StatusFont, nonclient_metrics.lfCaptionFont.lfFaceName,
919                            nonclient_metrics.lfStatusFont.lfFaceName, LF_FACESIZE );
920         nonclient_metrics.lfStatusFont.lfHeight = -GetProfileIntW( Desktop, StatusFontSize, 11 );
921         nonclient_metrics.lfStatusFont.lfWeight = FW_NORMAL;
922     }
923
924     /* message font metrics */
925     if (!reg_get_logfont(METRICS_REGKEY, METRICS_MESSAGELOGFONT_VALNAME, &nonclient_metrics.lfMessageFont))
926     {
927         SystemParametersInfoW( SPI_GETICONTITLELOGFONT, 0, &nonclient_metrics.lfMessageFont, 0 );
928         GetProfileStringW( Desktop, MessageFont, nonclient_metrics.lfCaptionFont.lfFaceName,
929                            nonclient_metrics.lfMessageFont.lfFaceName, LF_FACESIZE );
930         nonclient_metrics.lfMessageFont.lfHeight = -GetProfileIntW( Desktop, MessageFontSize, 11 );
931         nonclient_metrics.lfMessageFont.lfWeight = FW_NORMAL;
932     }
933
934     /* some extra fields not in the nonclient structure */
935     icon_size.cx = icon_size.cy = get_reg_metric( hkey, METRICS_ICONSIZE_VALNAME, 32 );
936
937     scroll_height.cx = get_reg_metric (hkey, METRICS_SCROLLHEIGHT_VALNAME, nonclient_metrics.iScrollHeight );
938     scroll_height.cy = get_reg_metric (hkey, METRICS_SCROLLHEIGHT_VALNAME, nonclient_metrics.iScrollWidth );
939
940     if (hkey) RegCloseKey( hkey );
941     spi_loaded[SPI_NONCLIENTMETRICS_IDX] = TRUE;
942 }
943
944
945 /***********************************************************************
946  *              SystemParametersInfoW (USER32.@)
947  *
948  *     Each system parameter has flag which shows whether the parameter
949  * is loaded or not. Parameters, stored directly in SysParametersInfo are
950  * loaded from registry only when they are requested and the flag is
951  * "false", after the loading the flag is set to "true". On interprocess
952  * notification of the parameter change the corresponding parameter flag is
953  * set to "false". The parameter value will be reloaded when it is requested
954  * the next time.
955  *     Parameters, backed by or depend on GetSystemMetrics are processed
956  * differently. These parameters are always loaded. They are reloaded right
957  * away on interprocess change notification. We can't do lazy loading because
958  * we don't want to complicate GetSystemMetrics.
959  *     Parameters, backed by X settings are read from corresponding setting.
960  * On the parameter change request the setting is changed. Interprocess change
961  * notifications are ignored.
962  *     When parameter value is updated the changed value is stored in permanent
963  * registry branch if saving is requested. Otherwise it is stored
964  * in temporary branch
965  *
966  * Some SPI values can also be stored as Twips values in the registry,
967  * don't forget the conversion!
968  */
969 BOOL WINAPI SystemParametersInfoW( UINT uiAction, UINT uiParam,
970                                    PVOID pvParam, UINT fWinIni )
971 {
972 #define WINE_SPI_FIXME(x) \
973     case x: \
974         FIXME( "Unimplemented action: %u (%s)\n", x, #x ); \
975         SetLastError( ERROR_INVALID_SPI_VALUE ); \
976         ret = FALSE; \
977         break
978 #define WINE_SPI_WARN(x) \
979     case x: \
980         WARN( "Ignored action: %u (%s)\n", x, #x ); \
981         break
982
983     BOOL ret = TRUE;
984     unsigned spi_idx = 0;
985
986     TRACE("(%u, %u, %p, %u)\n", uiAction, uiParam, pvParam, fWinIni);
987
988     switch (uiAction)
989     {
990     case SPI_GETBEEP:                           /*      1 */
991         if (!pvParam) return FALSE;
992
993         spi_idx = SPI_SETBEEP_IDX;
994         if (!spi_loaded[spi_idx])
995         {
996             WCHAR buf[5];
997
998             if (SYSPARAMS_Load( SPI_SETBEEP_REGKEY, SPI_SETBEEP_VALNAME, buf, sizeof(buf) ))
999                 beep_active  = !lstrcmpiW( Yes, buf );
1000             spi_loaded[spi_idx] = TRUE;
1001         }
1002
1003         *(BOOL *)pvParam = beep_active;
1004         break;
1005
1006     case SPI_SETBEEP:                           /*      2 */
1007         spi_idx = SPI_SETBEEP_IDX;
1008         if (SYSPARAMS_Save( SPI_SETBEEP_REGKEY, SPI_SETBEEP_VALNAME,
1009                             (uiParam ? Yes : No), fWinIni ))
1010         {
1011             beep_active = uiParam;
1012             spi_loaded[spi_idx] = TRUE;
1013         }
1014         else
1015             ret = FALSE;
1016         break;
1017
1018     case SPI_GETMOUSE:                          /*      3 */
1019         if (!pvParam) return FALSE;
1020
1021         spi_idx = SPI_SETMOUSE_IDX;
1022         if (!spi_loaded[spi_idx])
1023         {
1024             WCHAR buf[10];
1025
1026             if (SYSPARAMS_Load( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME1,
1027                                 buf, sizeof(buf) ))
1028                 mouse_threshold1 = atoiW( buf );
1029             if (SYSPARAMS_Load( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME2,
1030                                 buf, sizeof(buf) ))
1031                 mouse_threshold2 = atoiW( buf );
1032             if (SYSPARAMS_Load( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME3,
1033                                 buf, sizeof(buf) ))
1034                 mouse_speed = atoiW( buf );
1035             spi_loaded[spi_idx] = TRUE;
1036         }
1037         ((INT *)pvParam)[0] = mouse_threshold1;
1038         ((INT *)pvParam)[1] = mouse_threshold2;
1039         ((INT *)pvParam)[2] = mouse_speed;
1040         break;
1041
1042     case SPI_SETMOUSE:                          /*      4 */
1043     {
1044         WCHAR buf[10];
1045
1046         if (!pvParam) return FALSE;
1047
1048         spi_idx = SPI_SETMOUSE_IDX;
1049         wsprintfW(buf, CSd, ((INT *)pvParam)[0]);
1050
1051         if (SYSPARAMS_Save( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME1,
1052                             buf, fWinIni ))
1053         {
1054             mouse_threshold1 = ((INT *)pvParam)[0];
1055             spi_loaded[spi_idx] = TRUE;
1056
1057             wsprintfW(buf, CSd, ((INT *)pvParam)[1]);
1058             SYSPARAMS_Save( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME2,
1059                             buf, fWinIni );
1060             mouse_threshold2 = ((INT *)pvParam)[1];
1061
1062             wsprintfW(buf, CSd, ((INT *)pvParam)[2]);
1063             SYSPARAMS_Save( SPI_SETMOUSE_REGKEY, SPI_SETMOUSE_VALNAME3,
1064                             buf, fWinIni );
1065             mouse_speed = ((INT *)pvParam)[2];
1066         }
1067         else
1068             ret = FALSE;
1069         break;
1070     }
1071
1072     case SPI_GETBORDER:
1073         ret = get_twips_param( SPI_SETBORDER_IDX,
1074                                SPI_SETBORDER_REGKEY,
1075                                SPI_SETBORDER_VALNAME,
1076                                &border, pvParam );
1077         break;
1078
1079     case SPI_SETBORDER:
1080         ret = set_uint_param( SPI_SETBORDER_IDX,
1081                               SPI_SETBORDER_REGKEY,
1082                               SPI_SETBORDER_VALNAME,
1083                               &border, uiParam, fWinIni );
1084         break;
1085
1086     case SPI_GETKEYBOARDSPEED:
1087         ret = get_uint_param( SPI_SETKEYBOARDSPEED_IDX,
1088                               SPI_SETKEYBOARDSPEED_REGKEY,
1089                               SPI_SETKEYBOARDSPEED_VALNAME,
1090                               &keyboard_speed, pvParam );
1091         break;
1092
1093     case SPI_SETKEYBOARDSPEED:
1094         if (uiParam > 31) uiParam = 31;
1095         ret = set_uint_param( SPI_SETKEYBOARDSPEED_IDX,
1096                               SPI_SETKEYBOARDSPEED_REGKEY,
1097                               SPI_SETKEYBOARDSPEED_VALNAME,
1098                               &keyboard_speed, uiParam, fWinIni );
1099         break;
1100
1101     /* not implemented in Windows */
1102     WINE_SPI_WARN(SPI_LANGDRIVER);              /*     12 */
1103
1104     case SPI_ICONHORIZONTALSPACING:
1105         if (pvParam != NULL)
1106         {
1107             ret = get_twips_param( SPI_ICONHORIZONTALSPACING_IDX,
1108                                    SPI_ICONHORIZONTALSPACING_REGKEY,
1109                                    SPI_ICONHORIZONTALSPACING_VALNAME,
1110                                    &icon_metrics.iHorzSpacing, pvParam );
1111         }
1112         else
1113         {
1114             if (uiParam < 32) uiParam = 32;
1115             ret = set_uint_param( SPI_ICONHORIZONTALSPACING_IDX,
1116                                   SPI_ICONHORIZONTALSPACING_REGKEY,
1117                                   SPI_ICONHORIZONTALSPACING_VALNAME,
1118                                   &icon_metrics.iHorzSpacing, uiParam, fWinIni );
1119         }
1120         break;
1121
1122     case SPI_GETSCREENSAVETIMEOUT:
1123         ret = get_uint_param( SPI_SETSCREENSAVETIMEOUT_IDX,
1124                               SPI_SETSCREENSAVETIMEOUT_REGKEY,
1125                               SPI_SETSCREENSAVETIMEOUT_VALNAME,
1126                               &screensave_timeout, pvParam );
1127         break;
1128
1129     case SPI_SETSCREENSAVETIMEOUT:
1130         ret = set_uint_param( SPI_SETSCREENSAVETIMEOUT_IDX,
1131                               SPI_SETSCREENSAVETIMEOUT_REGKEY,
1132                               SPI_SETSCREENSAVETIMEOUT_VALNAME,
1133                               &screensave_timeout, uiParam, fWinIni );
1134         break;
1135
1136     case SPI_GETSCREENSAVEACTIVE:               /*     16 */
1137         if (!pvParam) return FALSE;
1138         if (USER_Driver.pGetScreenSaveActive)
1139             *(BOOL *)pvParam = USER_Driver.pGetScreenSaveActive();
1140         else
1141             *(BOOL *)pvParam = FALSE;
1142         break;
1143
1144     case SPI_SETSCREENSAVEACTIVE:               /*     17 */
1145     {
1146         WCHAR buf[5];
1147
1148         wsprintfW(buf, CSu, uiParam);
1149         if (USER_Driver.pSetScreenSaveActive)
1150             USER_Driver.pSetScreenSaveActive( uiParam );
1151         /* saved value does not affect Wine */
1152         SYSPARAMS_Save( SPI_SETSCREENSAVEACTIVE_REGKEY,
1153                         SPI_SETSCREENSAVEACTIVE_VALNAME,
1154                         buf, fWinIni );
1155         break;
1156     }
1157
1158     case SPI_GETGRIDGRANULARITY:
1159         ret = get_uint_param( SPI_SETGRIDGRANULARITY_IDX,
1160                               SPI_SETGRIDGRANULARITY_REGKEY,
1161                               SPI_SETGRIDGRANULARITY_VALNAME,
1162                               &grid_granularity, pvParam );
1163         break;
1164
1165     case SPI_SETGRIDGRANULARITY:
1166         ret = set_uint_param( SPI_SETGRIDGRANULARITY_IDX,
1167                               SPI_SETGRIDGRANULARITY_REGKEY,
1168                               SPI_SETGRIDGRANULARITY_VALNAME,
1169                               &grid_granularity, uiParam, fWinIni );
1170         break;
1171
1172     case SPI_SETDESKWALLPAPER:                  /*     20 */
1173         if (!pvParam || !SetDeskWallPaper( (LPSTR)pvParam )) return FALSE;
1174         SYSPARAMS_Save(SPI_SETDESKWALLPAPER_REGKEY, SPI_SETDESKWALLPAPER_VALNAME, pvParam, fWinIni);
1175         break;
1176         
1177     case SPI_SETDESKPATTERN:                    /*     21 */
1178         /* FIXME: the ability to specify a pattern in pvParam
1179            doesn't seem to be documented for Win32 */
1180         if ((INT16)uiParam == -1)
1181         {
1182             WCHAR buf[256];
1183             GetProfileStringW( Desktop, Pattern,
1184                                defPattern,
1185                                buf, sizeof(buf)/sizeof(WCHAR) );
1186             ret = DESKTOP_SetPattern( buf );
1187         } else
1188             ret = DESKTOP_SetPattern( (LPWSTR)pvParam );
1189         break;
1190
1191     case SPI_GETKEYBOARDDELAY:
1192         ret = get_uint_param( SPI_SETKEYBOARDDELAY_IDX,
1193                               SPI_SETKEYBOARDDELAY_REGKEY,
1194                               SPI_SETKEYBOARDDELAY_VALNAME,
1195                               &keyboard_delay, pvParam );
1196         break;
1197
1198     case SPI_SETKEYBOARDDELAY:
1199         ret = set_uint_param( SPI_SETKEYBOARDDELAY_IDX,
1200                               SPI_SETKEYBOARDDELAY_REGKEY,
1201                               SPI_SETKEYBOARDDELAY_VALNAME,
1202                               &keyboard_delay, uiParam, fWinIni );
1203         break;
1204
1205     case SPI_ICONVERTICALSPACING:
1206         if (pvParam != NULL)
1207         {
1208             ret = get_twips_param( SPI_ICONVERTICALSPACING_IDX,
1209                                    SPI_ICONVERTICALSPACING_REGKEY,
1210                                    SPI_ICONVERTICALSPACING_VALNAME,
1211                                    &icon_metrics.iVertSpacing, pvParam );
1212         }
1213         else
1214         {
1215             if (uiParam < 32) uiParam = 32;
1216             ret = set_uint_param( SPI_ICONVERTICALSPACING_IDX,
1217                                   SPI_ICONVERTICALSPACING_REGKEY,
1218                                   SPI_ICONVERTICALSPACING_VALNAME,
1219                                   &icon_metrics.iVertSpacing, uiParam, fWinIni );
1220         }
1221         break;
1222
1223     case SPI_GETICONTITLEWRAP:
1224         ret = get_bool_param( SPI_SETICONTITLEWRAP_IDX,
1225                               SPI_SETICONTITLEWRAP_REGKEY1,
1226                               SPI_SETICONTITLEWRAP_VALNAME,
1227                               &icon_metrics.iTitleWrap, pvParam );
1228         break;
1229
1230     case SPI_SETICONTITLEWRAP:
1231         ret = set_bool_param_mirrored( SPI_SETICONTITLEWRAP_IDX,
1232                                        SPI_SETICONTITLEWRAP_REGKEY1,
1233                                        SPI_SETICONTITLEWRAP_REGKEY2,
1234                                        SPI_SETICONTITLEWRAP_VALNAME,
1235                                        &icon_metrics.iTitleWrap, uiParam, fWinIni );
1236         break;
1237
1238     case SPI_GETMENUDROPALIGNMENT:
1239         ret = get_uint_param( SPI_SETMENUDROPALIGNMENT_IDX,
1240                               SPI_SETMENUDROPALIGNMENT_REGKEY1,
1241                               SPI_SETMENUDROPALIGNMENT_VALNAME,
1242                               &menu_drop_alignment, pvParam );
1243         break;
1244
1245     case SPI_SETMENUDROPALIGNMENT:
1246         ret = set_uint_param_mirrored( SPI_SETMENUDROPALIGNMENT_IDX,
1247                                        SPI_SETMENUDROPALIGNMENT_REGKEY1,
1248                                        SPI_SETMENUDROPALIGNMENT_REGKEY2,
1249                                        SPI_SETMENUDROPALIGNMENT_VALNAME,
1250                                        &menu_drop_alignment, uiParam, fWinIni );
1251         break;
1252
1253     case SPI_SETDOUBLECLKWIDTH:
1254         ret = set_uint_param_mirrored( SPI_SETDOUBLECLKWIDTH_IDX,
1255                                        SPI_SETDOUBLECLKWIDTH_REGKEY1,
1256                                        SPI_SETDOUBLECLKWIDTH_REGKEY2,
1257                                        SPI_SETDOUBLECLKWIDTH_VALNAME,
1258                                        &double_click_width, uiParam, fWinIni );
1259         break;
1260
1261     case SPI_SETDOUBLECLKHEIGHT:
1262         ret = set_uint_param_mirrored( SPI_SETDOUBLECLKHEIGHT_IDX,
1263                                        SPI_SETDOUBLECLKHEIGHT_REGKEY1,
1264                                        SPI_SETDOUBLECLKHEIGHT_REGKEY2,
1265                                        SPI_SETDOUBLECLKHEIGHT_VALNAME,
1266                                        &double_click_height, uiParam, fWinIni );
1267         break;
1268
1269     case SPI_GETICONTITLELOGFONT:
1270     {
1271         LOGFONTW lfDefault;
1272
1273         if (!pvParam) return FALSE;
1274
1275         spi_idx = SPI_SETICONTITLELOGFONT_IDX;
1276         if (!spi_loaded[spi_idx])
1277         {
1278             if (!reg_get_logfont( SPI_SETICONTITLELOGFONT_REGKEY,
1279                                   SPI_SETICONTITLELOGFONT_VALNAME, &icon_metrics.lfFont ))
1280             {
1281                 /*
1282                  * The 'default GDI fonts' seems to be returned.
1283                  * If a returned font is not a correct font in your environment,
1284                  * please try to fix objects/gdiobj.c at first.
1285                  */
1286                 GetObjectW( GetStockObject( DEFAULT_GUI_FONT ), sizeof(LOGFONTW), &lfDefault );
1287
1288                 GetProfileStringW( Desktop, IconTitleFaceName,
1289                                    lfDefault.lfFaceName,
1290                                    icon_metrics.lfFont.lfFaceName,
1291                                    LF_FACESIZE );
1292                 icon_metrics.lfFont.lfHeight = -GetProfileIntW( Desktop, IconTitleSize, 11 );
1293                 icon_metrics.lfFont.lfWidth = 0;
1294                 icon_metrics.lfFont.lfEscapement = icon_metrics.lfFont.lfOrientation = 0;
1295                 icon_metrics.lfFont.lfWeight = FW_NORMAL;
1296                 icon_metrics.lfFont.lfItalic = FALSE;
1297                 icon_metrics.lfFont.lfStrikeOut = FALSE;
1298                 icon_metrics.lfFont.lfUnderline = FALSE;
1299                 icon_metrics.lfFont.lfCharSet = lfDefault.lfCharSet; /* at least 'charset' should not be hard-coded */
1300                 icon_metrics.lfFont.lfOutPrecision = OUT_DEFAULT_PRECIS;
1301                 icon_metrics.lfFont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1302                 icon_metrics.lfFont.lfQuality = DEFAULT_QUALITY;
1303                 icon_metrics.lfFont.lfPitchAndFamily = DEFAULT_PITCH;
1304                 spi_loaded[spi_idx] = TRUE;
1305             }
1306         }
1307         *(LOGFONTW *)pvParam = icon_metrics.lfFont;
1308         break;
1309     }
1310
1311     case SPI_SETDOUBLECLICKTIME:
1312         ret = set_uint_param( SPI_SETDOUBLECLICKTIME_IDX,
1313                               SPI_SETDOUBLECLICKTIME_REGKEY,
1314                               SPI_SETDOUBLECLICKTIME_VALNAME,
1315                               &double_click_time, uiParam, fWinIni );
1316         break;
1317
1318     case SPI_SETMOUSEBUTTONSWAP:
1319         ret = set_uint_param( SPI_SETMOUSEBUTTONSWAP_IDX,
1320                               SPI_SETMOUSEBUTTONSWAP_REGKEY,
1321                               SPI_SETMOUSEBUTTONSWAP_VALNAME,
1322                               &swap_buttons, uiParam, fWinIni );
1323         break;
1324
1325     WINE_SPI_FIXME(SPI_SETICONTITLELOGFONT);    /*     34 */
1326
1327     case SPI_GETFASTTASKSWITCH:                 /*     35 */
1328         if (!pvParam) return FALSE;
1329         *(BOOL *)pvParam = 1;
1330         break;
1331
1332     case SPI_SETFASTTASKSWITCH:                 /*     36 */
1333         /* the action is disabled */
1334         ret = FALSE;
1335         break;
1336
1337     case SPI_SETDRAGFULLWINDOWS:
1338         ret = set_bool_param( SPI_SETDRAGFULLWINDOWS_IDX,
1339                               SPI_SETDRAGFULLWINDOWS_REGKEY,
1340                               SPI_SETDRAGFULLWINDOWS_VALNAME,
1341                               &drag_full_windows, uiParam, fWinIni );
1342         break;
1343
1344     case SPI_GETDRAGFULLWINDOWS:
1345         ret = get_bool_param( SPI_SETDRAGFULLWINDOWS_IDX,
1346                               SPI_SETDRAGFULLWINDOWS_REGKEY,
1347                               SPI_SETDRAGFULLWINDOWS_VALNAME,
1348                               &drag_full_windows, pvParam );
1349         break;
1350
1351     case SPI_GETNONCLIENTMETRICS:
1352     {
1353         LPNONCLIENTMETRICSW lpnm = pvParam;
1354
1355         if (!spi_loaded[SPI_NONCLIENTMETRICS_IDX]) load_nonclient_metrics();
1356
1357         if (lpnm && lpnm->cbSize == sizeof(NONCLIENTMETRICSW))
1358             memcpy( lpnm, &nonclient_metrics, sizeof(*lpnm) );
1359         else
1360             ret = FALSE;
1361         break;
1362     }
1363
1364     case SPI_SETNONCLIENTMETRICS:
1365     {
1366         LPNONCLIENTMETRICSW lpnm = pvParam;
1367
1368         if (lpnm && lpnm->cbSize == sizeof(NONCLIENTMETRICSW))
1369         {
1370             memcpy( &nonclient_metrics, lpnm, sizeof(nonclient_metrics) );
1371             spi_loaded[SPI_NONCLIENTMETRICS_IDX] = TRUE;
1372         }
1373         break;
1374     }
1375
1376     case SPI_GETMINIMIZEDMETRICS:
1377     {
1378         MINIMIZEDMETRICS * lpMm = pvParam;
1379         if (lpMm && lpMm->cbSize == sizeof(*lpMm))
1380             memcpy( lpMm, &minimized_metrics, sizeof(*lpMm) );
1381         else
1382             ret = FALSE;
1383         break;
1384     }
1385
1386     case SPI_SETMINIMIZEDMETRICS:
1387     {
1388         MINIMIZEDMETRICS * lpMm = pvParam;
1389         if (lpMm && lpMm->cbSize == sizeof(*lpMm))
1390             memcpy( &minimized_metrics, lpMm, sizeof(*lpMm) );
1391         else
1392             ret = FALSE;
1393         break;
1394     }
1395
1396     case SPI_GETICONMETRICS:
1397     {
1398         LPICONMETRICSW lpIcon = pvParam;
1399         if(lpIcon && lpIcon->cbSize == sizeof(*lpIcon))
1400         {
1401             SystemParametersInfoW( SPI_ICONHORIZONTALSPACING, 0,
1402                                    &lpIcon->iHorzSpacing, FALSE );
1403             SystemParametersInfoW( SPI_ICONVERTICALSPACING, 0,
1404                                    &lpIcon->iVertSpacing, FALSE );
1405             SystemParametersInfoW( SPI_GETICONTITLEWRAP, 0,
1406                                    &lpIcon->iTitleWrap, FALSE );
1407             SystemParametersInfoW( SPI_GETICONTITLELOGFONT, 0,
1408                                    &lpIcon->lfFont, FALSE );
1409         }
1410         else
1411         {
1412             ret = FALSE;
1413         }
1414         break;
1415     }
1416
1417     case SPI_SETICONMETRICS:
1418     {
1419         LPICONMETRICSW lpIcon = pvParam;
1420         if (lpIcon && lpIcon->cbSize == sizeof(*lpIcon))
1421             memcpy( &icon_metrics, lpIcon, sizeof(icon_metrics) );
1422         else
1423             ret = FALSE;
1424         break;
1425     }
1426
1427     case SPI_SETWORKAREA:                       /*     47  WINVER >= 0x400 */
1428     {
1429         if (!pvParam) return FALSE;
1430
1431         spi_idx = SPI_SETWORKAREA_IDX;
1432         CopyRect( &work_area, (RECT *)pvParam );
1433         spi_loaded[spi_idx] = TRUE;
1434         break;
1435     }
1436
1437     case SPI_GETWORKAREA:                       /*     48  WINVER >= 0x400 */
1438     {
1439         if (!pvParam) return FALSE;
1440
1441         spi_idx = SPI_SETWORKAREA_IDX;
1442         if (!spi_loaded[spi_idx])
1443         {
1444             SetRect( &work_area, 0, 0,
1445                      GetSystemMetrics( SM_CXSCREEN ),
1446                      GetSystemMetrics( SM_CYSCREEN ) );
1447             spi_loaded[spi_idx] = TRUE;
1448         }
1449         CopyRect( (RECT *)pvParam, &work_area );
1450
1451         break;
1452     }
1453
1454     WINE_SPI_FIXME(SPI_SETPENWINDOWS);          /*     49  WINVER >= 0x400 */
1455
1456     case SPI_GETFILTERKEYS:                     /*     50 */
1457     {
1458         LPFILTERKEYS lpFilterKeys = (LPFILTERKEYS)pvParam;
1459         WARN("SPI_GETFILTERKEYS not fully implemented\n");
1460         if (lpFilterKeys && lpFilterKeys->cbSize == sizeof(FILTERKEYS))
1461         {
1462             /* Indicate that no FilterKeys feature available */
1463             lpFilterKeys->dwFlags = 0;
1464             lpFilterKeys->iWaitMSec = 0;
1465             lpFilterKeys->iDelayMSec = 0;
1466             lpFilterKeys->iRepeatMSec = 0;
1467             lpFilterKeys->iBounceMSec = 0;
1468          }
1469         else
1470         {
1471             ret = FALSE;
1472         }
1473         break;
1474     }
1475     WINE_SPI_FIXME(SPI_SETFILTERKEYS);          /*     51 */
1476
1477     case SPI_GETTOGGLEKEYS:                     /*     52 */
1478     {
1479         LPTOGGLEKEYS lpToggleKeys = (LPTOGGLEKEYS)pvParam;
1480         WARN("SPI_GETTOGGLEKEYS not fully implemented\n");
1481         if (lpToggleKeys && lpToggleKeys->cbSize == sizeof(TOGGLEKEYS))
1482         {
1483             /* Indicate that no ToggleKeys feature available */
1484             lpToggleKeys->dwFlags = 0;
1485         }
1486         else
1487         {
1488             ret = FALSE;
1489         }
1490         break;
1491     }
1492     WINE_SPI_FIXME(SPI_SETTOGGLEKEYS);          /*     53 */
1493
1494     case SPI_GETMOUSEKEYS:                      /*     54 */
1495     {
1496         LPMOUSEKEYS lpMouseKeys = (LPMOUSEKEYS)pvParam;
1497         WARN("SPI_GETMOUSEKEYS not fully implemented\n");
1498         if (lpMouseKeys && lpMouseKeys->cbSize == sizeof(MOUSEKEYS))
1499         {
1500             /* Indicate that no MouseKeys feature available */
1501             lpMouseKeys->dwFlags = 0;
1502             lpMouseKeys->iMaxSpeed = 360;
1503             lpMouseKeys->iTimeToMaxSpeed = 1000;
1504             lpMouseKeys->iCtrlSpeed = 0;
1505             lpMouseKeys->dwReserved1 = 0;
1506             lpMouseKeys->dwReserved2 = 0;
1507         }
1508         else
1509         {
1510             ret = FALSE;
1511         }
1512         break;
1513     }
1514     WINE_SPI_FIXME(SPI_SETMOUSEKEYS);           /*     55 */
1515
1516     case SPI_GETSHOWSOUNDS:
1517         ret = get_bool_param( SPI_SETSHOWSOUNDS_IDX,
1518                               SPI_SETSHOWSOUNDS_REGKEY,
1519                               SPI_SETSHOWSOUNDS_VALNAME,
1520                               &show_sounds, pvParam );
1521         break;
1522
1523     case SPI_SETSHOWSOUNDS:
1524         ret = set_bool_param( SPI_SETSHOWSOUNDS_IDX,
1525                               SPI_SETSHOWSOUNDS_REGKEY,
1526                               SPI_SETSHOWSOUNDS_VALNAME,
1527                               &show_sounds, uiParam, fWinIni );
1528         break;
1529
1530     case SPI_GETSTICKYKEYS:                     /*     58 */
1531     {
1532         LPSTICKYKEYS lpStickyKeys = (LPSTICKYKEYS)pvParam;
1533         WARN("SPI_GETSTICKYKEYS not fully implemented\n");
1534         if (lpStickyKeys && lpStickyKeys->cbSize == sizeof(STICKYKEYS))
1535         {
1536             /* Indicate that no StickyKeys feature available */
1537             lpStickyKeys->dwFlags = 0;
1538         }
1539         else
1540         {
1541             ret = FALSE;
1542         }
1543         break;
1544     }
1545     WINE_SPI_FIXME(SPI_SETSTICKYKEYS);          /*     59 */
1546
1547     case SPI_GETACCESSTIMEOUT:                  /*     60 */
1548     {
1549         LPACCESSTIMEOUT lpAccessTimeout = (LPACCESSTIMEOUT)pvParam;
1550         WARN("SPI_GETACCESSTIMEOUT not fully implemented\n");
1551         if (lpAccessTimeout && lpAccessTimeout->cbSize == sizeof(ACCESSTIMEOUT))
1552         {
1553             /* Indicate that no accessibility features timeout is available */
1554             lpAccessTimeout->dwFlags = 0;
1555             lpAccessTimeout->iTimeOutMSec = 0;
1556         }
1557         else
1558         {
1559             ret = FALSE;
1560         }
1561         break;
1562     }
1563     WINE_SPI_FIXME(SPI_SETACCESSTIMEOUT);       /*     61 */
1564
1565     case SPI_GETSERIALKEYS:                     /*     62  WINVER >= 0x400 */
1566     {
1567         LPSERIALKEYSW lpSerialKeysW = (LPSERIALKEYSW)pvParam;
1568         WARN("SPI_GETSERIALKEYS not fully implemented\n");
1569         if (lpSerialKeysW && lpSerialKeysW->cbSize == sizeof(SERIALKEYSW))
1570         {
1571             /* Indicate that no SerialKeys feature available */
1572             lpSerialKeysW->dwFlags = 0;
1573             lpSerialKeysW->lpszActivePort = NULL;
1574             lpSerialKeysW->lpszPort = NULL;
1575             lpSerialKeysW->iBaudRate = 0;
1576             lpSerialKeysW->iPortState = 0;
1577         }
1578         else
1579         {
1580             ret = FALSE;
1581         }
1582         break;
1583     }
1584     WINE_SPI_FIXME(SPI_SETSERIALKEYS);          /*     63  WINVER >= 0x400 */
1585
1586     case SPI_GETSOUNDSENTRY:                    /*     64 */
1587     {
1588         LPSOUNDSENTRYW lpSoundSentryW = (LPSOUNDSENTRYW)pvParam;
1589         WARN("SPI_GETSOUNDSENTRY not fully implemented\n");
1590         if (lpSoundSentryW && lpSoundSentryW->cbSize == sizeof(SOUNDSENTRYW))
1591         {
1592             /* Indicate that no SoundSentry feature available */
1593             lpSoundSentryW->dwFlags = 0;
1594             lpSoundSentryW->iFSTextEffect = 0;
1595             lpSoundSentryW->iFSTextEffectMSec = 0;
1596             lpSoundSentryW->iFSTextEffectColorBits = 0;
1597             lpSoundSentryW->iFSGrafEffect = 0;
1598             lpSoundSentryW->iFSGrafEffectMSec = 0;
1599             lpSoundSentryW->iFSGrafEffectColor = 0;
1600             lpSoundSentryW->iWindowsEffect = 0;
1601             lpSoundSentryW->iWindowsEffectMSec = 0;
1602             lpSoundSentryW->lpszWindowsEffectDLL = 0;
1603             lpSoundSentryW->iWindowsEffectOrdinal = 0;
1604         }
1605         else
1606         {
1607             ret = FALSE;
1608         }
1609         break;
1610     }
1611     WINE_SPI_FIXME(SPI_SETSOUNDSENTRY);         /*     65 */
1612
1613     case SPI_GETHIGHCONTRAST:                   /*     66  WINVER >= 0x400 */
1614     {
1615         LPHIGHCONTRASTW lpHighContrastW = (LPHIGHCONTRASTW)pvParam;
1616         WARN("SPI_GETHIGHCONTRAST not fully implemented\n");
1617         if (lpHighContrastW && lpHighContrastW->cbSize == sizeof(HIGHCONTRASTW))
1618         {
1619             /* Indicate that no high contrast feature available */
1620             lpHighContrastW->dwFlags = 0;
1621             lpHighContrastW->lpszDefaultScheme = NULL;
1622         }
1623         else
1624         {
1625             ret = FALSE;
1626         }
1627         break;
1628     }
1629     WINE_SPI_FIXME(SPI_SETHIGHCONTRAST);        /*     67  WINVER >= 0x400 */
1630
1631     case SPI_GETKEYBOARDPREF:
1632         ret = get_bool_param( SPI_SETKEYBOARDPREF_IDX,
1633                               SPI_SETKEYBOARDPREF_REGKEY,
1634                               SPI_SETKEYBOARDPREF_VALNAME,
1635                               &keyboard_pref, pvParam );
1636         break;
1637
1638     case SPI_SETKEYBOARDPREF:
1639         ret = set_bool_param( SPI_SETKEYBOARDPREF_IDX,
1640                               SPI_SETKEYBOARDPREF_REGKEY,
1641                               SPI_SETKEYBOARDPREF_VALNAME,
1642                               &keyboard_pref, uiParam, fWinIni );
1643         break;
1644
1645     case SPI_GETSCREENREADER:
1646         ret = get_bool_param( SPI_SETSCREENREADER_IDX,
1647                               SPI_SETSCREENREADER_REGKEY,
1648                               SPI_SETSCREENREADER_VALNAME,
1649                               &screen_reader, pvParam );
1650         break;
1651
1652     case SPI_SETSCREENREADER:
1653         ret = set_bool_param( SPI_SETSCREENREADER_IDX,
1654                               SPI_SETSCREENREADER_REGKEY,
1655                               SPI_SETSCREENREADER_VALNAME,
1656                               &screen_reader, uiParam, fWinIni );
1657         break;
1658
1659     case SPI_GETANIMATION:                      /*     72  WINVER >= 0x400 */
1660     {
1661         LPANIMATIONINFO lpAnimInfo = (LPANIMATIONINFO)pvParam;
1662
1663         /* Tell it "disabled" */
1664         if (lpAnimInfo && lpAnimInfo->cbSize == sizeof(ANIMATIONINFO))
1665             lpAnimInfo->iMinAnimate = 0; /* Minimise and restore animation is disabled (nonzero == enabled) */
1666         else
1667             ret = FALSE;
1668         break;
1669     }
1670     WINE_SPI_WARN(SPI_SETANIMATION);            /*     73  WINVER >= 0x400 */
1671
1672     case SPI_GETFONTSMOOTHING:
1673         ret = get_uint_param( SPI_SETFONTSMOOTHING_IDX,
1674                               SPI_SETFONTSMOOTHING_REGKEY,
1675                               SPI_SETFONTSMOOTHING_VALNAME,
1676                               &font_smoothing, pvParam );
1677         break;
1678
1679     case SPI_SETFONTSMOOTHING:
1680         ret = set_uint_param( SPI_SETFONTSMOOTHING_IDX,
1681                               SPI_SETFONTSMOOTHING_REGKEY,
1682                               SPI_SETFONTSMOOTHING_VALNAME,
1683                               &font_smoothing, uiParam, fWinIni );
1684         break;
1685
1686     WINE_SPI_FIXME(SPI_SETDRAGWIDTH);           /*     76  WINVER >= 0x400 */
1687     WINE_SPI_FIXME(SPI_SETDRAGHEIGHT);          /*     77  WINVER >= 0x400 */
1688
1689     WINE_SPI_FIXME(SPI_SETHANDHELD);            /*     78  WINVER >= 0x400 */
1690
1691     WINE_SPI_FIXME(SPI_GETLOWPOWERTIMEOUT);     /*     79  WINVER >= 0x400 */
1692     WINE_SPI_FIXME(SPI_GETPOWEROFFTIMEOUT);     /*     80  WINVER >= 0x400 */
1693     WINE_SPI_FIXME(SPI_SETLOWPOWERTIMEOUT);     /*     81  WINVER >= 0x400 */
1694     WINE_SPI_FIXME(SPI_SETPOWEROFFTIMEOUT);     /*     82  WINVER >= 0x400 */
1695
1696     case SPI_GETLOWPOWERACTIVE:
1697         ret = get_bool_param( SPI_SETLOWPOWERACTIVE_IDX,
1698                               SPI_SETLOWPOWERACTIVE_REGKEY,
1699                               SPI_SETLOWPOWERACTIVE_VALNAME,
1700                               &lowpoweractive, pvParam );
1701         break;
1702
1703     case SPI_GETPOWEROFFACTIVE:
1704         ret = get_bool_param( SPI_SETPOWEROFFACTIVE_IDX,
1705                               SPI_SETPOWEROFFACTIVE_REGKEY,
1706                               SPI_SETPOWEROFFACTIVE_VALNAME,
1707                               &poweroffactive, pvParam );
1708         break;
1709
1710     case SPI_SETLOWPOWERACTIVE:
1711         ret = set_bool_param( SPI_SETLOWPOWERACTIVE_IDX,
1712                               SPI_SETLOWPOWERACTIVE_REGKEY,
1713                               SPI_SETLOWPOWERACTIVE_VALNAME,
1714                               &lowpoweractive, uiParam, fWinIni );
1715         break;
1716
1717     case SPI_SETPOWEROFFACTIVE:
1718         ret = set_bool_param( SPI_SETPOWEROFFACTIVE_IDX,
1719                               SPI_SETPOWEROFFACTIVE_REGKEY,
1720                               SPI_SETPOWEROFFACTIVE_VALNAME,
1721                               &poweroffactive, uiParam, fWinIni );
1722         break;
1723
1724     WINE_SPI_FIXME(SPI_SETCURSORS);             /*     87  WINVER >= 0x400 */
1725     WINE_SPI_FIXME(SPI_SETICONS);               /*     88  WINVER >= 0x400 */
1726
1727     case SPI_GETDEFAULTINPUTLANG:       /*     89  WINVER >= 0x400 */
1728         ret = GetKeyboardLayout(0) ? TRUE : FALSE;
1729         break;
1730
1731     WINE_SPI_FIXME(SPI_SETDEFAULTINPUTLANG);    /*     90  WINVER >= 0x400 */
1732
1733     WINE_SPI_FIXME(SPI_SETLANGTOGGLE);          /*     91  WINVER >= 0x400 */
1734
1735     case SPI_GETWINDOWSEXTENSION:               /*     92  WINVER >= 0x400 */
1736         WARN("pretend no support for Win9x Plus! for now.\n");
1737         ret = FALSE; /* yes, this is the result value */
1738         break;
1739
1740     WINE_SPI_FIXME(SPI_SETMOUSETRAILS);         /*     93  WINVER >= 0x400 */
1741     WINE_SPI_FIXME(SPI_GETMOUSETRAILS);         /*     94  WINVER >= 0x400 */
1742     WINE_SPI_FIXME(SPI_GETSNAPTODEFBUTTON);     /*     95  WINVER >= 0x400 */
1743     WINE_SPI_FIXME(SPI_SETSNAPTODEFBUTTON);     /*     96  WINVER >= 0x400 */
1744
1745     case SPI_SETSCREENSAVERRUNNING:
1746         ret = set_bool_param( SPI_SETSCREENSAVERRUNNING_IDX,
1747                               SPI_SETSCREENSAVERRUNNING_REGKEY,
1748                               SPI_SETSCREENSAVERRUNNING_VALNAME,
1749                               &screensaver_running, uiParam, fWinIni );
1750         break;
1751
1752     case SPI_GETMOUSEHOVERWIDTH:
1753         ret = get_uint_param( SPI_SETMOUSEHOVERWIDTH_IDX,
1754                               SPI_SETMOUSEHOVERWIDTH_REGKEY,
1755                               SPI_SETMOUSEHOVERWIDTH_VALNAME,
1756                               &mouse_hover_width, pvParam );
1757         break;
1758
1759     case SPI_SETMOUSEHOVERWIDTH:
1760         ret = set_uint_param( SPI_SETMOUSEHOVERWIDTH_IDX,
1761                               SPI_SETMOUSEHOVERWIDTH_REGKEY,
1762                               SPI_SETMOUSEHOVERWIDTH_VALNAME,
1763                               &mouse_hover_width, uiParam, fWinIni );
1764         break;
1765
1766     case SPI_GETMOUSEHOVERHEIGHT:
1767         ret = get_uint_param( SPI_SETMOUSEHOVERHEIGHT_IDX,
1768                               SPI_SETMOUSEHOVERHEIGHT_REGKEY,
1769                               SPI_SETMOUSEHOVERHEIGHT_VALNAME,
1770                               &mouse_hover_height, pvParam );
1771         break;
1772
1773     case SPI_SETMOUSEHOVERHEIGHT:
1774         ret = set_uint_param( SPI_SETMOUSEHOVERHEIGHT_IDX,
1775                               SPI_SETMOUSEHOVERHEIGHT_REGKEY,
1776                               SPI_SETMOUSEHOVERHEIGHT_VALNAME,
1777                               &mouse_hover_height, uiParam, fWinIni );
1778         break;
1779
1780     case SPI_GETMOUSEHOVERTIME:
1781         ret = get_uint_param( SPI_SETMOUSEHOVERTIME_IDX,
1782                               SPI_SETMOUSEHOVERTIME_REGKEY,
1783                               SPI_SETMOUSEHOVERTIME_VALNAME,
1784                               &mouse_hover_time, pvParam );
1785         break;
1786
1787     case SPI_SETMOUSEHOVERTIME:
1788         ret = set_uint_param( SPI_SETMOUSEHOVERTIME_IDX,
1789                               SPI_SETMOUSEHOVERTIME_REGKEY,
1790                               SPI_SETMOUSEHOVERTIME_VALNAME,
1791                               &mouse_hover_time, uiParam, fWinIni );
1792         break;
1793
1794     case SPI_GETWHEELSCROLLLINES:
1795         ret = get_uint_param( SPI_SETMOUSESCROLLLINES_IDX,
1796                               SPI_SETMOUSESCROLLLINES_REGKEY,
1797                               SPI_SETMOUSESCROLLLINES_VALNAME,
1798                               &mouse_scroll_lines, pvParam );
1799         break;
1800
1801     case SPI_SETWHEELSCROLLLINES:
1802         ret = set_uint_param( SPI_SETMOUSESCROLLLINES_IDX,
1803                               SPI_SETMOUSESCROLLLINES_REGKEY,
1804                               SPI_SETMOUSESCROLLLINES_VALNAME,
1805                               &mouse_scroll_lines, uiParam, fWinIni );
1806         break;
1807
1808     case SPI_GETMENUSHOWDELAY:
1809         ret = get_uint_param( SPI_SETMENUSHOWDELAY_IDX,
1810                               SPI_SETMENUSHOWDELAY_REGKEY,
1811                               SPI_SETMENUSHOWDELAY_VALNAME,
1812                               &menu_show_delay, pvParam );
1813         break;
1814
1815     case SPI_SETMENUSHOWDELAY:
1816         ret = set_uint_param( SPI_SETMENUSHOWDELAY_IDX,
1817                               SPI_SETMENUSHOWDELAY_REGKEY,
1818                               SPI_SETMENUSHOWDELAY_VALNAME,
1819                               &menu_show_delay, uiParam, fWinIni );
1820         break;
1821
1822     WINE_SPI_FIXME(SPI_GETSHOWIMEUI);           /*    110  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1823     WINE_SPI_FIXME(SPI_SETSHOWIMEUI);           /*    111  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
1824     WINE_SPI_FIXME(SPI_GETMOUSESPEED);          /*    112  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1825     WINE_SPI_FIXME(SPI_SETMOUSESPEED);          /*    113  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1826
1827     case SPI_GETSCREENSAVERRUNNING:
1828         ret = get_bool_param( SPI_SETSCREENSAVERRUNNING_IDX,
1829                               SPI_SETSCREENSAVERRUNNING_REGKEY,
1830                               SPI_SETSCREENSAVERRUNNING_VALNAME,
1831                               &screensaver_running, pvParam );
1832         break;
1833
1834     case SPI_GETDESKWALLPAPER:                  /*    115  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1835     {
1836         WCHAR buf[MAX_PATH];
1837
1838         if (!pvParam) return FALSE;
1839
1840         if (uiParam > MAX_PATH)
1841         {
1842             uiParam = MAX_PATH;
1843         }
1844
1845         if (SYSPARAMS_Load(SPI_SETDESKWALLPAPER_REGKEY, SPI_SETDESKWALLPAPER_VALNAME, buf, sizeof(buf)))
1846         {
1847             lstrcpynW((WCHAR*)pvParam, buf, uiParam);
1848         }
1849         else
1850         {
1851             /* Return an empty string */
1852             memset((WCHAR*)pvParam, 0, uiParam);
1853         }
1854
1855         break;
1856     }
1857
1858     WINE_SPI_FIXME(SPI_GETACTIVEWINDOWTRACKING);/* 0x1000  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1859     WINE_SPI_FIXME(SPI_SETACTIVEWINDOWTRACKING);/* 0x1001  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1860     WINE_SPI_FIXME(SPI_GETMENUANIMATION);       /* 0x1002  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1861     WINE_SPI_FIXME(SPI_SETMENUANIMATION);       /* 0x1003  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1862     WINE_SPI_FIXME(SPI_GETCOMBOBOXANIMATION);   /* 0x1004  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1863     WINE_SPI_FIXME(SPI_SETCOMBOBOXANIMATION);   /* 0x1005  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1864
1865     case SPI_GETLISTBOXSMOOTHSCROLLING:    /* 0x1006  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1866         if (!pvParam) return FALSE;
1867
1868         spi_idx = SPI_SETLISTBOXSMOOTHSCROLLING_IDX;
1869         if (!spi_loaded[spi_idx])
1870         {
1871             WCHAR buf[5];
1872
1873             if (SYSPARAMS_Load( SPI_SETLISTBOXSMOOTHSCROLLING_REGKEY,
1874                                 SPI_SETLISTBOXSMOOTHSCROLLING_VALNAME, buf, sizeof(buf) ))
1875             {
1876                 if ((buf[0]&0x01) == 0x01)
1877                 {
1878                     listbox_smoothscrolling = TRUE;
1879                 }
1880             }
1881             spi_loaded[spi_idx] = TRUE;
1882         }
1883
1884         *(BOOL *)pvParam = listbox_smoothscrolling;
1885
1886         break;
1887
1888     WINE_SPI_FIXME(SPI_SETLISTBOXSMOOTHSCROLLING);/* 0x1007  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1889
1890     case SPI_GETGRADIENTCAPTIONS:
1891         ret = get_user_pref_param( 0, 0x10, pvParam );
1892         break;
1893
1894     case SPI_SETGRADIENTCAPTIONS:
1895         ret = set_user_pref_param( 0, 0x10, (BOOL)pvParam, fWinIni );
1896         break;
1897
1898     case SPI_GETKEYBOARDCUES:
1899         ret = get_user_pref_param( 0, 0x20, pvParam );
1900         break;
1901
1902     case SPI_SETKEYBOARDCUES:
1903         ret = set_user_pref_param( 0, 0x20, (BOOL)pvParam, fWinIni );
1904         break;
1905
1906     WINE_SPI_FIXME(SPI_GETACTIVEWNDTRKZORDER);  /* 0x100C  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1907     WINE_SPI_FIXME(SPI_SETACTIVEWNDTRKZORDER);  /* 0x100D  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1908     case SPI_GETHOTTRACKING:
1909         ret = get_user_pref_param( 0, 0x80, pvParam );
1910         break;
1911
1912     case SPI_SETHOTTRACKING:
1913         ret = set_user_pref_param( 0, 0x80, (BOOL)pvParam, fWinIni );
1914         break;
1915
1916     WINE_SPI_FIXME(SPI_GETMENUFADE);            /* 0x1012  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1917     WINE_SPI_FIXME(SPI_SETMENUFADE);            /* 0x1013  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1918     WINE_SPI_FIXME(SPI_GETSELECTIONFADE);       /* 0x1014  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1919     WINE_SPI_FIXME(SPI_SETSELECTIONFADE);       /* 0x1015  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1920     WINE_SPI_FIXME(SPI_GETTOOLTIPANIMATION);    /* 0x1016  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1921     WINE_SPI_FIXME(SPI_SETTOOLTIPANIMATION);    /* 0x1017  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1922     WINE_SPI_FIXME(SPI_GETTOOLTIPFADE);         /* 0x1018  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1923     WINE_SPI_FIXME(SPI_SETTOOLTIPFADE);         /* 0x1019  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1924     WINE_SPI_FIXME(SPI_GETCURSORSHADOW);        /* 0x101A  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1925     WINE_SPI_FIXME(SPI_SETCURSORSHADOW);        /* 0x101B  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1926     WINE_SPI_FIXME(SPI_GETMOUSESONAR);          /* 0x101C  _WIN32_WINNT >= 0x510 || _WIN32_WINDOW >= 0x490*/
1927     WINE_SPI_FIXME(SPI_SETMOUSESONAR);          /* 0x101D  _WIN32_WINNT >= 0x510 || _WIN32_WINDOW >= 0x490*/
1928     WINE_SPI_FIXME(SPI_GETMOUSECLICKLOCK);      /* 0x101E  _WIN32_WINNT >= 0x510 || _WIN32_WINDOW >= 0x490*/
1929     WINE_SPI_FIXME(SPI_SETMOUSECLICKLOCK);      /* 0x101F  _WIN32_WINNT >= 0x510 || _WIN32_WINDOW >= 0x490*/
1930     WINE_SPI_FIXME(SPI_GETMOUSEVANISH);         /* 0x1020  _WIN32_WINNT >= 0x510 || _WIN32_WINDOW >= 0x490*/
1931     WINE_SPI_FIXME(SPI_SETMOUSEVANISH);         /* 0x1021  _WIN32_WINNT >= 0x510 || _WIN32_WINDOW >= 0x490*/
1932     case SPI_GETFLATMENU:
1933         ret = get_user_pref_param( 2, 0x02, pvParam );
1934         break;
1935
1936     case SPI_SETFLATMENU:
1937         ret = set_user_pref_param( 2, 0x02, (BOOL)pvParam, fWinIni );
1938         break;
1939
1940     WINE_SPI_FIXME(SPI_GETDROPSHADOW);          /* 0x1024  _WIN32_WINNT >= 0x510 */
1941     WINE_SPI_FIXME(SPI_SETDROPSHADOW);          /* 0x1025  _WIN32_WINNT >= 0x510 */
1942     WINE_SPI_FIXME(SPI_GETBLOCKSENDINPUTRESETS);
1943     WINE_SPI_FIXME(SPI_SETBLOCKSENDINPUTRESETS);
1944     WINE_SPI_FIXME(SPI_GETUIEFFECTS);
1945     WINE_SPI_FIXME(SPI_SETUIEFFECTS);
1946     WINE_SPI_FIXME(SPI_GETFOREGROUNDLOCKTIMEOUT);/* 0x2000  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1947     WINE_SPI_FIXME(SPI_SETFOREGROUNDLOCKTIMEOUT);/* 0x2001  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1948     WINE_SPI_FIXME(SPI_GETACTIVEWNDTRKTIMEOUT); /* 0x2002  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1949     WINE_SPI_FIXME(SPI_SETACTIVEWNDTRKTIMEOUT); /* 0x2003  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1950     WINE_SPI_FIXME(SPI_GETFOREGROUNDFLASHCOUNT);/* 0x2004  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1951     WINE_SPI_FIXME(SPI_SETFOREGROUNDFLASHCOUNT);/* 0x2005  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1952     WINE_SPI_FIXME(SPI_GETCARETWIDTH);          /* 0x2006  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1953     WINE_SPI_FIXME(SPI_SETCARETWIDTH);          /* 0x2007  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1954     WINE_SPI_FIXME(SPI_GETMOUSECLICKLOCKTIME);  /* 0x2008  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1955     WINE_SPI_FIXME(SPI_SETMOUSECLICKLOCKTIME);  /* 0x2009  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1956     WINE_SPI_FIXME(SPI_GETFONTSMOOTHINGTYPE);   /* 0x200A  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1957     WINE_SPI_FIXME(SPI_SETFONTSMOOTHINGTYPE);   /* 0x200B  _WIN32_WINNT >= 0x500 || _WIN32_WINDOW > 0x400 */
1958     WINE_SPI_FIXME(SPI_GETFONTSMOOTHINGCONTRAST);/* 0x200C  _WIN32_WINNT >= 0x510 */
1959     WINE_SPI_FIXME(SPI_SETFONTSMOOTHINGCONTRAST);/* 0x200D  _WIN32_WINNT >= 0x510 */
1960     WINE_SPI_FIXME(SPI_GETFOCUSBORDERWIDTH);    /* 0x200E  _WIN32_WINNT >= 0x510 */
1961     WINE_SPI_FIXME(SPI_SETFOCUSBORDERWIDTH);    /* 0x200F  _WIN32_WINNT >= 0x510 */
1962     WINE_SPI_FIXME(SPI_GETFOCUSBORDERHEIGHT);    /* 0x2010  _WIN32_WINNT >= 0x510 */
1963     WINE_SPI_FIXME(SPI_SETFOCUSBORDERHEIGHT);    /* 0x2011  _WIN32_WINNT >= 0x510 */
1964
1965     default:
1966         FIXME( "Unknown action: %u\n", uiAction );
1967         SetLastError( ERROR_INVALID_SPI_VALUE );
1968         ret = FALSE;
1969         break;
1970     }
1971
1972     if (ret)
1973         SYSPARAMS_NotifyChange( uiAction, fWinIni );
1974     return ret;
1975
1976 #undef WINE_SPI_FIXME
1977 #undef WINE_SPI_WARN
1978 }
1979
1980
1981 /***********************************************************************
1982  *              SystemParametersInfo (USER.483)
1983  */
1984 BOOL16 WINAPI SystemParametersInfo16( UINT16 uAction, UINT16 uParam,
1985                                       LPVOID lpvParam, UINT16 fuWinIni )
1986 {
1987     BOOL16 ret;
1988
1989     TRACE("(%u, %u, %p, %u)\n", uAction, uParam, lpvParam, fuWinIni);
1990
1991     switch (uAction)
1992     {
1993     case SPI_GETBEEP:                           /*      1 */
1994     case SPI_GETSCREENSAVEACTIVE:               /*     16 */
1995     case SPI_GETICONTITLEWRAP:                  /*     25 */
1996     case SPI_GETMENUDROPALIGNMENT:              /*     27 */
1997     case SPI_GETFASTTASKSWITCH:                 /*     35 */
1998     case SPI_GETDRAGFULLWINDOWS:                /*     38  WINVER >= 0x0400 */
1999     {
2000         BOOL tmp;
2001         ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
2002         if (ret && lpvParam)
2003             *(BOOL16 *)lpvParam = tmp;
2004         break;
2005     }
2006
2007     case SPI_GETBORDER:                         /*      5 */
2008     case SPI_ICONHORIZONTALSPACING:             /*     13 */
2009     case SPI_GETSCREENSAVETIMEOUT:              /*     14 */
2010     case SPI_GETGRIDGRANULARITY:                /*     18 */
2011     case SPI_GETKEYBOARDDELAY:                  /*     22 */
2012     case SPI_ICONVERTICALSPACING:               /*     24 */
2013     {
2014         INT tmp;
2015         ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
2016         if (ret && lpvParam)
2017             *(INT16 *)lpvParam = tmp;
2018         break;
2019     }
2020
2021     case SPI_GETKEYBOARDSPEED:                  /*     10 */
2022     {
2023         DWORD tmp;
2024         ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
2025         if (ret && lpvParam)
2026             *(WORD *)lpvParam = tmp;
2027         break;
2028     }
2029
2030     case SPI_GETICONTITLELOGFONT:               /*     31 */
2031     {
2032         LOGFONTA tmp;
2033         ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
2034         if (ret && lpvParam)
2035             SYSPARAMS_LogFont32ATo16( &tmp, (LPLOGFONT16)lpvParam );
2036         break;
2037     }
2038
2039     case SPI_GETNONCLIENTMETRICS:               /*     41  WINVER >= 0x400 */
2040     {
2041         NONCLIENTMETRICSA tmp;
2042         LPNONCLIENTMETRICS16 lpnm16 = (LPNONCLIENTMETRICS16)lpvParam;
2043         if (lpnm16 && lpnm16->cbSize == sizeof(NONCLIENTMETRICS16))
2044         {
2045             tmp.cbSize = sizeof(NONCLIENTMETRICSA);
2046             ret = SystemParametersInfoA( uAction, uParam, &tmp, fuWinIni );
2047             if (ret)
2048                 SYSPARAMS_NonClientMetrics32ATo16( &tmp, lpnm16 );
2049         }
2050         else /* winfile 95 sets cbSize to 340 */
2051             ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
2052         break;
2053     }
2054
2055     case SPI_GETWORKAREA:                       /*     48  WINVER >= 0x400 */
2056     {
2057         RECT tmp;
2058         ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
2059         if (ret && lpvParam)
2060         {
2061             RECT16 *r16 = (RECT16 *)lpvParam;
2062             r16->left   = tmp.left;
2063             r16->top    = tmp.top;
2064             r16->right  = tmp.right;
2065             r16->bottom = tmp.bottom;
2066         }
2067         break;
2068     }
2069
2070     case SPI_GETMOUSEHOVERWIDTH:                /*     98  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
2071     case SPI_GETMOUSEHOVERHEIGHT:               /*    100  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
2072     case SPI_GETMOUSEHOVERTIME:                 /*    102  _WIN32_WINNT >= 0x400 || _WIN32_WINDOW > 0x400 */
2073     {
2074         UINT tmp;
2075         ret = SystemParametersInfoA( uAction, uParam, lpvParam ? &tmp : NULL, fuWinIni );
2076         if (ret && lpvParam)
2077             *(UINT16 *)lpvParam = tmp;
2078         break;
2079     }
2080
2081     default:
2082         ret = SystemParametersInfoA( uAction, uParam, lpvParam, fuWinIni );
2083     }
2084
2085     return ret;
2086 }
2087
2088 /***********************************************************************
2089  *              SystemParametersInfoA (USER32.@)
2090  */
2091 BOOL WINAPI SystemParametersInfoA( UINT uiAction, UINT uiParam,
2092                                    PVOID pvParam, UINT fuWinIni )
2093 {
2094     BOOL ret;
2095
2096     TRACE("(%u, %u, %p, %u)\n", uiAction, uiParam, pvParam, fuWinIni);
2097
2098     switch (uiAction)
2099     {
2100     case SPI_SETDESKWALLPAPER:                  /*     20 */
2101     case SPI_SETDESKPATTERN:                    /*     21 */
2102     {
2103         WCHAR buffer[256];
2104         if (pvParam)
2105             if (!MultiByteToWideChar( CP_ACP, 0, (LPSTR)pvParam, -1,
2106                                       buffer, sizeof(buffer)/sizeof(WCHAR) ))
2107                 buffer[sizeof(buffer)/sizeof(WCHAR)-1] = 0;
2108         ret = SystemParametersInfoW( uiAction, uiParam, pvParam ? buffer : NULL, fuWinIni );
2109         break;
2110     }
2111
2112     case SPI_GETICONTITLELOGFONT:               /*     31 */
2113     {
2114         LOGFONTW tmp;
2115         ret = SystemParametersInfoW( uiAction, uiParam, pvParam ? &tmp : NULL, fuWinIni );
2116         if (ret && pvParam)
2117             SYSPARAMS_LogFont32WTo32A( &tmp, (LPLOGFONTA)pvParam );
2118         break;
2119     }
2120
2121     case SPI_GETNONCLIENTMETRICS:               /*     41  WINVER >= 0x400 */
2122     {
2123         NONCLIENTMETRICSW tmp;
2124         LPNONCLIENTMETRICSA lpnmA = (LPNONCLIENTMETRICSA)pvParam;
2125         if (lpnmA && lpnmA->cbSize == sizeof(NONCLIENTMETRICSA))
2126         {
2127             tmp.cbSize = sizeof(NONCLIENTMETRICSW);
2128             ret = SystemParametersInfoW( uiAction, uiParam, &tmp, fuWinIni );
2129             if (ret)
2130                 SYSPARAMS_NonClientMetrics32WTo32A( &tmp, lpnmA );
2131         }
2132         else
2133             ret = FALSE;
2134         break;
2135     }
2136
2137     case SPI_GETICONMETRICS:                    /*     45  WINVER >= 0x400 */
2138     {
2139         ICONMETRICSW tmp;
2140         LPICONMETRICSA lpimA = (LPICONMETRICSA)pvParam;
2141         if (lpimA && lpimA->cbSize == sizeof(ICONMETRICSA))
2142         {
2143             tmp.cbSize = sizeof(ICONMETRICSW);
2144             ret = SystemParametersInfoW( uiAction, uiParam, &tmp, fuWinIni );
2145             if (ret)
2146             {
2147                 lpimA->iHorzSpacing = tmp.iHorzSpacing;
2148                 lpimA->iVertSpacing = tmp.iVertSpacing;
2149                 lpimA->iTitleWrap   = tmp.iTitleWrap;
2150                 SYSPARAMS_LogFont32WTo32A( &tmp.lfFont, &lpimA->lfFont );
2151             }
2152         }
2153         else
2154             ret = FALSE;
2155         break;
2156     }
2157
2158     case SPI_SETICONMETRICS:                    /*     46  WINVER >= 0x400 */
2159     {
2160         ICONMETRICSW tmp;
2161         LPICONMETRICSA lpimA = (LPICONMETRICSA)pvParam;
2162         if (lpimA && lpimA->cbSize == sizeof(ICONMETRICSA))
2163         {
2164             tmp.cbSize = sizeof(ICONMETRICSW);
2165             ret = SystemParametersInfoW( uiAction, uiParam, &tmp, fuWinIni );
2166             if (ret)
2167             {
2168                 lpimA->iHorzSpacing = tmp.iHorzSpacing;
2169                 lpimA->iVertSpacing = tmp.iVertSpacing;
2170                 lpimA->iTitleWrap   = tmp.iTitleWrap;
2171                 SYSPARAMS_LogFont32WTo32A( &tmp.lfFont, &lpimA->lfFont );
2172             }
2173         }
2174         else
2175             ret = FALSE;
2176         break;
2177     }
2178
2179     case SPI_GETHIGHCONTRAST:                   /*     66  WINVER >= 0x400 */
2180     {
2181         HIGHCONTRASTW tmp;
2182         LPHIGHCONTRASTA lphcA = (LPHIGHCONTRASTA)pvParam;
2183         if (lphcA && lphcA->cbSize == sizeof(HIGHCONTRASTA))
2184         {
2185             tmp.cbSize = sizeof(HIGHCONTRASTW);
2186             ret = SystemParametersInfoW( uiAction, uiParam, &tmp, fuWinIni );
2187             if (ret)
2188             {
2189                 lphcA->dwFlags = tmp.dwFlags;
2190                 lphcA->lpszDefaultScheme = NULL;  /* FIXME? */
2191             }
2192         }
2193         else
2194             ret = FALSE;
2195         break;
2196     }
2197
2198     default:
2199         ret = SystemParametersInfoW( uiAction, uiParam, pvParam, fuWinIni );
2200         break;
2201     }
2202     return ret;
2203 }
2204
2205
2206 /***********************************************************************
2207  *              GetSystemMetrics (USER32.@)
2208  */
2209 INT WINAPI GetSystemMetrics( INT index )
2210 {
2211     UINT ret;
2212
2213     /* some metrics are dynamic */
2214     switch (index)
2215     {
2216     case SM_CXSCREEN:
2217         return GetDeviceCaps( get_display_dc(), HORZRES );
2218     case SM_CYSCREEN:
2219         return GetDeviceCaps( get_display_dc(), VERTRES );
2220     case SM_CXVSCROLL:
2221         if (!spi_loaded[SPI_NONCLIENTMETRICS_IDX]) load_nonclient_metrics();
2222         return nonclient_metrics.iScrollWidth;
2223     case SM_CYHSCROLL:
2224         if (!spi_loaded[SPI_NONCLIENTMETRICS_IDX]) load_nonclient_metrics();
2225         return nonclient_metrics.iScrollHeight;
2226     case SM_CYCAPTION:
2227         if (!spi_loaded[SPI_NONCLIENTMETRICS_IDX]) load_nonclient_metrics();
2228         return nonclient_metrics.iCaptionHeight + 1; /* for the separator? */
2229     case SM_CXBORDER:
2230     case SM_CYBORDER:
2231         /* SM_C{X,Y}BORDER always returns 1 regardless of 'BorderWidth' value in registry */
2232         return 1;
2233     case SM_CXDLGFRAME:
2234     case SM_CYDLGFRAME:
2235         return 3;
2236     case SM_CYVTHUMB:
2237         return GetSystemMetrics(SM_CXVSCROLL);
2238     case SM_CXHTHUMB:
2239         return GetSystemMetrics(SM_CYHSCROLL);
2240     case SM_CXICON:
2241         if (!spi_loaded[SPI_NONCLIENTMETRICS_IDX]) load_nonclient_metrics();
2242         return icon_size.cx;
2243     case SM_CYICON:
2244         if (!spi_loaded[SPI_NONCLIENTMETRICS_IDX]) load_nonclient_metrics();
2245         return icon_size.cy;
2246     case SM_CXCURSOR:
2247     case SM_CYCURSOR:
2248         return 32;
2249     case SM_CYMENU:
2250         return GetSystemMetrics(SM_CYMENUSIZE) + 1;
2251     case SM_CXFULLSCREEN:
2252         return GetSystemMetrics(SM_CXSCREEN);
2253     case SM_CYFULLSCREEN:
2254         return GetSystemMetrics(SM_CYSCREEN) - GetSystemMetrics(SM_CYCAPTION);
2255     case SM_CYKANJIWINDOW:
2256         return 0;
2257     case SM_MOUSEPRESENT:
2258         return 1;
2259     case SM_CYVSCROLL:
2260         if (!spi_loaded[SPI_NONCLIENTMETRICS_IDX]) load_nonclient_metrics();
2261         return scroll_height.cy;
2262     case SM_CXHSCROLL:
2263         if (!spi_loaded[SPI_NONCLIENTMETRICS_IDX]) load_nonclient_metrics();
2264         return scroll_height.cx;
2265     case SM_DEBUG:
2266         return 0;
2267     case SM_SWAPBUTTON:
2268         get_uint_param( SPI_SETMOUSEBUTTONSWAP_IDX, SPI_SETMOUSEBUTTONSWAP_REGKEY,
2269                         SPI_SETMOUSEBUTTONSWAP_VALNAME, &swap_buttons, &ret );
2270         return ret;
2271     case SM_RESERVED1:
2272     case SM_RESERVED2:
2273     case SM_RESERVED3:
2274     case SM_RESERVED4:
2275         return 0;
2276     case SM_CXMIN:
2277         return 112;  /* FIXME */
2278     case SM_CYMIN:
2279         return 27;  /* FIXME */
2280     case SM_CXSIZE:
2281         if (!spi_loaded[SPI_NONCLIENTMETRICS_IDX]) load_nonclient_metrics();
2282         return nonclient_metrics.iCaptionWidth;
2283     case SM_CYSIZE:
2284         if (!spi_loaded[SPI_NONCLIENTMETRICS_IDX]) load_nonclient_metrics();
2285         return nonclient_metrics.iCaptionHeight;
2286     case SM_CXFRAME:
2287         SystemParametersInfoW( SPI_GETBORDER, 0, &ret, 0 );
2288         return GetSystemMetrics(SM_CXDLGFRAME) + ret;
2289     case SM_CYFRAME:
2290         SystemParametersInfoW( SPI_GETBORDER, 0, &ret, 0 );
2291         return GetSystemMetrics(SM_CYDLGFRAME) + ret;
2292     case SM_CXMINTRACK:
2293         return GetSystemMetrics(SM_CXMIN);
2294     case SM_CYMINTRACK:
2295         return GetSystemMetrics(SM_CYMIN);
2296     case SM_CXDOUBLECLK:
2297         get_uint_param( SPI_SETDOUBLECLKWIDTH_IDX, SPI_SETDOUBLECLKWIDTH_REGKEY1,
2298                         SPI_SETDOUBLECLKWIDTH_VALNAME, &double_click_width, &ret );
2299         return ret;
2300     case SM_CYDOUBLECLK:
2301         get_uint_param( SPI_SETDOUBLECLKHEIGHT_IDX, SPI_SETDOUBLECLKHEIGHT_REGKEY1,
2302                         SPI_SETDOUBLECLKHEIGHT_VALNAME, &double_click_height, &ret );
2303         return ret;
2304     case SM_CXICONSPACING:
2305         SystemParametersInfoW( SPI_ICONHORIZONTALSPACING, 0, &ret, 0 );
2306         return ret;
2307     case SM_CYICONSPACING:
2308         SystemParametersInfoW( SPI_ICONVERTICALSPACING, 0, &ret, 0 );
2309         return ret;
2310     case SM_MENUDROPALIGNMENT:
2311         SystemParametersInfoW( SPI_GETMENUDROPALIGNMENT, 0, &ret, 0 );
2312         return ret;
2313     case SM_PENWINDOWS:
2314         return 0;
2315     case SM_DBCSENABLED:
2316     {
2317         CPINFO cpinfo;
2318         GetCPInfo( CP_ACP, &cpinfo );
2319         return (cpinfo.MaxCharSize > 1);
2320     }
2321     case SM_CMOUSEBUTTONS:
2322         return 3;
2323     case SM_SECURE:
2324         return 0;
2325     case SM_CXEDGE:
2326         return GetSystemMetrics(SM_CXBORDER) + 1;
2327     case SM_CYEDGE:
2328         return GetSystemMetrics(SM_CYBORDER) + 1;
2329     case SM_CXMINSPACING:
2330         return GetSystemMetrics(SM_CXMINIMIZED) + minimized_metrics.iHorzGap;
2331     case SM_CYMINSPACING:
2332         return GetSystemMetrics(SM_CYMINIMIZED) + minimized_metrics.iVertGap;
2333     case SM_CXSMICON:
2334     case SM_CYSMICON:
2335         return 16;
2336     case SM_CYSMCAPTION:
2337         return GetSystemMetrics(SM_CYSMSIZE) + 1;
2338     case SM_CXSMSIZE:
2339         if (!spi_loaded[SPI_NONCLIENTMETRICS_IDX]) load_nonclient_metrics();
2340         return nonclient_metrics.iSmCaptionWidth;
2341     case SM_CYSMSIZE:
2342         if (!spi_loaded[SPI_NONCLIENTMETRICS_IDX]) load_nonclient_metrics();
2343         return nonclient_metrics.iSmCaptionHeight;
2344     case SM_CXMENUSIZE:
2345         if (!spi_loaded[SPI_NONCLIENTMETRICS_IDX]) load_nonclient_metrics();
2346         return nonclient_metrics.iMenuWidth;
2347     case SM_CYMENUSIZE:
2348         if (!spi_loaded[SPI_NONCLIENTMETRICS_IDX]) load_nonclient_metrics();
2349         return nonclient_metrics.iMenuHeight;
2350     case SM_ARRANGE:
2351         return minimized_metrics.iArrange;
2352     case SM_CXMINIMIZED:
2353         return minimized_metrics.iWidth + 6;
2354     case SM_CYMINIMIZED:
2355         return 24;  /* FIXME */
2356     case SM_CXMAXTRACK:
2357         return GetSystemMetrics(SM_CXSCREEN) + 4 + 2 * GetSystemMetrics(SM_CXFRAME);
2358     case SM_CYMAXTRACK:
2359         return GetSystemMetrics(SM_CYSCREEN) + 4 + 2 * GetSystemMetrics(SM_CYFRAME);
2360     case SM_CXMAXIMIZED:
2361         return GetSystemMetrics(SM_CXSCREEN) + 2 * GetSystemMetrics(SM_CXFRAME);
2362     case SM_CYMAXIMIZED:
2363         return GetSystemMetrics(SM_CYSCREEN) + 2 * GetSystemMetrics(SM_CYFRAME);
2364     case SM_NETWORK:
2365         return 3;  /* FIXME */
2366     case SM_CLEANBOOT:
2367         return 0; /* 0 = ok, 1 = failsafe, 2 = failsafe + network */
2368     case SM_CXDRAG:
2369     case SM_CYDRAG:
2370         return 4;
2371     case SM_SHOWSOUNDS:
2372         SystemParametersInfoW( SPI_GETSHOWSOUNDS, 0, &ret, 0 );
2373         return ret;
2374     case SM_CXMENUCHECK:
2375     case SM_CYMENUCHECK:
2376         return 13;
2377     case SM_SLOWMACHINE:
2378         return 0;  /* FIXME: Should check the type of processor */
2379     case SM_MIDEASTENABLED:
2380         return 0;  /* FIXME */
2381     case SM_MOUSEWHEELPRESENT:
2382         return 1;
2383     case SM_XVIRTUALSCREEN:
2384     case SM_YVIRTUALSCREEN:
2385         return 0;
2386     case SM_CXVIRTUALSCREEN:
2387         return GetSystemMetrics(SM_CXSCREEN);
2388     case SM_CYVIRTUALSCREEN:
2389         return GetSystemMetrics(SM_CYSCREEN);
2390     case SM_CMONITORS:
2391         return 1;
2392     case SM_SAMEDISPLAYFORMAT:
2393         return 1;
2394     case SM_IMMENABLED:
2395         return 0;  /* FIXME */
2396     case SM_CXFOCUSBORDER:
2397     case SM_CYFOCUSBORDER:
2398         return 1;
2399     case SM_TABLETPC:
2400     case SM_MEDIACENTER:
2401         return 0;
2402     case SM_CMETRICS:
2403         return SM_CMETRICS;
2404     default:
2405         return 0;
2406     }
2407 }
2408
2409
2410 /***********************************************************************
2411  *              SwapMouseButton (USER32.@)
2412  */
2413 BOOL WINAPI SwapMouseButton( BOOL fSwap )
2414 {
2415     return SystemParametersInfoW(SPI_SETMOUSEBUTTONSWAP, fSwap, 0, 0);
2416 }
2417
2418
2419 /**********************************************************************
2420  *              SetDoubleClickTime (USER32.@)
2421  */
2422 BOOL WINAPI SetDoubleClickTime( UINT interval )
2423 {
2424     return SystemParametersInfoW(SPI_SETDOUBLECLICKTIME, interval, 0, 0);
2425 }
2426
2427
2428 /**********************************************************************
2429  *              GetDoubleClickTime (USER32.@)
2430  */
2431 UINT WINAPI GetDoubleClickTime(void)
2432 {
2433     UINT time = 0;
2434
2435     get_uint_param( SPI_SETDOUBLECLICKTIME_IDX,
2436                     SPI_SETDOUBLECLICKTIME_REGKEY,
2437                     SPI_SETDOUBLECLICKTIME_VALNAME,
2438                     &double_click_time, &time );
2439     if (!time) time = 500;
2440     return time;
2441 }
2442
2443
2444 /*************************************************************************
2445  *              GetSysColor (USER32.@)
2446  */
2447 COLORREF WINAPI GetSysColor( INT nIndex )
2448 {
2449     if (nIndex >= 0 && nIndex < NUM_SYS_COLORS)
2450         return SysColors[nIndex];
2451     else
2452         return 0;
2453 }
2454
2455
2456 /*************************************************************************
2457  *              SetSysColors (USER32.@)
2458  */
2459 BOOL WINAPI SetSysColors( INT nChanges, const INT *lpSysColor,
2460                               const COLORREF *lpColorValues )
2461 {
2462     int i;
2463
2464     for (i = 0; i < nChanges; i++) SYSPARAMS_SetSysColor( lpSysColor[i], lpColorValues[i] );
2465
2466     /* Send WM_SYSCOLORCHANGE message to all windows */
2467
2468     SendMessageTimeoutW( HWND_BROADCAST, WM_SYSCOLORCHANGE, 0, 0, SMTO_ABORTIFHUNG, 2000, NULL );
2469
2470     /* Repaint affected portions of all visible windows */
2471
2472     RedrawWindow( GetDesktopWindow(), NULL, 0,
2473                 RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ALLCHILDREN );
2474     return TRUE;
2475 }
2476
2477
2478 /*************************************************************************
2479  *              SetSysColorsTemp (USER32.@)
2480  *
2481  * UNDOCUMENTED !!
2482  *
2483  * Called by W98SE desk.cpl Control Panel Applet:
2484  * handle = SetSysColorsTemp(ptr, ptr, nCount);     ("set" call)
2485  * result = SetSysColorsTemp(NULL, NULL, handle);   ("restore" call)
2486  *
2487  * pPens is an array of COLORREF values, which seems to be used
2488  * to indicate the color values to create new pens with.
2489  *
2490  * pBrushes is an array of solid brush handles (returned by a previous
2491  * CreateSolidBrush), which seems to contain the brush handles to set
2492  * for the system colors.
2493  *
2494  * n seems to be used for
2495  *   a) indicating the number of entries to operate on (length of pPens,
2496  *      pBrushes)
2497  *   b) passing the handle that points to the previously used color settings.
2498  *      I couldn't figure out in hell what kind of handle this is on
2499  *      Windows. I just use a heap handle instead. Shouldn't matter anyway.
2500  *
2501  * RETURNS
2502  *     heap handle of our own copy of the current syscolors in case of
2503  *                 "set" call, i.e. pPens, pBrushes != NULL.
2504  *     TRUE (unconditionally !) in case of "restore" call,
2505  *          i.e. pPens, pBrushes == NULL.
2506  *     FALSE in case of either pPens != NULL and pBrushes == NULL
2507  *          or pPens == NULL and pBrushes != NULL.
2508  *
2509  * I'm not sure whether this implementation is 100% correct. [AM]
2510  */
2511 DWORD WINAPI SetSysColorsTemp( const COLORREF *pPens, const HBRUSH *pBrushes, DWORD n)
2512 {
2513     int i;
2514
2515     if (pPens && pBrushes) /* "set" call */
2516     {
2517         /* allocate our structure to remember old colors */
2518         LPVOID pOldCol = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD)+n*sizeof(HPEN)+n*sizeof(HBRUSH));
2519         LPVOID p = pOldCol;
2520         *(DWORD *)p = n; p = (char*)p + sizeof(DWORD);
2521         memcpy(p, SysColorPens, n*sizeof(HPEN)); p = (char*)p + n*sizeof(HPEN);
2522         memcpy(p, SysColorBrushes, n*sizeof(HBRUSH)); p = (char*)p + n*sizeof(HBRUSH);
2523
2524         for (i=0; i < n; i++)
2525         {
2526             SysColorPens[i] = CreatePen( PS_SOLID, 1, pPens[i] );
2527             SysColorBrushes[i] = pBrushes[i];
2528         }
2529
2530         return (DWORD)pOldCol;
2531     }
2532     if (!pPens && !pBrushes) /* "restore" call */
2533     {
2534         LPVOID pOldCol = (LPVOID)n;
2535         LPVOID p = pOldCol;
2536         DWORD nCount = *(DWORD *)p;
2537         p = (char*)p + sizeof(DWORD);
2538
2539         for (i=0; i < nCount; i++)
2540         {
2541             DeleteObject(SysColorPens[i]);
2542             SysColorPens[i] = *(HPEN *)p; p = (char*)p + sizeof(HPEN);
2543         }
2544         for (i=0; i < nCount; i++)
2545         {
2546             SysColorBrushes[i] = *(HBRUSH *)p; p = (char*)p + sizeof(HBRUSH);
2547         }
2548         /* get rid of storage structure */
2549         HeapFree(GetProcessHeap(), 0, pOldCol);
2550
2551         return TRUE;
2552     }
2553     return FALSE;
2554 }
2555
2556
2557 /***********************************************************************
2558  *              GetSysColorBrush (USER32.@)
2559  */
2560 HBRUSH WINAPI GetSysColorBrush( INT index )
2561 {
2562     if (0 <= index && index < NUM_SYS_COLORS) return SysColorBrushes[index];
2563     WARN("Unknown index(%d)\n", index );
2564     return GetStockObject(LTGRAY_BRUSH);
2565 }
2566
2567
2568 /***********************************************************************
2569  *              SYSCOLOR_GetPen
2570  */
2571 HPEN SYSCOLOR_GetPen( INT index )
2572 {
2573     /* We can assert here, because this function is internal to Wine */
2574     assert (0 <= index && index < NUM_SYS_COLORS);
2575     return SysColorPens[index];
2576 }
2577
2578
2579 /***********************************************************************
2580  *              ChangeDisplaySettingsA (USER32.@)
2581  */
2582 LONG WINAPI ChangeDisplaySettingsA( LPDEVMODEA devmode, DWORD flags )
2583 {
2584     return ChangeDisplaySettingsExA(NULL,devmode,NULL,flags,NULL);
2585 }
2586
2587
2588 /***********************************************************************
2589  *              ChangeDisplaySettingsW (USER32.@)
2590  */
2591 LONG WINAPI ChangeDisplaySettingsW( LPDEVMODEW devmode, DWORD flags )
2592 {
2593     return ChangeDisplaySettingsExW(NULL,devmode,NULL,flags,NULL);
2594 }
2595
2596
2597 /***********************************************************************
2598  *              ChangeDisplaySettingsExA (USER32.@)
2599  */
2600 LONG WINAPI ChangeDisplaySettingsExA( LPCSTR devname, LPDEVMODEA devmode, HWND hwnd,
2601                                       DWORD flags, LPVOID lparam )
2602 {
2603     DEVMODEW devmodeW;
2604     LONG ret;
2605     UNICODE_STRING nameW;
2606
2607     if (devname) RtlCreateUnicodeStringFromAsciiz(&nameW, devname);
2608     else nameW.Buffer = NULL;
2609
2610     if (devmode)
2611     {
2612         devmodeW.dmBitsPerPel       = devmode->dmBitsPerPel;
2613         devmodeW.dmPelsHeight       = devmode->dmPelsHeight;
2614         devmodeW.dmPelsWidth        = devmode->dmPelsWidth;
2615         devmodeW.dmDisplayFlags     = devmode->dmDisplayFlags;
2616         devmodeW.dmDisplayFrequency = devmode->dmDisplayFrequency;
2617         devmodeW.dmFields           = devmode->dmFields;
2618         ret = ChangeDisplaySettingsExW(nameW.Buffer, &devmodeW, hwnd, flags, lparam);
2619     }
2620     else
2621     {
2622         ret = ChangeDisplaySettingsExW(nameW.Buffer, NULL, hwnd, flags, lparam);
2623     }
2624
2625     if (devname) RtlFreeUnicodeString(&nameW);
2626     return ret;
2627 }
2628
2629
2630 /***********************************************************************
2631  *              ChangeDisplaySettingsExW (USER32.@)
2632  */
2633 LONG WINAPI ChangeDisplaySettingsExW( LPCWSTR devname, LPDEVMODEW devmode, HWND hwnd,
2634                                       DWORD flags, LPVOID lparam )
2635 {
2636     /* Pass the request on to the driver */
2637     if (!USER_Driver.pChangeDisplaySettingsEx) return DISP_CHANGE_FAILED;
2638     return USER_Driver.pChangeDisplaySettingsEx( devname, devmode, hwnd, flags, lparam );
2639 }
2640
2641
2642 /***********************************************************************
2643  *              EnumDisplaySettingsW (USER32.@)
2644  *
2645  * RETURNS
2646  *      TRUE if nth setting exists found (described in the LPDEVMODEW struct)
2647  *      FALSE if we do not have the nth setting
2648  */
2649 BOOL WINAPI EnumDisplaySettingsW( LPCWSTR name, DWORD n, LPDEVMODEW devmode )
2650 {
2651     return EnumDisplaySettingsExW(name, n, devmode, 0);
2652 }
2653
2654
2655 /***********************************************************************
2656  *              EnumDisplaySettingsA (USER32.@)
2657  */
2658 BOOL WINAPI EnumDisplaySettingsA(LPCSTR name,DWORD n,LPDEVMODEA devmode)
2659 {
2660     return EnumDisplaySettingsExA(name, n, devmode, 0);
2661 }
2662
2663
2664 /***********************************************************************
2665  *              EnumDisplaySettingsExA (USER32.@)
2666  */
2667 BOOL WINAPI EnumDisplaySettingsExA(LPCSTR lpszDeviceName, DWORD iModeNum,
2668                                    LPDEVMODEA lpDevMode, DWORD dwFlags)
2669 {
2670     DEVMODEW devmodeW;
2671     BOOL ret;
2672     UNICODE_STRING nameW;
2673
2674     if (lpszDeviceName) RtlCreateUnicodeStringFromAsciiz(&nameW, lpszDeviceName);
2675     else nameW.Buffer = NULL;
2676
2677     ret = EnumDisplaySettingsExW(nameW.Buffer,iModeNum,&devmodeW,dwFlags);
2678     if (ret)
2679     {
2680         lpDevMode->dmBitsPerPel       = devmodeW.dmBitsPerPel;
2681         lpDevMode->dmPelsHeight       = devmodeW.dmPelsHeight;
2682         lpDevMode->dmPelsWidth        = devmodeW.dmPelsWidth;
2683         lpDevMode->dmDisplayFlags     = devmodeW.dmDisplayFlags;
2684         lpDevMode->dmDisplayFrequency = devmodeW.dmDisplayFrequency;
2685         lpDevMode->dmFields           = devmodeW.dmFields;
2686     }
2687     if (lpszDeviceName) RtlFreeUnicodeString(&nameW);
2688     return ret;
2689 }
2690
2691
2692 /***********************************************************************
2693  *              EnumDisplaySettingsExW (USER32.@)
2694  */
2695 BOOL WINAPI EnumDisplaySettingsExW(LPCWSTR lpszDeviceName, DWORD iModeNum,
2696                                    LPDEVMODEW lpDevMode, DWORD dwFlags)
2697 {
2698     /* Pass the request on to the driver */
2699     if (!USER_Driver.pEnumDisplaySettingsEx) return FALSE;
2700     return USER_Driver.pEnumDisplaySettingsEx(lpszDeviceName, iModeNum, lpDevMode, dwFlags);
2701 }