~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/user32/tests/sysparams.c

Version: ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~ [ wine-1.0-rc5 ] ~ [ wine-1.0-rc4 ] ~ [ wine-1.0-rc3 ] ~ [ wine-1.0-rc2 ] ~ [ wine-1.0-rc1 ] ~ [ wine-0.9.61 ] ~ [ wine-0.9.60 ] ~ [ wine-0.9.59 ] ~ [ wine-0.9.58 ] ~ [ wine-0.9.57 ] ~ [ wine-0.9.56 ] ~ [ wine-0.9.55 ] ~ [ wine-0.9.54 ] ~ [ wine-0.9.53 ] ~ [ wine-0.9.52 ] ~ [ wine-0.9.51 ] ~ [ wine-0.9.50 ] ~ [ wine-0.9.49 ] ~ [ wine-0.9.48 ] ~ [ wine-0.9.47 ] ~ [ wine-0.9.46 ] ~ [ wine-0.9.45 ] ~ [ wine-0.9.44 ] ~ [ wine-0.9.43 ] ~ [ wine-0.9.42 ] ~ [ wine-0.9.41 ] ~ [ wine-0.9.40 ] ~ [ wine-0.9.39 ] ~ [ wine-0.9.38 ] ~ [ wine-0.9.37 ] ~ [ wine-0.9.36 ] ~ [ wine-0.9.35 ] ~ [ wine-0.9.34 ] ~ [ wine-0.9.33 ] ~ [ wine-0.9.32 ] ~ [ wine-0.9.31 ] ~ [ wine-0.9.30 ] ~ [ wine-0.9.29 ] ~ [ wine-0.9.28 ] ~ [ wine-0.9.27 ] ~ [ wine-0.9.26 ] ~ [ wine-0.9.25 ] ~ [ wine-0.9.24 ] ~ [ wine-0.9.23 ] ~ [ wine-0.9.22 ] ~ [ wine-0.9.21 ] ~ [ wine-0.9.20 ] ~ [ wine-0.9.19 ] ~ [ wine-0.9.18 ] ~ [ wine-0.9.17 ] ~ [ wine-0.9.16 ] ~ [ wine-0.9.15 ] ~ [ wine-0.9.14 ] ~ [ wine-0.9.13 ] ~ [ wine-0.9.12 ] ~ [ wine-0.9.11 ] ~ [ wine-0.9.10 ] ~ [ wine-0.9.9 ] ~ [ wine-0.9.8 ] ~ [ wine-0.9.7 ] ~ [ wine-0.9.6 ] ~ [ wine-0.9.5 ] ~ [ wine-0.9.4 ] ~ [ wine-0.9.3 ] ~ [ wine-0.9.2 ] ~ [ wine-0.9.1 ] ~ [ wine-0.9 ] ~ [ wine20050930 ] ~ [ wine20050830 ] ~ [ wine20050725 ] ~ [ wine20050628 ] ~ [ wine20050524 ] ~ [ wine20050419 ] ~ [ wine20050310 ] ~ [ wine20050211 ] ~ [ wine20050111 ] ~ [ wine20041201 ] ~ [ wine20041019 ] ~ [ wine20040914 ] ~ [ wine20040813 ] ~ [ wine20040716 ] ~ [ wine20040615 ] ~ [ wine20040505 ] ~ [ wine20040408 ] ~ [ wine20040309 ] ~ [ wine20040213 ] ~ [ wine20040121 ] ~ [ wine20031212 ] ~ [ wine20031118 ] ~ [ wine20031016 ] ~ [ wine20030911 ] ~ [ wine20030813 ] ~ [ wine20030709 ] ~ [ wine20030618 ] ~ [ wine20030508 ] ~ [ wine20030408 ] ~ [ wine20030318 ] ~ [ wine20030219 ] ~ [ wine20030115 ] ~ [ wine20021219 ] ~ [ wine20021125 ] ~ [ wine20021031 ] ~ [ wine20021007 ] ~ [ wine20020904 ] ~ [ wine20020804 ] ~ [ wine20020710 ] ~ [ wine20020605 ] ~ [ wine20020509 ] ~ [ wine20020411 ] ~ [ wine20020310 ] ~ [ wine20020228 ] ~ [ wine20011226 ] ~ [ wine20011108 ] ~ [ wine20011004 ] ~ [ wine20010824 ] ~ [ wine20010731 ] ~ [ wine20010629 ] ~ [ wine20010510 ] ~ [ wine20010418 ] ~ [ wine20010326 ] ~ [ wine20010305 ] ~ [ wine20010216 ] ~ [ wine20010112 ] ~ [ wine20001222 ] ~ [ wine20001202 ] ~ [ wine20001026 ] ~ [ wine20001002 ] ~ [ wine20000909 ] ~ [ wine20000821 ] ~ [ wine20000801 ] ~ [ wine20000716 ] ~ [ wine20000326 ] ~ [ wine20000227 ] ~ [ wine20000130 ] ~ [ wine20000109 ] ~

  1 /* Unit test suite for functions SystemParametersInfo and GetSystemMetrics.
  2  *
  3  * Copyright 2002 Andriy Palamarchuk
  4  *
  5  * This library is free software; you can redistribute it and/or
  6  * modify it under the terms of the GNU Lesser General Public
  7  * License as published by the Free Software Foundation; either
  8  * version 2.1 of the License, or (at your option) any later version.
  9  *
 10  * This library is distributed in the hope that it will be useful,
 11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 13  * Lesser General Public License for more details.
 14  *
 15  * You should have received a copy of the GNU Lesser General Public
 16  * License along with this library; if not, write to the Free Software
 17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 18  */
 19 
 20 #include <assert.h>
 21 #include <stdlib.h>
 22 #include <stdarg.h>
 23 #include <stdio.h>
 24 
 25 #undef _WIN32_WINNT
 26 #define _WIN32_WINNT 0x0600 /* For SPI_GETMOUSEHOVERWIDTH and more */
 27 #define _WIN32_IE 0x0700
 28 
 29 #include "wine/test.h"
 30 #include "windef.h"
 31 #include "winbase.h"
 32 #include "wingdi.h"
 33 #include "winreg.h"
 34 #include "winuser.h"
 35 #include "winnls.h"
 36 
 37 #ifndef SPI_GETDESKWALLPAPER
 38 # define SPI_GETDESKWALLPAPER 0x0073
 39 #endif
 40 
 41 static LONG (WINAPI *pChangeDisplaySettingsExA)(LPCSTR, LPDEVMODEA, HWND, DWORD, LPVOID);
 42 
 43 static int strict;
 44 static int dpi;
 45 static int iswin9x;
 46 static HDC hdc;
 47 
 48 #define eq(received, expected, label, type) \
 49         ok((received) == (expected), "%s: got " type " instead of " type "\n", (label),(received),(expected))
 50 
 51 
 52 #define SPI_SETBEEP_REGKEY                      "Control Panel\\Sound"
 53 #define SPI_SETBEEP_VALNAME                     "Beep"
 54 #define SPI_SETMOUSE_REGKEY                     "Control Panel\\Mouse"
 55 #define SPI_SETMOUSE_VALNAME1                   "MouseThreshold1"
 56 #define SPI_SETMOUSE_VALNAME2                   "MouseThreshold2"
 57 #define SPI_SETMOUSE_VALNAME3                   "MouseSpeed"
 58 #define SPI_SETBORDER_REGKEY                    "Control Panel\\Desktop\\WindowMetrics"
 59 #define SPI_SETBORDER_REGKEY2                   "Control Panel\\Desktop"
 60 #define SPI_SETBORDER_VALNAME                   "BorderWidth"
 61 #define SPI_METRIC_REGKEY                       "Control Panel\\Desktop\\WindowMetrics"
 62 #define SPI_SCROLLWIDTH_VALNAME                 "ScrollWidth"
 63 #define SPI_SCROLLHEIGHT_VALNAME                "ScrollHeight"
 64 #define SPI_CAPTIONWIDTH_VALNAME                "CaptionWidth"
 65 #define SPI_CAPTIONHEIGHT_VALNAME               "CaptionHeight"
 66 #define SPI_CAPTIONFONT_VALNAME                 "CaptionFont"
 67 #define SPI_SMCAPTIONWIDTH_VALNAME              "SmCaptionWidth"
 68 #define SPI_SMCAPTIONHEIGHT_VALNAME             "SmCaptionHeight"
 69 #define SPI_SMCAPTIONFONT_VALNAME               "SmCaptionFont"
 70 #define SPI_MENUWIDTH_VALNAME                   "MenuWidth"
 71 #define SPI_MENUHEIGHT_VALNAME                  "MenuHeight"
 72 #define SPI_MENUFONT_VALNAME                    "MenuFont"
 73 #define SPI_STATUSFONT_VALNAME                  "StatusFont"
 74 #define SPI_MESSAGEFONT_VALNAME                 "MessageFont"
 75 
 76 #define SPI_SETKEYBOARDSPEED_REGKEY             "Control Panel\\Keyboard"
 77 #define SPI_SETKEYBOARDSPEED_VALNAME            "KeyboardSpeed"
 78 #define SPI_ICONHORIZONTALSPACING_REGKEY        "Control Panel\\Desktop\\WindowMetrics"
 79 #define SPI_ICONHORIZONTALSPACING_REGKEY2       "Control Panel\\Desktop"
 80 #define SPI_ICONHORIZONTALSPACING_VALNAME       "IconSpacing"
 81 #define SPI_ICONVERTICALSPACING_REGKEY          "Control Panel\\Desktop\\WindowMetrics"
 82 #define SPI_ICONVERTICALSPACING_REGKEY2         "Control Panel\\Desktop"
 83 #define SPI_ICONVERTICALSPACING_VALNAME         "IconVerticalSpacing"
 84 #define SPI_MINIMIZEDMETRICS_REGKEY             "Control Panel\\Desktop\\WindowMetrics"
 85 #define SPI_MINWIDTH_VALNAME                    "MinWidth"
 86 #define SPI_MINHORZGAP_VALNAME                  "MinHorzGap"
 87 #define SPI_MINVERTGAP_VALNAME                  "MinVertGap"
 88 #define SPI_MINARRANGE_VALNAME                  "MinArrange"
 89 #define SPI_SETSCREENSAVETIMEOUT_REGKEY         "Control Panel\\Desktop"
 90 #define SPI_SETSCREENSAVETIMEOUT_VALNAME        "ScreenSaveTimeOut"
 91 #define SPI_SETSCREENSAVEACTIVE_REGKEY          "Control Panel\\Desktop"
 92 #define SPI_SETSCREENSAVEACTIVE_VALNAME         "ScreenSaveActive"
 93 #define SPI_SETGRIDGRANULARITY_REGKEY           "Control Panel\\Desktop"
 94 #define SPI_SETGRIDGRANULARITY_VALNAME          "GridGranularity"
 95 #define SPI_SETKEYBOARDDELAY_REGKEY             "Control Panel\\Keyboard"
 96 #define SPI_SETKEYBOARDDELAY_VALNAME            "KeyboardDelay"
 97 #define SPI_SETICONTITLEWRAP_REGKEY1            "Control Panel\\Desktop\\WindowMetrics"
 98 #define SPI_SETICONTITLEWRAP_REGKEY2            "Control Panel\\Desktop"
 99 #define SPI_SETICONTITLEWRAP_VALNAME            "IconTitleWrap"
100 #define SPI_SETMENUDROPALIGNMENT_REGKEY1        "Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows"
101 #define SPI_SETMENUDROPALIGNMENT_REGKEY2        "Control Panel\\Desktop"
102 #define SPI_SETMENUDROPALIGNMENT_VALNAME        "MenuDropAlignment"
103 #define SPI_SETDOUBLECLKWIDTH_REGKEY1           "Control Panel\\Mouse"
104 #define SPI_SETDOUBLECLKWIDTH_REGKEY2           "Control Panel\\Desktop"
105 #define SPI_SETDOUBLECLKWIDTH_VALNAME           "DoubleClickWidth"
106 #define SPI_SETDOUBLECLKHEIGHT_REGKEY1          "Control Panel\\Mouse"
107 #define SPI_SETDOUBLECLKHEIGHT_REGKEY2          "Control Panel\\Desktop"
108 #define SPI_SETDOUBLECLKHEIGHT_VALNAME          "DoubleClickHeight"
109 #define SPI_SETDOUBLECLICKTIME_REGKEY           "Control Panel\\Mouse"
110 #define SPI_SETDOUBLECLICKTIME_VALNAME          "DoubleClickSpeed"
111 #define SPI_SETMOUSEBUTTONSWAP_REGKEY           "Control Panel\\Mouse"
112 #define SPI_SETMOUSEBUTTONSWAP_VALNAME          "SwapMouseButtons"
113 #define SPI_SETWORKAREA_REGKEY                  "Control Panel\\Desktop"
114 #define SPI_SETWORKAREA_VALNAME                 "WINE_WorkArea"
115 #define SPI_SETSHOWSOUNDS_REGKEY                "Control Panel\\Accessibility\\ShowSounds"
116 #define SPI_SETSHOWSOUNDS_VALNAME               "On"
117 #define SPI_SETKEYBOARDPREF_REGKEY              "Control Panel\\Accessibility\\Keyboard Preference"
118 #define SPI_SETKEYBOARDPREF_VALNAME             "On"
119 #define SPI_SETKEYBOARDPREF_REGKEY_LEGACY       "Control Panel\\Accessibility"
120 #define SPI_SETKEYBOARDPREF_VALNAME_LEGACY      "Keyboard Preference"
121 #define SPI_SETSCREENREADER_REGKEY              "Control Panel\\Accessibility\\Blind Access"
122 #define SPI_SETSCREENREADER_VALNAME             "On"
123 #define SPI_SETSCREENREADER_REGKEY_LEGACY       "Control Panel\\Accessibility"
124 #define SPI_SETSCREENREADER_VALNAME_LEGACY      "Blind Access"
125 #define SPI_SETFONTSMOOTHING_REGKEY             "Control Panel\\Desktop"
126 #define SPI_SETFONTSMOOTHING_VALNAME            "FontSmoothing"
127 #define SPI_SETLOWPOWERACTIVE_REGKEY            "Control Panel\\Desktop"
128 #define SPI_SETLOWPOWERACTIVE_VALNAME           "LowPowerActive"
129 #define SPI_SETPOWEROFFACTIVE_REGKEY            "Control Panel\\Desktop"
130 #define SPI_SETPOWEROFFACTIVE_VALNAME           "PowerOffActive"
131 #define SPI_SETDRAGFULLWINDOWS_REGKEY           "Control Panel\\Desktop"
132 #define SPI_SETDRAGFULLWINDOWS_VALNAME          "DragFullWindows"
133 #define SPI_SETSNAPTODEFBUTTON_REGKEY           "Control Panel\\Mouse"
134 #define SPI_SETSNAPTODEFBUTTON_VALNAME          "SnapToDefaultButton"
135 #define SPI_SETMOUSEHOVERWIDTH_REGKEY           "Control Panel\\Mouse"
136 #define SPI_SETMOUSEHOVERWIDTH_VALNAME          "MouseHoverWidth"
137 #define SPI_SETMOUSEHOVERHEIGHT_REGKEY          "Control Panel\\Mouse"
138 #define SPI_SETMOUSEHOVERHEIGHT_VALNAME         "MouseHoverHeight"
139 #define SPI_SETMOUSEHOVERTIME_REGKEY            "Control Panel\\Mouse"
140 #define SPI_SETMOUSEHOVERTIME_VALNAME           "MouseHoverTime"
141 #define SPI_SETMOUSESCROLLCHARS_REGKEY          "Control Panel\\Desktop"
142 #define SPI_SETMOUSESCROLLCHARS_VALNAME         "WheelScrollChars"
143 #define SPI_SETMOUSESCROLLLINES_REGKEY          "Control Panel\\Desktop"
144 #define SPI_SETMOUSESCROLLLINES_VALNAME         "WheelScrollLines"
145 #define SPI_SETMENUSHOWDELAY_REGKEY             "Control Panel\\Desktop"
146 #define SPI_SETMENUSHOWDELAY_VALNAME            "MenuShowDelay"
147 #define SPI_SETDESKWALLPAPER_REGKEY             "Control Panel\\Desktop"
148 #define SPI_SETDESKWALLPAPER_VALNAME            "Wallpaper"
149 
150 /* volatile registry branch under CURRENT_USER_REGKEY for temporary values storage */
151 #define WINE_CURRENT_USER_REGKEY     "Wine"
152 
153 static HWND ghTestWnd;
154 
155 static DWORD WINAPI SysParamsThreadFunc( LPVOID lpParam );
156 static LRESULT CALLBACK SysParamsTestWndProc( HWND hWnd, UINT msg, WPARAM wParam,
157                                               LPARAM lParam );
158 static int change_counter;
159 static int change_last_param;
160 static int last_bpp;
161 static BOOL displaychange_ok = FALSE, displaychange_test_active = FALSE;
162 static HANDLE displaychange_sem = 0;
163 
164 static LRESULT CALLBACK SysParamsTestWndProc( HWND hWnd, UINT msg, WPARAM wParam,
165                                               LPARAM lParam )
166 {
167     switch (msg) {
168 
169     case WM_DISPLAYCHANGE:
170         ok(displaychange_ok, "Unexpected WM_DISPLAYCHANGE message\n");
171         last_bpp = wParam;
172         displaychange_ok = FALSE;
173         ReleaseSemaphore(displaychange_sem, 1, 0);
174         break;
175 
176     case WM_SETTINGCHANGE:
177         if (change_counter>0) { 
178             /* ignore these messages caused by resizing of toolbars */
179             if( wParam == SPI_SETWORKAREA || displaychange_test_active) break;
180             if( change_last_param == SPI_SETWORKAREA) {
181                 change_last_param = wParam;
182                 break;
183             }
184             ok(0,"too many changes counter=%d last change=%d\n",
185                change_counter,change_last_param);
186         }
187         change_counter++;
188         change_last_param = wParam;
189         break;
190 
191     case WM_DESTROY:
192         PostQuitMessage( 0 );
193         break;
194 
195     /* drop through */
196     default:
197         return( DefWindowProcA( hWnd, msg, wParam, lParam ) );
198     }
199 
200     return 0;
201 }
202 
203 /*
204 Performs testing for system parameters messages
205 params:
206  - system parameter id
207  - supposed value of the registry key
208 */
209 static void test_change_message( int action, int optional )
210 {
211     if (change_counter==0 && optional==1)
212         return;
213     ok( 1 == change_counter,
214         "Missed a message: change_counter=%d\n", change_counter );
215     change_counter = 0;
216     ok( action == change_last_param,
217         "Wrong action got %d expected %d\n", change_last_param, action );
218     change_last_param = 0;
219 }
220 
221 static BOOL test_error_msg ( int rc, const char *name )
222 {
223     DWORD last_error = GetLastError();
224 
225     if (rc==0)
226     {
227         if (last_error==0xdeadbeef || last_error==ERROR_INVALID_SPI_VALUE || last_error==ERROR_INVALID_PARAMETER)
228         {
229             trace("%s not supported on this platform. Skipping test\n", name);
230         }
231         else if (last_error==ERROR_ACCESS_DENIED)
232         {
233             trace("%s does not have privileges to run. Skipping test\n", name);
234         }
235         else
236         {
237             trace("%s failed for reason: %d. Indicating test failure and skipping remainder of test\n",name,last_error);
238             ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,last_error);
239         }
240         return FALSE;
241     }
242     else
243     {
244         ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,last_error);
245         return TRUE;
246     }
247 }
248 
249 /*
250  * Tests the HKEY_CURRENT_USER subkey value.
251  * The value should contain string value.
252  *
253  * Params:
254  * lpsSubKey - subkey name
255  * lpsRegName - registry entry name
256  * lpsTestValue - value to test
257  */
258 static void _test_reg_key( LPCSTR subKey1, LPCSTR subKey2, LPCSTR valName1, LPCSTR valName2, LPCSTR testValue )
259 {
260     CHAR  value[MAX_PATH];
261     DWORD valueLen;
262     DWORD type;
263     HKEY hKey;
264     LONG rc;
265     int found=0;
266 
267     *value='\0';
268     valueLen=sizeof(value);
269     RegOpenKeyA( HKEY_CURRENT_USER, subKey1, &hKey );
270     rc=RegQueryValueExA( hKey, valName1, NULL, &type, (LPBYTE)value, &valueLen );
271     RegCloseKey( hKey );
272     if (rc==ERROR_SUCCESS)
273     {
274         ok( !strcmp( testValue, value ),
275             "Wrong value in registry: subKey=%s, valName=%s, testValue=%s, value=%s\n",
276             subKey1, valName1, testValue, value );
277         found++;
278     }
279     else if (strict)
280     {
281         ok(0,"Missing registry entry: subKey=%s, valName=%s\n",
282            subKey1, valName1);
283     }
284     if (valName2)
285     {
286         *value='\0';
287         valueLen=sizeof(value);
288         RegOpenKeyA( HKEY_CURRENT_USER, subKey1, &hKey );
289         rc=RegQueryValueExA( hKey, valName2, NULL, &type, (LPBYTE)value, &valueLen );
290         RegCloseKey( hKey );
291         if (rc==ERROR_SUCCESS)
292         {
293             ok( !strcmp( testValue, value ),
294                 "Wrong value in registry: subKey=%s, valName=%s, testValue=%s, value=%s\n",
295                 subKey1, valName2, testValue, value );
296             found++;
297         }
298         else if (strict)
299         {
300             ok( 0,"Missing registry entry: subKey=%s, valName=%s\n",
301                 subKey1, valName2 );
302         }
303     }
304     if (subKey2 && !strict)
305     {
306         *value='\0';
307         valueLen=sizeof(value);
308         RegOpenKeyA( HKEY_CURRENT_USER, subKey2, &hKey );
309         rc=RegQueryValueExA( hKey, valName1, NULL, &type, (LPBYTE)value, &valueLen );
310         RegCloseKey( hKey );
311         if (rc==ERROR_SUCCESS)
312         {
313             ok( !strcmp( testValue, value ),
314                 "Wrong value in registry: subKey=%s, valName=%s, testValue=%s, value=%s\n",
315                 subKey2, valName1, testValue, value );
316             found++;
317         }
318         else if (strict)
319         {
320             ok( 0,"Missing registry entry: subKey=%s, valName=%s\n",
321                 subKey2, valName1 );
322         }
323         if (valName2)
324         {
325             *value='\0';
326             valueLen=sizeof(value);
327             RegOpenKeyA( HKEY_CURRENT_USER, subKey2, &hKey );
328             rc=RegQueryValueExA( hKey, valName2, NULL, &type, (LPBYTE)value, &valueLen );
329             RegCloseKey( hKey );
330             if (rc==ERROR_SUCCESS)
331             {
332                 ok( !strcmp( testValue, value ),
333                     "Wrong value in registry: subKey=%s, valName=%s, testValue=%s, value=%s\n",
334                     subKey2, valName2, testValue, value );
335                 found++;
336             }
337             else if (strict)
338             {
339                 ok( 0,"Missing registry entry: subKey=%s, valName=%s\n",
340                     subKey2, valName2 );
341             }
342          }
343     }
344     ok(found,"Missing registry values: %s or %s in keys: %s or %s\n",
345        valName1, (valName2?valName2:"<n/a>"), subKey1, (subKey2?subKey2:"<n/a>") );
346 }
347 
348 #define test_reg_key( subKey, valName, testValue ) \
349     _test_reg_key( subKey, NULL, valName, NULL, testValue )
350 #define test_reg_key_ex( subKey1, subKey2, valName, testValue ) \
351     _test_reg_key( subKey1, subKey2, valName, NULL, testValue )
352 #define test_reg_key_ex2( subKey1, subKey2, valName1, valName2, testValue ) \
353     _test_reg_key( subKey1, subKey2, valName1, valName2, testValue )
354 
355 /* get a metric from the registry. If the value is negative
356  * it is assumed to be in twips and converted to pixels */
357 static UINT metricfromreg( const char *keyname, const char *valname, int dpi)
358 {
359     HKEY hkey;
360     char buf[64];
361     DWORD ret;
362     DWORD size, type;
363     int value;
364 
365     RegOpenKeyA( HKEY_CURRENT_USER, keyname, &hkey );
366     size = sizeof(buf);
367     ret=RegQueryValueExA( hkey, valname, NULL, &type, (LPBYTE)buf, &size );
368     RegCloseKey( hkey );
369     if( ret != ERROR_SUCCESS) return -1;
370     value = atoi( buf);
371     if( value < 0)
372         value = ( -value * dpi + 720) / 1440;
373     return value;
374 }
375 
376 typedef struct
377 {
378     INT16  lfHeight;
379     INT16  lfWidth;
380     INT16  lfEscapement;
381     INT16  lfOrientation;
382     INT16  lfWeight;
383     BYTE   lfItalic;
384     BYTE   lfUnderline;
385     BYTE   lfStrikeOut;
386     BYTE   lfCharSet;
387     BYTE   lfOutPrecision;
388     BYTE   lfClipPrecision;
389     BYTE   lfQuality;
390     BYTE   lfPitchAndFamily;
391     CHAR   lfFaceName[LF_FACESIZE];
392 } LOGFONT16, *LPLOGFONT16;
393 
394 /* get logfont from the registry */
395 static int lffromreg( const char *keyname, const char *valname, LOGFONTA *plf)
396 {
397     HKEY hkey;
398     LOGFONTW lfw;
399     DWORD ret, size, type;
400 
401     RegOpenKeyA( HKEY_CURRENT_USER, keyname, &hkey ); 
402     size = sizeof( lfw);
403     ret=RegQueryValueExA( hkey, valname, NULL, &type, (LPBYTE)&lfw, &size );
404     RegCloseKey( hkey );
405     ok( ret == ERROR_SUCCESS, "Key \"%s\" value \"%s\" not found\n", keyname, valname);
406     if( ret != ERROR_SUCCESS) 
407         return FALSE;
408     if( size <= sizeof( LOGFONT16)) {
409         LOGFONT16 *plf16 = (LOGFONT16*) &lfw;
410         plf->lfHeight = plf16->lfHeight;
411         plf->lfWidth = plf16->lfWidth;
412         plf->lfEscapement = plf16->lfEscapement;
413         plf->lfOrientation = plf16->lfOrientation;
414         plf->lfWeight = plf16->lfWeight;
415         plf->lfItalic = plf16->lfItalic;
416         plf->lfUnderline = plf16->lfUnderline;
417         plf->lfStrikeOut = plf16->lfStrikeOut;
418         plf->lfCharSet = plf16->lfCharSet;
419         plf->lfOutPrecision = plf16->lfOutPrecision;
420         plf->lfClipPrecision = plf16->lfClipPrecision;
421         plf->lfQuality = plf16->lfQuality;
422         plf->lfPitchAndFamily = plf16->lfPitchAndFamily;
423         memcpy( plf->lfFaceName, plf16->lfFaceName, LF_FACESIZE );
424     } else if( size <= sizeof( LOGFONTA)) {
425         plf = (LOGFONTA*) &lfw;
426     } else {
427         plf->lfHeight = lfw.lfHeight;
428         plf->lfWidth = lfw.lfWidth;
429         plf->lfEscapement = lfw.lfEscapement;
430         plf->lfOrientation = lfw.lfOrientation;
431         plf->lfWeight = lfw.lfWeight;
432         plf->lfItalic = lfw.lfItalic;
433         plf->lfUnderline = lfw.lfUnderline;
434         plf->lfStrikeOut = lfw.lfStrikeOut;
435         plf->lfCharSet = lfw.lfCharSet;
436         plf->lfOutPrecision = lfw.lfOutPrecision;
437         plf->lfClipPrecision = lfw.lfClipPrecision;
438         plf->lfQuality = lfw.lfQuality;
439         plf->lfPitchAndFamily = lfw.lfPitchAndFamily;
440         WideCharToMultiByte( CP_ACP, 0, lfw.lfFaceName, -1, plf->lfFaceName,
441             LF_FACESIZE, NULL, NULL);
442 
443     }
444     return TRUE;
445 }
446 
447 static void test_SPI_SETBEEP( void )                   /*      2 */
448 {
449     BOOL rc;
450     BOOL old_b;
451     BOOL b;
452     BOOL curr_val;
453 
454     trace("testing SPI_{GET,SET}BEEP\n");
455     SetLastError(0xdeadbeef);
456     rc=SystemParametersInfoA( SPI_GETBEEP, 0, &old_b, 0 );
457     if (!test_error_msg(rc,"SPI_{GET,SET}BEEP"))
458         return;
459 
460     curr_val = TRUE;
461     rc=SystemParametersInfoA( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
462     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
463     test_change_message( SPI_SETBEEP, 0 );
464     test_reg_key( SPI_SETBEEP_REGKEY,
465                   SPI_SETBEEP_VALNAME,
466                   curr_val ? "Yes" : "No" );
467     rc=SystemParametersInfoA( SPI_GETBEEP, 0, &b, 0 );
468     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
469     eq( b, curr_val, "SPI_{GET,SET}BEEP", "%d" );
470     rc=SystemParametersInfoW( SPI_GETBEEP, 0, &b, 0 );
471     if (rc!=0 || GetLastError()!=ERROR_CALL_NOT_IMPLEMENTED)
472     {
473         ok(rc!=0,"SystemParametersInfoW: rc=%d err=%d\n",rc,GetLastError());
474         eq( b, curr_val, "SystemParametersInfoW", "%d" );
475     }
476 
477     /* is a message sent for the second change? */
478     rc=SystemParametersInfoA( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
479     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
480     test_change_message( SPI_SETBEEP, 0 );
481 
482     curr_val = FALSE;
483     rc=SystemParametersInfoW( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
484     if (rc==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
485         rc=SystemParametersInfoA( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
486     ok(rc!=0,"SystemParametersInfo: rc=%d err=%d\n",rc,GetLastError());
487     test_change_message( SPI_SETBEEP, 0 );
488     test_reg_key( SPI_SETBEEP_REGKEY,
489                   SPI_SETBEEP_VALNAME,
490                   curr_val ? "Yes" : "No" );
491     rc=SystemParametersInfoA( SPI_GETBEEP, 0, &b, 0 );
492     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
493     eq( b, curr_val, "SPI_{GET,SET}BEEP", "%d" );
494     rc=SystemParametersInfoW( SPI_GETBEEP, 0, &b, 0 );
495     if (rc!=0 || GetLastError()!=ERROR_CALL_NOT_IMPLEMENTED)
496     {
497         ok(rc!=0,"SystemParametersInfoW: rc=%d err=%d\n",rc,GetLastError());
498         eq( b, curr_val, "SystemParametersInfoW", "%d" );
499     }
500     ok( MessageBeep( MB_OK ), "Return value of MessageBeep when sound is disabled\n" );
501 
502     rc=SystemParametersInfoA( SPI_SETBEEP, old_b, 0, SPIF_UPDATEINIFILE );
503     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
504 }
505 
506 static const char *setmouse_valuenames[3] = {
507     SPI_SETMOUSE_VALNAME1,
508     SPI_SETMOUSE_VALNAME2,
509     SPI_SETMOUSE_VALNAME3
510 };
511 
512 /*
513  * Runs check for one setting of spi_setmouse.
514  */
515 static void run_spi_setmouse_test( int curr_val[], POINT *req_change, POINT *proj_change,
516                                    int nchange )
517 {
518     BOOL rc;
519     INT mi[3];
520     static int aw_turn = 0;
521     static BOOL w_implemented = 1;
522 
523     char buf[20];
524     int i;
525 
526     aw_turn++;
527     rc=0;
528     if ((aw_turn % 2!=0) && (w_implemented))
529     {
530         /* call unicode on odd (non even) calls */ 
531         SetLastError(0xdeadbeef);
532         rc=SystemParametersInfoW( SPI_SETMOUSE, 0, curr_val, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
533         if (rc==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
534         {
535             w_implemented = 0;
536             trace("SystemParametersInfoW not supported on this platform\n");
537         }
538     }
539 
540     if ((aw_turn % 2==0) || (!w_implemented))
541     {
542         /* call ascii version on even calls or if unicode is not available */
543         rc=SystemParametersInfoA( SPI_SETMOUSE, 0, curr_val, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
544     }
545 
546     ok(rc!=0,"SystemParametersInfo: rc=%d err=%d\n",rc,GetLastError());
547     test_change_message( SPI_SETMOUSE, 0 );
548     for (i = 0; i < 3; i++)
549     {
550         sprintf( buf, "%d", curr_val[i] );
551         test_reg_key( SPI_SETMOUSE_REGKEY, setmouse_valuenames[i], buf );
552     }
553 
554     rc=SystemParametersInfoA( SPI_GETMOUSE, 0, mi, 0 );
555     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
556     for (i = 0; i < 3; i++)
557     {
558         ok(mi[i] == curr_val[i],
559            "incorrect value for %d: %d != %d\n", i, mi[i], curr_val[i]);
560     }
561 
562     if (w_implemented)
563     { 
564         rc=SystemParametersInfoW( SPI_GETMOUSE, 0, mi, 0 );
565         ok(rc!=0,"SystemParametersInfoW: rc=%d err=%d\n",rc,GetLastError());
566         for (i = 0; i < 3; i++)
567         {
568             ok(mi[i] == curr_val[i],
569                "incorrect value for %d: %d != %d\n", i, mi[i], curr_val[i]);
570         }
571     }
572 
573     if (0)
574     {
575     /* FIXME: this always fails for me  - AJ */
576     for (i = 0; i < nchange; i++)
577     {
578         POINT mv;
579         mouse_event( MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, 0, 0, 0, 0 );
580         mouse_event( MOUSEEVENTF_MOVE, req_change[i].x, req_change[i].y, 0, 0 );
581         GetCursorPos( &mv );
582         ok( proj_change[i].x == mv.x, "Projected dx and real dx comparison. May fail under high load.\n" );
583         ok( proj_change[i].y == mv.y, "Projected dy equals real dy. May fail under high load.\n" );
584     }
585     }
586 }
587 
588 static void test_SPI_SETMOUSE( void )                  /*      4 */
589 {
590     BOOL rc;
591     INT old_mi[3];
592 
593     /* win nt default values - 6, 10, 1 */
594     INT curr_val[3] = {6, 10, 1};
595 
596     /* requested and projected mouse movements */
597     POINT req_change[] =   { {6, 6}, { 7, 6}, { 8, 6}, {10, 10}, {11, 10}, {100, 100} };
598     POINT proj_change1[] = { {6, 6}, {14, 6}, {16, 6}, {20, 20}, {22, 20}, {200, 200} };
599     POINT proj_change2[] = { {6, 6}, {14, 6}, {16, 6}, {20, 20}, {44, 20}, {400, 400} };
600     POINT proj_change3[] = { {6, 6}, {14, 6}, {16, 6}, {20, 20}, {22, 20}, {200, 200} };
601     POINT proj_change4[] = { {6, 6}, { 7, 6}, { 8, 6}, {10, 10}, {11, 10}, {100, 100} };
602     POINT proj_change5[] = { {6, 6}, { 7, 6}, {16, 6}, {20, 20}, {22, 20}, {200, 200} };
603     POINT proj_change6[] = { {6, 6}, {28, 6}, {32, 6}, {40, 40}, {44, 40}, {400, 400} };
604     POINT proj_change7[] = { {6, 6}, {14, 6}, {32, 6}, {40, 40}, {44, 40}, {400, 400} };
605     POINT proj_change8[] = { {6, 6}, {28, 6}, {32, 6}, {40, 40}, {44, 40}, {400, 400} };
606 
607     int nchange = sizeof( req_change ) / sizeof( POINT );
608 
609     trace("testing SPI_{GET,SET}MOUSE\n");
610     SetLastError(0xdeadbeef);
611     rc=SystemParametersInfoA( SPI_GETMOUSE, 0, old_mi, 0 );
612     if (!test_error_msg(rc,"SPI_{GET,SET}MOUSE"))
613         return;
614 
615     run_spi_setmouse_test( curr_val, req_change, proj_change1, nchange );
616 
617     /* acceleration change */
618     curr_val[2] = 2;
619     run_spi_setmouse_test( curr_val, req_change, proj_change2, nchange );
620 
621     /* acceleration change */
622     curr_val[2] = 3;
623     run_spi_setmouse_test( curr_val, req_change, proj_change3, nchange );
624 
625     /* acceleration change */
626     curr_val[2] = 0;
627     run_spi_setmouse_test( curr_val, req_change, proj_change4, nchange );
628 
629     /* threshold change */
630     curr_val[2] = 1;
631     curr_val[0] = 7;
632     run_spi_setmouse_test( curr_val, req_change, proj_change5, nchange );
633 
634     /* threshold change */
635     curr_val[2] = 2;
636     curr_val[0] = 6;
637     curr_val[1] = 6;
638     run_spi_setmouse_test( curr_val, req_change, proj_change6, nchange );
639 
640     /* threshold change */
641     curr_val[1] = 7;
642     run_spi_setmouse_test( curr_val, req_change, proj_change7, nchange );
643 
644     /* threshold change */
645     curr_val[1] = 5;
646     run_spi_setmouse_test( curr_val, req_change, proj_change8, nchange );
647 
648     rc=SystemParametersInfoA( SPI_SETMOUSE, 0, old_mi, SPIF_UPDATEINIFILE );
649     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
650 }
651 
652 static void test_setborder(UINT curr_val, int usesetborder, int dpi)
653 {
654     BOOL rc;
655     UINT border, regval;
656     INT frame;
657     NONCLIENTMETRICSA ncm;
658 
659     ncm.cbSize = sizeof( ncm);
660     rc=SystemParametersInfo( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
661     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
662     if( usesetborder) {
663             rc=SystemParametersInfoA( SPI_SETBORDER, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
664         ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
665         test_change_message( SPI_SETBORDER, 1 );
666     } else { /* set non client metrics */
667         ncm.iBorderWidth = curr_val;
668         rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &ncm, SPIF_UPDATEINIFILE|
669                 SPIF_SENDCHANGE);
670         ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
671         test_change_message( SPI_SETNONCLIENTMETRICS, 1 );
672     }
673     if( curr_val) { /* skip if 0, some windows versions return 0 others 1 */
674         regval = metricfromreg( SPI_SETBORDER_REGKEY2, SPI_SETBORDER_VALNAME, dpi);
675         if( regval != curr_val)
676             regval = metricfromreg( SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME, dpi);
677         ok( regval==curr_val, "wrong value in registry %d, expected %d\n", regval, curr_val);
678     }
679     /* minimum border width is 1 */
680     if (curr_val == 0) curr_val = 1;
681     /* should be the same as the non client metrics */
682     rc=SystemParametersInfo( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
683     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
684     eq( (UINT)ncm.iBorderWidth, curr_val, "NonClientMetric.iBorderWidth", "%d");
685     /* and from SPI_GETBORDER */ 
686     rc=SystemParametersInfoA( SPI_GETBORDER, 0, &border, 0 );
687     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
688     eq( border, curr_val, "SPI_{GET,SET}BORDER", "%d");
689     /* test some SystemMetrics */
690     frame = curr_val + GetSystemMetrics( SM_CXDLGFRAME );
691     eq( frame, GetSystemMetrics( SM_CXFRAME ), "SM_CXFRAME", "%d" );
692     eq( frame, GetSystemMetrics( SM_CYFRAME ), "SM_CYFRAME", "%d" );
693     eq( frame, GetSystemMetrics( SM_CXSIZEFRAME ), "SM_CXSIZEFRAME", "%d" );
694     eq( frame, GetSystemMetrics( SM_CYSIZEFRAME ), "SM_CYSIZEFRAME", "%d" );
695 }
696 
697 static void test_SPI_SETBORDER( void )                 /*      6 */
698 {
699     BOOL rc;
700     UINT old_border;
701     NONCLIENTMETRICSA ncmsave;
702     INT CaptionWidth;
703 
704     ncmsave.cbSize = sizeof( ncmsave);
705     rc=SystemParametersInfo( SPI_GETNONCLIENTMETRICS, 0, &ncmsave, 0);
706     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
707     /* CaptionWidth from the registry may have different value of iCaptionWidth
708      * from the non client metrics (observed on WinXP).
709      * Fix this so we can safely restore settings with the nonclientmetrics */
710     CaptionWidth = metricfromreg(
711             "Control Panel\\Desktop\\WindowMetrics","CaptionWidth", dpi);
712     ncmsave.iCaptionWidth = CaptionWidth;
713 
714     /* These tests hang when XFree86 4.0 for Windows is running (tested on
715      *  WinNT, SP2, Cygwin/XFree 4.1.0. Skip the test when XFree86 is
716      * running.
717      */
718     if (FindWindowA( NULL, "Cygwin/XFree86" ))
719         return;
720 
721     trace("testing SPI_{GET,SET}BORDER\n");
722 
723     SetLastError(0xdeadbeef);
724     rc=SystemParametersInfoA( SPI_GETBORDER, 0, &old_border, 0 );
725     if (!test_error_msg(rc,"SPI_{GET,SET}BORDER"))
726         return;
727     /* This will restore sane values if the test hang previous run. */
728     if ( old_border == 7 || old_border == 20 )
729         old_border = 1;
730 
731     /* The SPI_SETBORDER seems to be buggy on Win9x/ME (looks like you need to
732      * do it twice to make the intended change). So skip parts of the tests on
733      * those platforms */
734     if( !iswin9x) {
735         /* win2k3 fails if you set the same border twice, or if size is 0 */
736         test_setborder(2,  1, dpi);
737         test_setborder(1,  1, dpi);
738         test_setborder(3,  1, dpi);
739     }
740     test_setborder(1, 0, dpi);
741     test_setborder(0, 0, dpi);
742     test_setborder(3, 0, dpi);
743 
744     rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &ncmsave,
745             SPIF_UPDATEINIFILE| SPIF_SENDCHANGE);
746     test_change_message( SPI_SETNONCLIENTMETRICS, 1 );
747     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",
748         rc,GetLastError());
749 }
750 
751 static void test_SPI_SETKEYBOARDSPEED( void )          /*     10 */
752 {
753     BOOL rc;
754     UINT old_speed;
755     const UINT vals[]={0,20,31};
756     unsigned int i;
757 
758     trace("testing SPI_{GET,SET}KEYBOARDSPEED\n");
759     SetLastError(0xdeadbeef);
760     rc=SystemParametersInfoA( SPI_GETKEYBOARDSPEED, 0, &old_speed, 0 );
761     if (!test_error_msg(rc,"SPI_{GET,SET}KEYBOARDSPEED"))
762         return;
763 
764     for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
765     {
766         UINT v;
767         char buf[10];
768 
769         rc=SystemParametersInfoA( SPI_SETKEYBOARDSPEED, vals[i], 0,
770                                   SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
771         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
772         test_change_message( SPI_SETKEYBOARDSPEED, 0 );
773         sprintf( buf, "%d", vals[i] );
774         test_reg_key( SPI_SETKEYBOARDSPEED_REGKEY, SPI_SETKEYBOARDSPEED_VALNAME, buf );
775 
776         rc=SystemParametersInfoA( SPI_GETKEYBOARDSPEED, 0, &v, 0 );
777         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
778         eq( v, vals[i], "SPI_{GET,SET}KEYBOARDSPEED", "%d" );
779     }
780 
781     rc=SystemParametersInfoA( SPI_SETKEYBOARDSPEED, old_speed, 0, SPIF_UPDATEINIFILE );
782     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
783 }
784 
785 /* test_SPI_ICONHORIZONTALSPACING helper */
786 static void dotest_spi_