2 * COPYRIGHT: GPL, see COPYING in the top level directory
3 * PROJECT: ReactOS win32 kernel mode subsystem server
4 * PURPOSE: System parameters functions
5 * FILE: subsystem/win32/win32k/ntuser/sysparams.c
6 * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org)
10 // - check all values that are in Winsta in ros
11 // - does setting invalid fonts work?
12 // - save appropriate text metrics
15 DBG_DEFAULT_CHANNEL(UserSysparams
);
18 BOOL gbSpiInitialized
= FALSE
;
19 PWINSTATION_OBJECT gpwinstaCurrent
= NULL
;
21 // HACK! We initialize SPI before we have a proper surface to get this from.
23 //(pPrimarySurface->GDIInfo.ulLogPixelsY)
24 #define REG2METRIC(reg) (reg > 0 ? reg : ((-(reg) * dpi + 720) / 1440))
25 #define METRIC2REG(met) (-((((met) * 1440)- 0) / dpi))
27 #define REQ_INTERACTIVE_WINSTA(err) \
28 if (gpwinstaCurrent != InputWindowStation) \
30 EngSetLastError(err); \
34 static const WCHAR
* KEY_MOUSE
= L
"Control Panel\\Mouse";
35 static const WCHAR
* VAL_MOUSE1
= L
"MouseThreshold1";
36 static const WCHAR
* VAL_MOUSE2
= L
"MouseThreshold2";
37 static const WCHAR
* VAL_MOUSE3
= L
"MouseSpeed";
38 static const WCHAR
* VAL_MOUSETRAILS
= L
"MouseTrails";
39 static const WCHAR
* VAL_DBLCLKWIDTH
= L
"DoubleClickWidth";
40 static const WCHAR
* VAL_DBLCLKHEIGHT
= L
"DoubleClickHeight";
41 static const WCHAR
* VAL_DBLCLKTIME
= L
"DoubleClickSpeed";
42 static const WCHAR
* VAL_SNAPDEFBTN
= L
"SnapToDefaultButton";
43 static const WCHAR
* VAL_SWAP
= L
"SwapMouseButtons";
44 static const WCHAR
* VAL_HOVERTIME
= L
"MouseHoverTime";
45 static const WCHAR
* VAL_HOVERWIDTH
= L
"MouseHoverWidth";
46 static const WCHAR
* VAL_HOVERHEIGHT
= L
"MouseHoverHeight";
47 //static const WCHAR* VAL_SENSITIVITY = L"MouseSensitivity";
49 static const WCHAR
* KEY_DESKTOP
= L
"Control Panel\\Desktop";
50 static const WCHAR
* VAL_SCRTO
= L
"ScreenSaveTimeOut";
51 static const WCHAR
* VAL_SCRNSV
= L
"SCRNSAVE.EXE";
52 static const WCHAR
* VAL_SCRACT
= L
"ScreenSaveActive";
53 static const WCHAR
* VAL_GRID
= L
"GridGranularity";
54 static const WCHAR
* VAL_DRAG
= L
"DragFullWindows";
55 static const WCHAR
* VAL_DRAGHEIGHT
= L
"DragHeight";
56 static const WCHAR
* VAL_DRAGWIDTH
= L
"DragWidth";
57 static const WCHAR
* VAL_FNTSMOOTH
= L
"FontSmoothing";
58 static const WCHAR
* VAL_SCRLLLINES
= L
"WheelScrollLines";
59 static const WCHAR
* VAL_CLICKLOCKTIME
= L
"ClickLockTime";
60 #if (_WIN32_WINNT >= 0x0600)
61 static const WCHAR
* VAL_SCRLLCHARS
= L
"WheelScrollChars";
63 static const WCHAR
* VAL_USERPREFMASK
= L
"UserPreferencesMask";
65 static const WCHAR
* KEY_MDALIGN
= L
"Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows";
66 static const WCHAR
* VAL_MDALIGN
= L
"MenuDropAlignment";
68 static const WCHAR
* KEY_METRIC
= L
"Control Panel\\Desktop\\WindowMetrics";
69 static const WCHAR
* VAL_BORDER
= L
"BorderWidth";
70 static const WCHAR
* VAL_ICONSPC
= L
"IconSpacing";
71 static const WCHAR
* VAL_ICONVSPC
= L
"IconVerticalspacing";
72 static const WCHAR
* VAL_ITWRAP
= L
"IconTitleWrap";
74 static const WCHAR
* KEY_SOUND
= L
"Control Panel\\Sound";
75 static const WCHAR
* VAL_BEEP
= L
"Beep";
77 static const WCHAR
* KEY_KBD
= L
"Control Panel\\Keyboard";
78 static const WCHAR
* VAL_KBDSPD
= L
"KeyboardSpeed";
79 static const WCHAR
* VAL_KBDDELAY
= L
"KeyboardDelay";
81 static const WCHAR
* KEY_SHOWSNDS
= L
"Control Panel\\Accessibility\\ShowSounds";
82 static const WCHAR
* KEY_KDBPREF
= L
"Control Panel\\Accessibility\\Keyboard Preference";
83 static const WCHAR
* KEY_SCRREAD
= L
"Control Panel\\Accessibility\\Blind Access";
84 static const WCHAR
* VAL_ON
= L
"On";
88 /** Loading the settings ******************************************************/
92 SpiLoadDWord(PCWSTR pwszKey
, PCWSTR pwszValue
, INT iValue
)
95 if (!RegReadUserSetting(pwszKey
, pwszValue
, REG_DWORD
, &Result
, sizeof(Result
)))
104 SpiLoadInt(PCWSTR pwszKey
, PCWSTR pwszValue
, INT iValue
)
109 cbSize
= sizeof(awcBuffer
);
110 if (!RegReadUserSetting(pwszKey
, pwszValue
, REG_SZ
, awcBuffer
, cbSize
))
114 return _wtoi(awcBuffer
);
119 SpiLoadUserPrefMask(DWORD dValue
)
122 if (!RegReadUserSetting(KEY_DESKTOP
, VAL_USERPREFMASK
, REG_BINARY
, &Result
, sizeof(Result
)))
132 { // Must have the string!
133 WCHAR szApplicationName
[MAX_PATH
];
134 RtlZeroMemory(&szApplicationName
, sizeof(szApplicationName
));
135 if (!RegReadUserSetting(KEY_DESKTOP
, VAL_SCRNSV
, REG_SZ
, &szApplicationName
, sizeof(szApplicationName
)))
139 if (wcslen(szApplicationName
) == 0) return 0;
140 return SpiLoadInt(KEY_DESKTOP
, VAL_SCRTO
, 0);
145 SpiLoadMouse(PCWSTR pwszValue
, INT iValue
)
147 return SpiLoadInt(KEY_MOUSE
, pwszValue
, iValue
);
152 SpiLoadMetric(PCWSTR pwszValue
, INT iValue
)
156 iRegVal
= SpiLoadInt(KEY_METRIC
, pwszValue
, METRIC2REG(iValue
));
157 TRACE("Loaded metric setting '%S', iValue=%d(reg:%d), ret=%d(reg:%d)\n",
158 pwszValue
, iValue
, METRIC2REG(iValue
), REG2METRIC(iRegVal
), iRegVal
);
159 return REG2METRIC(iRegVal
);
164 SpiLoadFont(PLOGFONTW plfOut
, LPWSTR pwszValueName
, PLOGFONTW plfDefault
)
168 bResult
= RegReadUserSetting(KEY_METRIC
,
174 *plfOut
= *plfDefault
;
182 gspv
.ncm
.iCaptionWidth
= max(gspv
.ncm
.iCaptionWidth
, 8);
183 gspv
.ncm
.iBorderWidth
= max(gspv
.ncm
.iBorderWidth
, 1);
184 gspv
.ncm
.iScrollWidth
= max(gspv
.ncm
.iScrollWidth
, 8);
185 gspv
.ncm
.iScrollHeight
= max(gspv
.ncm
.iScrollHeight
, 8);
186 // gspv.ncm.iMenuHeight = max(gspv.ncm.iMenuHeight, gspv.tmMenuFont.tmHeight);
187 // gspv.ncm.iMenuHeight = max(gspv.ncm.iMenuHeight,
188 // 2 + gspv.tmMenuFont.tmHeight +
189 // gspv.tmMenuFont.tmExternalLeading);
190 if (gspv
.iDblClickTime
== 0) gspv
.iDblClickTime
= 500;
193 gspv
.tmMenuFont
.tmHeight
= 11;
194 gspv
.tmMenuFont
.tmExternalLeading
= 2;
196 gspv
.tmCaptionFont
.tmHeight
= 11;
197 gspv
.tmCaptionFont
.tmExternalLeading
= 2;
203 SpiUpdatePerUserSystemParameters()
205 static LOGFONTW lf1
= {-11, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
,
206 FALSE
, ANSI_CHARSET
, 0, 0, DEFAULT_QUALITY
,
207 VARIABLE_PITCH
| FF_SWISS
, L
"MS Sans Serif"};
208 static LOGFONTW lf2
= {-11, 0, 0, 0, FW_BOLD
, FALSE
, FALSE
,
209 FALSE
, ANSI_CHARSET
, 0, 0, DEFAULT_QUALITY
,
210 VARIABLE_PITCH
| FF_SWISS
, L
"MS Sans Serif"};
212 TRACE("Enter SpiUpdatePerUserSystemParameters\n");
214 /* Clear the structure */
215 memset(&gspv
, 0, sizeof(gspv
));
217 /* Load mouse settings */
218 gspv
.caiMouse
.FirstThreshold
= SpiLoadMouse(VAL_MOUSE1
, 6);
219 gspv
.caiMouse
.SecondThreshold
= SpiLoadMouse(VAL_MOUSE2
, 10);
220 gspv
.caiMouse
.Acceleration
= gspv
.iMouseSpeed
= SpiLoadMouse(VAL_MOUSE3
, 1);
221 gspv
.bMouseBtnSwap
= SpiLoadMouse(VAL_SWAP
, 0);
222 gspv
.bSnapToDefBtn
= SpiLoadMouse(VAL_SNAPDEFBTN
, 0);
223 gspv
.iMouseTrails
= SpiLoadMouse(VAL_MOUSETRAILS
, 0);
224 gspv
.iDblClickTime
= SpiLoadMouse(VAL_DBLCLKTIME
, 500);
225 gspv
.iDblClickWidth
= SpiLoadMouse(VAL_DBLCLKWIDTH
, 4);
226 gspv
.iDblClickHeight
= SpiLoadMouse(VAL_DBLCLKHEIGHT
, 4);
227 gspv
.iMouseHoverTime
= SpiLoadMouse(VAL_HOVERTIME
, 400);
228 gspv
.iMouseHoverWidth
= SpiLoadMouse(VAL_HOVERWIDTH
, 4);
229 gspv
.iMouseHoverHeight
= SpiLoadMouse(VAL_HOVERHEIGHT
, 4);
231 /* Load NONCLIENTMETRICS */
232 gspv
.ncm
.cbSize
= sizeof(NONCLIENTMETRICSW
);
233 gspv
.ncm
.iBorderWidth
= SpiLoadMetric(VAL_BORDER
, 1);
234 gspv
.ncm
.iScrollWidth
= SpiLoadMetric(L
"ScrollWidth", 16);
235 gspv
.ncm
.iScrollHeight
= SpiLoadMetric(L
"ScrollHeight", 16);
236 gspv
.ncm
.iCaptionWidth
= SpiLoadMetric(L
"CaptionWidth", 19);
237 gspv
.ncm
.iCaptionHeight
= SpiLoadMetric(L
"CaptionHeight", 19);
238 gspv
.ncm
.iSmCaptionWidth
= SpiLoadMetric(L
"SmCaptionWidth", 12);
239 gspv
.ncm
.iSmCaptionHeight
= SpiLoadMetric(L
"SmCaptionHeight", 14);
240 gspv
.ncm
.iMenuWidth
= SpiLoadMetric(L
"MenuWidth", 18);
241 gspv
.ncm
.iMenuHeight
= SpiLoadMetric(L
"MenuHeight", 18);
242 #if (WINVER >= 0x0600)
243 gspv
.ncm
.iPaddedBorderWidth
= SpiLoadMetric(L
"PaddedBorderWidth", 18);
245 SpiLoadFont(&gspv
.ncm
.lfCaptionFont
, L
"CaptionFont", &lf2
);
246 SpiLoadFont(&gspv
.ncm
.lfSmCaptionFont
, L
"SmCaptionFont", &lf1
);
247 SpiLoadFont(&gspv
.ncm
.lfMenuFont
, L
"MenuFont", &lf1
);
248 SpiLoadFont(&gspv
.ncm
.lfStatusFont
, L
"StatusFont", &lf1
);
249 SpiLoadFont(&gspv
.ncm
.lfMessageFont
, L
"MessageFont", &lf1
);
251 /* Load MINIMIZEDMETRICS */
252 gspv
.mm
.cbSize
= sizeof(MINIMIZEDMETRICS
);
253 gspv
.mm
.iWidth
= SpiLoadMetric(L
"MinWidth", 160);
254 gspv
.mm
.iHorzGap
= SpiLoadMetric(L
"MinHorzGap", 160);
255 gspv
.mm
.iVertGap
= SpiLoadMetric(L
"MinVertGap", 24);
256 gspv
.mm
.iArrange
= SpiLoadInt(KEY_METRIC
, L
"MinArrange", ARW_HIDE
);
258 /* Load ICONMETRICS */
259 gspv
.im
.cbSize
= sizeof(ICONMETRICSW
);
260 gspv
.im
.iHorzSpacing
= SpiLoadMetric(VAL_ICONSPC
, 64);
261 gspv
.im
.iVertSpacing
= SpiLoadMetric(VAL_ICONVSPC
, 64);
262 gspv
.im
.iTitleWrap
= SpiLoadMetric(VAL_ITWRAP
, 0);
263 SpiLoadFont(&gspv
.im
.lfFont
, L
"IconFont", &lf1
);
265 /* Load desktop settings */
266 gspv
.bDragFullWindows
= SpiLoadInt(KEY_DESKTOP
, VAL_DRAG
, 0);
267 gspv
.iWheelScrollLines
= SpiLoadInt(KEY_DESKTOP
, VAL_SCRLLLINES
, 3);
268 gspv
.dwMouseClickLockTime
= SpiLoadDWord(KEY_DESKTOP
, VAL_CLICKLOCKTIME
, 1200);
269 gspv
.dwUserPrefMask
= SpiLoadUserPrefMask(UPM_DEFAULT
);
270 gspv
.bMouseClickLock
= (gspv
.dwUserPrefMask
& UPM_CLICKLOCK
) != 0;
271 gspv
.bMouseCursorShadow
= (gspv
.dwUserPrefMask
& UPM_CURSORSHADOW
) != 0;
272 #if (_WIN32_WINNT >= 0x0600)
273 gspv
.iWheelScrollChars
= SpiLoadInt(KEY_DESKTOP
, VAL_SCRLLCHARS
, 3);
276 /* Some hardcoded values for now */
278 gspv
.tmCaptionFont
.tmAveCharWidth
= 6;
280 gspv
.bFlatMenu
= FALSE
;
281 gspv
.uiFocusBorderWidth
= 1;
282 gspv
.uiFocusBorderHeight
= 1;
283 gspv
.bMenuDropAlign
= 1;
284 gspv
.bDropShadow
= 1;
285 gspv
.dwMenuShowDelay
= 100;
287 gspv
.iScrSaverTimeout
= SpiLoadTimeOut();
288 gspv
.bScrSaverActive
= FALSE
;
289 gspv
.bScrSaverRunning
= FALSE
;
290 #if(WINVER >= 0x0600)
291 gspv
.bScrSaverSecure
= FALSE
;
294 /* Make sure we don't use broken values */
297 /* Update SystemMetrics */
304 SpiUpdatePerUserSystemParameters();
305 gbSpiInitialized
= TRUE
;
312 NtUserUpdatePerUserSystemParameters(
318 TRACE("Enter NtUserUpdatePerUserSystemParameters\n");
319 UserEnterExclusive();
321 SpiUpdatePerUserSystemParameters();
322 bResult
= IntDesktopUpdatePerUserSettings(bEnable
);
324 TRACE("Leave NtUserUpdatePerUserSystemParameters, returning %d\n", bResult
);
331 /** Storing the settings ******************************************************/
335 SpiStoreDWord(PCWSTR pwszKey
, PCWSTR pwszValue
, DWORD Value
)
337 RegWriteUserSetting(pwszKey
,
346 SpiStoreSz(PCWSTR pwszKey
, PCWSTR pwszValue
, PCWSTR pwsz
)
348 RegWriteUserSetting(pwszKey
,
352 wcslen(pwsz
) * sizeof(WCHAR
));
357 SpiStoreSzInt(PCWSTR pwszKey
, PCWSTR pwszValue
, INT iValue
)
361 _itow(iValue
, awcBuffer
, 10);
362 RegWriteUserSetting(pwszKey
,
366 (wcslen(awcBuffer
) + 1) * sizeof(WCHAR
));
371 SpiStoreMetric(LPCWSTR pwszValue
, INT iValue
)
373 SpiStoreSzInt(KEY_METRIC
, pwszValue
, METRIC2REG(iValue
));
378 SpiStoreFont(PCWSTR pwszValue
, LOGFONTW
* plogfont
)
380 RegWriteUserSetting(KEY_METRIC
,
388 /** Get/Set value *************************************************************/
390 // FIXME: get rid of the flags and only use this from um. kernel can access data directly.
393 SpiMemCopy(PVOID pvDst
, PVOID pvSrc
, ULONG cbSize
, BOOL bProtect
, BOOL bToUser
)
395 NTSTATUS Status
= STATUS_SUCCESS
;
403 ProbeForWrite(pvDst
, cbSize
, 1);
407 ProbeForRead(pvSrc
, cbSize
, 1);
409 memcpy(pvDst
, pvSrc
, cbSize
);
411 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
413 Status
= _SEH2_GetExceptionCode();
419 memcpy(pvDst
, pvSrc
, cbSize
);
422 if (!NT_SUCCESS(Status
))
424 SetLastNtError(Status
);
425 TRACE("SpiMemCopy failed, pvDst=%p, pvSrc=%p, bProtect=%d, bToUser=%d\n", pvDst
, pvSrc
, bProtect
, bToUser
);
427 return NT_SUCCESS(Status
);
432 SpiGet(PVOID pvParam
, PVOID pvData
, ULONG cbSize
, FLONG fl
)
434 REQ_INTERACTIVE_WINSTA(ERROR_ACCESS_DENIED
);
435 return SpiMemCopy(pvParam
, pvData
, cbSize
, fl
& SPIF_PROTECT
, TRUE
);
440 SpiSet(PVOID pvData
, PVOID pvParam
, ULONG cbSize
, FLONG fl
)
442 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION
);
443 return SpiMemCopy(pvData
, pvParam
, cbSize
, fl
& SPIF_PROTECT
, FALSE
);
448 SpiGetEx(PVOID pvParam
, PVOID pvData
, ULONG cbSize
, FLONG fl
)
451 /* Get the cbSite member from UM memory */
452 if (!SpiSet(&cbBufSize
, pvParam
, sizeof(ULONG
), fl
))
454 /* Verify the correct size */
455 if (cbBufSize
!= cbSize
)
457 return SpiGet(pvParam
, pvData
, cbSize
, fl
);
462 SpiGetInt(PVOID pvParam
, PVOID piValue
, FLONG fl
)
464 return SpiGet(pvParam
, piValue
, sizeof(INT
), fl
);
469 SpiSetYesNo(BOOL
*pbData
, BOOL bValue
, PCWSTR pwszKey
, PCWSTR pwszValue
, FLONG fl
)
471 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION
);
472 *pbData
= bValue
? TRUE
: FALSE
;
473 if (fl
& SPIF_UPDATEINIFILE
)
475 SpiStoreSz(pwszKey
, pwszValue
, bValue
? L
"Yes" : L
"No");
477 return (UINT_PTR
)pwszKey
;
482 SpiSetBool(BOOL
*pbData
, INT iValue
, PCWSTR pwszKey
, PCWSTR pwszValue
, FLONG fl
)
484 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION
);
485 *pbData
= iValue
? TRUE
: FALSE
;
486 if (fl
& SPIF_UPDATEINIFILE
)
488 SpiStoreSzInt(pwszKey
, pwszValue
, iValue
);
490 return (UINT_PTR
)pwszKey
;
495 SpiSetDWord(PVOID pvData
, INT iValue
, PCWSTR pwszKey
, PCWSTR pwszValue
, FLONG fl
)
497 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION
);
498 *(INT
*)pvData
= iValue
;
499 if (fl
& SPIF_UPDATEINIFILE
)
501 SpiStoreDWord(pwszKey
, pwszValue
, iValue
);
503 return (UINT_PTR
)pwszKey
;
508 SpiSetInt(PVOID pvData
, INT iValue
, PCWSTR pwszKey
, PCWSTR pwszValue
, FLONG fl
)
510 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION
);
511 *(INT
*)pvData
= iValue
;
512 if (fl
& SPIF_UPDATEINIFILE
)
514 SpiStoreSzInt(pwszKey
, pwszValue
, iValue
);
516 return (UINT_PTR
)pwszKey
;
521 SpiSetMetric(PVOID pvData
, INT iValue
, PCWSTR pwszValue
, FLONG fl
)
523 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION
);
524 *(INT
*)pvData
= iValue
;
525 if (fl
& SPIF_UPDATEINIFILE
)
527 SpiStoreMetric(pwszValue
, iValue
);
529 return (UINT_PTR
)KEY_METRIC
;
534 SpiSetUserPref(DWORD dwMask
, PVOID pvValue
, FLONG fl
)
537 BOOL bValue
= (BOOL
)pvValue
;
539 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION
);
541 /* Set or clear bit according to bValue */
542 gspv
.dwUserPrefMask
= bValue
? gspv
.dwUserPrefMask
| dwMask
:
543 gspv
.dwUserPrefMask
& ~dwMask
;
545 if (fl
& SPIF_UPDATEINIFILE
)
547 /* Read current value */
548 RegReadUserSetting(KEY_DESKTOP
,
554 /* Set or clear bit according to bValue */
555 dwRegMask
= bValue
? dwRegMask
| dwMask
: dwRegMask
& ~dwMask
;
557 /* write back value */
558 RegWriteUserSetting(KEY_DESKTOP
,
565 return (UINT_PTR
)KEY_DESKTOP
;
570 SpiGetUserPref(DWORD dwMask
, PVOID pvParam
, FLONG fl
)
572 INT iValue
= gspv
.dwUserPrefMask
& dwMask
? 1 : 0;
573 return SpiGetInt(pvParam
, &iValue
, fl
);
578 SpiSetWallpaper(PVOID pvParam
, FLONG fl
)
583 HBITMAP hbmp
, hOldBitmap
;
585 ULONG ulTile
, ulStyle
;
587 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION
);
591 /* FIXME: Reset Wallpaper to registry value */
592 return (UINT_PTR
)KEY_DESKTOP
;
595 /* Capture UNICODE_STRING */
596 bResult
= SpiMemCopy(&ustr
, pvParam
, sizeof(UNICODE_STRING
), fl
& SPIF_PROTECT
, 0);
597 if (!bResult
) return 0;
598 if (ustr
.Length
> MAX_PATH
* sizeof(WCHAR
))
601 /* Copy the string buffer name */
602 bResult
= SpiMemCopy(gspv
.awcWallpaper
, ustr
.Buffer
, ustr
.Length
, fl
& SPIF_PROTECT
, 0);
603 if (!bResult
) return 0;
605 /* Update the UNICODE_STRING */
606 gspv
.ustrWallpaper
.Buffer
= gspv
.awcWallpaper
;
607 gspv
.ustrWallpaper
.MaximumLength
= MAX_PATH
* sizeof(WCHAR
);
608 gspv
.ustrWallpaper
.Length
= ustr
.Length
;
609 gspv
.awcWallpaper
[ustr
.Length
/ sizeof(WCHAR
)] = 0;
611 TRACE("SpiSetWallpaper, name=%S\n", gspv
.awcWallpaper
);
613 /* Update registry */
614 if (fl
& SPIF_UPDATEINIFILE
)
616 SpiStoreSz(KEY_DESKTOP
, L
"Wallpaper", gspv
.awcWallpaper
);
619 /* Got a filename? */
620 if (gspv
.awcWallpaper
[0] != 0)
622 /* Convert file name to nt file name */
624 ustr
.MaximumLength
= MAX_PATH
* sizeof(WCHAR
);
626 if (!W32kDosPathNameToNtPathName(gspv
.awcWallpaper
, &ustr
))
628 ERR("RtlDosPathNameToNtPathName_U failed\n");
632 /* Load the Bitmap */
633 hbmp
= UserLoadImage(ustr
.Buffer
);
636 ERR("UserLoadImage failed\n");
640 /* Try to get the size of the wallpaper */
641 if(!(psurfBmp
= SURFACE_ShareLockSurface(hbmp
)))
643 GreDeleteObject(hbmp
);
647 gpwinstaCurrent
->cxWallpaper
= psurfBmp
->SurfObj
.sizlBitmap
.cx
;
648 gpwinstaCurrent
->cyWallpaper
= psurfBmp
->SurfObj
.sizlBitmap
.cy
;
649 gpwinstaCurrent
->WallpaperMode
= wmCenter
;
651 SURFACE_ShareUnlockSurface(psurfBmp
);
653 /* Change the bitmap's ownership */
654 GreSetObjectOwner(hbmp
, GDI_OBJ_HMGR_PUBLIC
);
656 /* Yes, Windows really loads the current setting from the registry. */
657 ulTile
= SpiLoadInt(KEY_DESKTOP
, L
"TileWallpaper", 0);
658 ulStyle
= SpiLoadInt(KEY_DESKTOP
, L
"WallpaperStyle", 0);
659 TRACE("SpiSetWallpaper: ulTile=%ld, ulStyle=%d\n", ulTile
, ulStyle
);
661 /* Check the values we found in the registry */
662 if(ulTile
&& !ulStyle
)
664 gpwinstaCurrent
->WallpaperMode
= wmTile
;
666 else if(!ulTile
&& ulStyle
== 2)
668 gpwinstaCurrent
->WallpaperMode
= wmStretch
;
673 /* Remove wallpaper */
674 gpwinstaCurrent
->cxWallpaper
= 0;
675 gpwinstaCurrent
->cyWallpaper
= 0;
679 /* Take care of the old wallpaper, if any */
680 hOldBitmap
= gpwinstaCurrent
->hbmWallpaper
;
681 if(hOldBitmap
!= NULL
)
683 /* Delete the old wallpaper */
684 GreSetObjectOwner(hOldBitmap
, GDI_OBJ_HMGR_POWNED
);
685 GreDeleteObject(hOldBitmap
);
688 /* Set the new wallpaper */
689 gpwinstaCurrent
->hbmWallpaper
= hbmp
;
691 NtUserRedrawWindow(UserGetShellWindow(), NULL
, NULL
, RDW_INVALIDATE
| RDW_ERASE
);
694 return (UINT_PTR
)KEY_DESKTOP
;
699 SpiGetSet(UINT uiAction
, UINT uiParam
, PVOID pvParam
, FLONG fl
)
704 return SpiGetInt(pvParam
, &gspv
.bBeep
, fl
);
707 return SpiSetYesNo(&gspv
.bBeep
, uiParam
, KEY_SOUND
, VAL_BEEP
, fl
);
710 return SpiGet(pvParam
, &gspv
.caiMouse
, 3 * sizeof(INT
), fl
);
713 if (!SpiSet(&gspv
.caiMouse
, pvParam
, 3 * sizeof(INT
), fl
))
715 if (fl
& SPIF_UPDATEINIFILE
)
717 SpiStoreSzInt(KEY_MOUSE
, VAL_MOUSE1
, gspv
.caiMouse
.FirstThreshold
);
718 SpiStoreSzInt(KEY_MOUSE
, VAL_MOUSE2
, gspv
.caiMouse
.SecondThreshold
);
719 SpiStoreSzInt(KEY_MOUSE
, VAL_MOUSE3
, gspv
.caiMouse
.Acceleration
);
721 return (UINT_PTR
)KEY_MOUSE
;
724 return SpiGetInt(pvParam
, &gspv
.ncm
.iBorderWidth
, fl
);
727 uiParam
= max(uiParam
, 1);
728 return SpiSetInt(&gspv
.ncm
.iBorderWidth
, uiParam
, KEY_METRIC
, VAL_BORDER
, fl
);
730 case SPI_GETKEYBOARDSPEED
:
731 return SpiGetInt(pvParam
, &gspv
.dwKbdSpeed
, fl
);
733 case SPI_SETKEYBOARDSPEED
:
734 return SpiSetInt(&gspv
.dwKbdSpeed
, uiParam
, KEY_KBD
, VAL_KBDSPD
, fl
);
737 ERR("SPI_LANGDRIVER is unimplemented\n");
740 case SPI_GETSCREENSAVETIMEOUT
:
741 return SpiGetInt(pvParam
, &gspv
.iScrSaverTimeout
, fl
);
743 case SPI_SETSCREENSAVETIMEOUT
:
744 return SpiSetInt(&gspv
.iScrSaverTimeout
, uiParam
, KEY_DESKTOP
, VAL_SCRTO
, fl
);
746 case SPI_GETSCREENSAVEACTIVE
:
747 return SpiGetInt(pvParam
, &gspv
.bScrSaverActive
, fl
);
749 case SPI_SETSCREENSAVEACTIVE
:
750 return SpiSetInt(&gspv
.bScrSaverActive
, uiParam
, KEY_DESKTOP
, VAL_SCRACT
, fl
);
752 case SPI_GETGRIDGRANULARITY
:
753 return SpiGetInt(pvParam
, &gspv
.uiGridGranularity
, fl
);
755 case SPI_SETGRIDGRANULARITY
:
756 return SpiSetInt(&gspv
.uiGridGranularity
, uiParam
, KEY_DESKTOP
, VAL_GRID
, fl
);
758 case SPI_GETDESKWALLPAPER
:
759 uiParam
= min(uiParam
, gspv
.ustrWallpaper
.Length
+ 1);
760 return SpiGet(pvParam
, gspv
.awcWallpaper
, uiParam
, fl
);
762 case SPI_SETDESKWALLPAPER
:
763 return SpiSetWallpaper(pvParam
, fl
);
765 case SPI_SETDESKPATTERN
:
766 ERR("SPI_SETDESKPATTERN is unimplemented\n");
769 case SPI_GETKEYBOARDDELAY
:
770 return SpiGetInt(pvParam
, &gspv
.iKbdDelay
, fl
);
772 case SPI_SETKEYBOARDDELAY
:
773 return SpiSetInt(&gspv
.iKbdDelay
, uiParam
, KEY_KBD
, VAL_KBDDELAY
, fl
);
775 case SPI_ICONHORIZONTALSPACING
:
778 return SpiGetInt(pvParam
, &gspv
.im
.iHorzSpacing
, fl
);
780 uiParam
= max(uiParam
, 32);
781 return SpiSetMetric(&gspv
.im
.iHorzSpacing
, uiParam
, VAL_ICONSPC
, fl
);
783 case SPI_ICONVERTICALSPACING
:
786 return SpiGetInt(pvParam
, &gspv
.im
.iVertSpacing
, fl
);
788 uiParam
= max(uiParam
, 32);
789 return SpiSetMetric(&gspv
.im
.iVertSpacing
, uiParam
, VAL_ICONVSPC
, fl
);
791 case SPI_GETICONTITLEWRAP
:
792 return SpiGetInt(pvParam
, &gspv
.im
.iTitleWrap
, fl
);
794 case SPI_SETICONTITLEWRAP
:
795 return SpiSetInt(&gspv
.im
.iTitleWrap
, uiParam
, KEY_METRIC
, VAL_ITWRAP
, fl
);
797 case SPI_GETMENUDROPALIGNMENT
:
798 return SpiGetInt(pvParam
, &gspv
.bMenuDropAlign
, fl
);
800 case SPI_SETMENUDROPALIGNMENT
:
801 return SpiSetBool(&gspv
.bMenuDropAlign
, uiParam
, KEY_MDALIGN
, VAL_MDALIGN
, fl
);
803 case SPI_SETDOUBLECLKWIDTH
:
804 return SpiSetInt(&gspv
.iDblClickWidth
, uiParam
, KEY_MOUSE
, VAL_DBLCLKWIDTH
, fl
);
806 case SPI_SETDOUBLECLKHEIGHT
:
807 return SpiSetInt(&gspv
.iDblClickHeight
, uiParam
, KEY_MOUSE
, VAL_DBLCLKHEIGHT
, fl
);
809 case SPI_GETICONTITLELOGFONT
:
810 return SpiGet(pvParam
, &gspv
.im
.lfFont
, sizeof(LOGFONTW
), fl
);
812 case SPI_SETICONTITLELOGFONT
:
813 if (!SpiSet(&gspv
.im
.lfFont
, pvParam
, sizeof(LOGFONTW
), fl
))
815 if (fl
& SPIF_UPDATEINIFILE
)
817 SpiStoreFont(L
"IconFont", &gspv
.im
.lfFont
);
819 return (UINT_PTR
)KEY_METRIC
;
821 case SPI_SETDOUBLECLICKTIME
:
822 return SpiSetInt(&gspv
.iDblClickTime
, uiParam
, KEY_MOUSE
, VAL_DBLCLKTIME
, fl
);
824 case SPI_SETMOUSEBUTTONSWAP
:
825 return SpiSetInt(&gspv
.bMouseBtnSwap
, uiParam
, KEY_MOUSE
, VAL_SWAP
, fl
);
827 case SPI_GETFASTTASKSWITCH
:
828 return SpiGetInt(pvParam
, &gspv
.bFastTaskSwitch
, fl
);
830 case SPI_SETFASTTASKSWITCH
:
831 /* According to Winetest this one is unimplemented */
834 case SPI_GETDRAGFULLWINDOWS
:
835 return SpiGetInt(pvParam
, &gspv
.bDragFullWindows
, fl
);
837 case SPI_SETDRAGFULLWINDOWS
:
838 return SpiSetInt(&gspv
.bDragFullWindows
, uiParam
, KEY_DESKTOP
, VAL_DRAG
, fl
);
840 case SPI_GETNONCLIENTMETRICS
:
841 return SpiGet(pvParam
, &gspv
.ncm
, sizeof(NONCLIENTMETRICSW
), fl
);
843 case SPI_SETNONCLIENTMETRICS
:
844 if (!SpiSet(&gspv
.ncm
, pvParam
, sizeof(NONCLIENTMETRICSW
), fl
))
846 if (fl
& SPIF_UPDATEINIFILE
)
848 SpiStoreMetric(VAL_BORDER
, gspv
.ncm
.iBorderWidth
);
849 SpiStoreMetric(L
"ScrollWidth", gspv
.ncm
.iScrollWidth
);
850 SpiStoreMetric(L
"ScrollHeight", gspv
.ncm
.iScrollHeight
);
851 SpiStoreMetric(L
"CaptionWidth", gspv
.ncm
.iCaptionWidth
);
852 SpiStoreMetric(L
"CaptionHeight", gspv
.ncm
.iCaptionHeight
);
853 SpiStoreMetric(L
"SmCaptionWidth", gspv
.ncm
.iSmCaptionWidth
);
854 SpiStoreMetric(L
"SmCaptionHeight", gspv
.ncm
.iSmCaptionHeight
);
855 SpiStoreMetric(L
"MenuWidth", gspv
.ncm
.iMenuWidth
);
856 SpiStoreMetric(L
"MenuHeight", gspv
.ncm
.iMenuHeight
);
857 #if (WINVER >= 0x0600)
858 SpiStoreMetric(L
"PaddedBorderWidth", gspv
.ncm
.iPaddedBorderWidth
);
860 SpiStoreFont(L
"CaptionFont", &gspv
.ncm
.lfCaptionFont
);
861 SpiStoreFont(L
"SmCaptionFont", &gspv
.ncm
.lfSmCaptionFont
);
862 SpiStoreFont(L
"MenuFont", &gspv
.ncm
.lfMenuFont
);
863 SpiStoreFont(L
"StatusFont", &gspv
.ncm
.lfStatusFont
);
864 SpiStoreFont(L
"MessageFont", &gspv
.ncm
.lfMessageFont
);
866 return (UINT_PTR
)KEY_METRIC
;
868 case SPI_GETMINIMIZEDMETRICS
:
869 return SpiGet(pvParam
, &gspv
.mm
, sizeof(MINIMIZEDMETRICS
), fl
);
871 case SPI_SETMINIMIZEDMETRICS
:
872 if (!SpiSet(&gspv
.mm
, pvParam
, sizeof(MINIMIZEDMETRICS
), fl
))
874 gspv
.mm
.iWidth
= max(0, gspv
.mm
.iWidth
);
875 gspv
.mm
.iHorzGap
= max(0, gspv
.mm
.iHorzGap
);
876 gspv
.mm
.iVertGap
= max(0, gspv
.mm
.iVertGap
);
877 gspv
.mm
.iArrange
= gspv
.mm
.iArrange
& 0xf;
878 if (fl
& SPIF_UPDATEINIFILE
)
880 SpiStoreMetric(L
"MinWidth", gspv
.mm
.iWidth
);
881 SpiStoreMetric(L
"MinHorzGap", gspv
.mm
.iHorzGap
);
882 SpiStoreMetric(L
"MinVertGap", gspv
.mm
.iVertGap
);
883 SpiStoreMetric(L
"MinArrange", gspv
.mm
.iArrange
);
885 return (UINT_PTR
)KEY_METRIC
;
887 case SPI_GETICONMETRICS
:
888 return SpiGet(pvParam
, &gspv
.im
, sizeof(ICONMETRICS
), fl
);
890 case SPI_SETICONMETRICS
:
891 if (!SpiSet(&gspv
.im
, pvParam
, sizeof(ICONMETRICS
), fl
))
893 if (fl
& SPIF_UPDATEINIFILE
)
895 SpiStoreMetric(VAL_ICONSPC
, gspv
.im
.iHorzSpacing
);
896 SpiStoreMetric(VAL_ICONVSPC
, gspv
.im
.iVertSpacing
);
897 SpiStoreMetric(VAL_ITWRAP
, gspv
.im
.iTitleWrap
);
898 SpiStoreFont(L
"IconFont", &gspv
.im
.lfFont
);
900 return (UINT_PTR
)KEY_METRIC
;
902 case SPI_GETWORKAREA
:
904 PMONITOR pmonitor
= IntGetPrimaryMonitor();
909 return SpiGet(pvParam
, &pmonitor
->rcWork
, sizeof(RECTL
), fl
);
912 case SPI_SETWORKAREA
:
914 /*FIXME: we should set the work area of the monitor
915 that contains the specified rectangle*/
916 PMONITOR pmonitor
= IntGetPrimaryMonitor();
922 if (!SpiSet(&rcWorkArea
, pvParam
, sizeof(RECTL
), fl
))
925 /* Verify the new values */
926 if (rcWorkArea
.left
< 0 ||
927 rcWorkArea
.top
< 0 ||
928 rcWorkArea
.right
> gpsi
->aiSysMet
[SM_CXSCREEN
] ||
929 rcWorkArea
.bottom
> gpsi
->aiSysMet
[SM_CYSCREEN
] ||
930 rcWorkArea
.right
<= rcWorkArea
.left
||
931 rcWorkArea
.bottom
<= rcWorkArea
.top
)
934 pmonitor
->rcWork
= rcWorkArea
;
935 if (fl
& SPIF_UPDATEINIFILE
)
937 // FIXME: what to do?
939 return (UINT_PTR
)KEY_DESKTOP
;
942 case SPI_SETPENWINDOWS
:
943 ERR("SPI_SETPENWINDOWS is unimplemented\n");
946 case SPI_GETFILTERKEYS
:
947 return SpiGet(pvParam
, &gspv
.filterkeys
, sizeof(FILTERKEYS
), fl
);
949 case SPI_SETFILTERKEYS
:
950 if (!SpiSet(&gspv
.filterkeys
, pvParam
, sizeof(FILTERKEYS
), fl
))
952 if (fl
& SPIF_UPDATEINIFILE
)
954 // FIXME: what to do?
956 return (UINT_PTR
)KEY_DESKTOP
;
958 case SPI_GETTOGGLEKEYS
:
959 return SpiGet(pvParam
, &gspv
.togglekeys
, sizeof(TOGGLEKEYS
), fl
);
961 case SPI_SETTOGGLEKEYS
:
962 if (!SpiSet(&gspv
.togglekeys
, pvParam
, sizeof(TOGGLEKEYS
), fl
))
964 if (fl
& SPIF_UPDATEINIFILE
)
966 // FIXME: what to do?
968 return (UINT_PTR
)KEY_DESKTOP
;
970 case SPI_GETMOUSEKEYS
:
971 return SpiGet(pvParam
, &gspv
.mousekeys
, sizeof(MOUSEKEYS
), fl
);
973 case SPI_SETMOUSEKEYS
:
974 if (!SpiSet(&gspv
.mousekeys
, pvParam
, sizeof(MOUSEKEYS
), fl
))
976 if (fl
& SPIF_UPDATEINIFILE
)
978 // FIXME: what to do?
980 return (UINT_PTR
)KEY_DESKTOP
;
982 case SPI_GETSHOWSOUNDS
:
983 return SpiGetInt(pvParam
, &gspv
.bShowSounds
, fl
);
985 case SPI_SETSHOWSOUNDS
:
986 return SpiSetBool(&gspv
.bShowSounds
, uiParam
, KEY_SHOWSNDS
, VAL_ON
, fl
);
988 case SPI_GETSTICKYKEYS
:
989 if (uiParam
!= sizeof(STICKYKEYS
))
991 return SpiGetEx(pvParam
, &gspv
.stickykeys
, sizeof(STICKYKEYS
), fl
);
993 case SPI_SETSTICKYKEYS
:
994 if (!SpiSet(&gspv
.stickykeys
, pvParam
, sizeof(STICKYKEYS
), fl
))
996 if (fl
& SPIF_UPDATEINIFILE
)
998 // FIXME: what to do?
1000 return (UINT_PTR
)KEY_DESKTOP
;
1002 case SPI_GETACCESSTIMEOUT
:
1003 if (uiParam
!= 0 && uiParam
!= sizeof(ACCESSTIMEOUT
))
1005 return SpiGetEx(pvParam
, &gspv
.accesstimeout
, sizeof(ACCESSTIMEOUT
), fl
);
1007 case SPI_SETACCESSTIMEOUT
:
1008 if (!SpiSet(&gspv
.accesstimeout
, pvParam
, sizeof(ACCESSTIMEOUT
), fl
))
1010 if (fl
& SPIF_UPDATEINIFILE
)
1012 // FIXME: what to do?
1014 return (UINT_PTR
)KEY_DESKTOP
;
1016 case SPI_GETSERIALKEYS
:
1017 return SpiGet(pvParam
, &gspv
.serialkeys
, sizeof(SERIALKEYS
), fl
);
1019 case SPI_SETSERIALKEYS
:
1020 if (!SpiSet(&gspv
.serialkeys
, pvParam
, sizeof(SERIALKEYS
), fl
))
1022 if (fl
& SPIF_UPDATEINIFILE
)
1024 // FIXME: what to do?
1026 return (UINT_PTR
)KEY_DESKTOP
;
1028 case SPI_GETSOUNDSENTRY
:
1029 return SpiGet(pvParam
, &gspv
.soundsentry
, sizeof(SOUNDSENTRY
), fl
);
1031 case SPI_SETSOUNDSENTRY
:
1032 if (!SpiSet(&gspv
.soundsentry
, pvParam
, sizeof(SOUNDSENTRY
), fl
))
1034 if (fl
& SPIF_UPDATEINIFILE
)
1036 // FIXME: what to do?
1038 return (UINT_PTR
)KEY_DESKTOP
;
1040 case SPI_GETHIGHCONTRAST
:
1041 return SpiGet(pvParam
, &gspv
.highcontrast
, sizeof(HIGHCONTRAST
), fl
);
1043 case SPI_SETHIGHCONTRAST
:
1044 if (!SpiSet(&gspv
.highcontrast
, pvParam
, sizeof(HIGHCONTRAST
), fl
))
1046 if (fl
& SPIF_UPDATEINIFILE
)
1048 // FIXME: what to do?
1050 return (UINT_PTR
)KEY_DESKTOP
;
1052 case SPI_GETKEYBOARDPREF
:
1053 return SpiGetInt(pvParam
, &gspv
.bKbdPref
, fl
);
1055 case SPI_SETKEYBOARDPREF
:
1056 return SpiSetBool(&gspv
.bKbdPref
, uiParam
, KEY_KDBPREF
, VAL_ON
, fl
);
1058 case SPI_GETSCREENREADER
:
1059 return SpiGetInt(pvParam
, &gspv
.bScreenReader
, fl
);
1061 case SPI_SETSCREENREADER
:
1062 return SpiSetBool(&gspv
.bScreenReader
, uiParam
, KEY_SCRREAD
, VAL_ON
, fl
);
1064 case SPI_GETANIMATION
:
1065 return SpiGet(pvParam
, &gspv
.animationinfo
, sizeof(ANIMATIONINFO
), fl
);
1067 case SPI_SETANIMATION
:
1068 if (!SpiSet(&gspv
.animationinfo
, pvParam
, sizeof(ANIMATIONINFO
), fl
))
1070 if (fl
& SPIF_UPDATEINIFILE
)
1072 // FIXME: what to do?
1074 return (UINT_PTR
)KEY_DESKTOP
;
1076 case SPI_GETFONTSMOOTHING
:
1077 return SpiGetInt(pvParam
, &gspv
.bFontSmoothing
, fl
);
1079 case SPI_SETFONTSMOOTHING
:
1080 gspv
.bFontSmoothing
= uiParam
? TRUE
: FALSE
;
1081 if (fl
& SPIF_UPDATEINIFILE
)
1083 SpiStoreSzInt(KEY_DESKTOP
, VAL_FNTSMOOTH
, uiParam
? 2 : 0);
1085 return (UINT_PTR
)KEY_DESKTOP
;
1087 case SPI_SETDRAGWIDTH
:
1088 return SpiSetInt(&gspv
.iDragWidth
, uiParam
, KEY_DESKTOP
, VAL_DRAGWIDTH
, fl
);
1090 case SPI_SETDRAGHEIGHT
:
1091 return SpiSetInt(&gspv
.iDragHeight
, uiParam
, KEY_DESKTOP
, VAL_DRAGHEIGHT
, fl
);
1093 case SPI_SETHANDHELD
:
1094 return SpiSetBool(&gspv
.bHandHeld
, uiParam
, KEY_DESKTOP
, L
"HandHeld", fl
);
1096 case SPI_GETLOWPOWERTIMEOUT
:
1097 return SpiGetInt(pvParam
, &gspv
.iLowPwrTimeout
, fl
);
1099 case SPI_GETPOWEROFFTIMEOUT
:
1100 return SpiGetInt(pvParam
, &gspv
.iPwrOffTimeout
, fl
);
1102 case SPI_SETLOWPOWERTIMEOUT
:
1103 return SpiSetInt(&gspv
.iLowPwrTimeout
, uiParam
, KEY_DESKTOP
, L
"LowPowerTimeOut", fl
);
1105 case SPI_SETPOWEROFFTIMEOUT
:
1106 return SpiSetInt(&gspv
.iPwrOffTimeout
, uiParam
, KEY_DESKTOP
, L
"PowerOffTimeOut", fl
);
1108 case SPI_GETLOWPOWERACTIVE
:
1109 return SpiGetInt(pvParam
, &gspv
.iPwrOffTimeout
, fl
);
1111 case SPI_GETPOWEROFFACTIVE
:
1112 return SpiGetInt(pvParam
, &gspv
.bPwrOffActive
, fl
);
1114 case SPI_SETLOWPOWERACTIVE
:
1115 return SpiSetBool(&gspv
.bLowPwrActive
, uiParam
, KEY_DESKTOP
, L
"LowPowerActive", fl
);
1117 case SPI_SETPOWEROFFACTIVE
:
1118 return SpiSetBool(&gspv
.bPwrOffActive
, uiParam
, KEY_DESKTOP
, L
"PowerOffActive", fl
);
1120 case SPI_SETCURSORS
:
1121 ERR("SPI_SETCURSORS is unimplemented\n");
1125 ERR("SPI_SETICONS is unimplemented\n");
1128 case SPI_GETDEFAULTINPUTLANG
:
1129 ERR("SPI_GETDEFAULTINPUTLANG is unimplemented\n");
1132 case SPI_SETDEFAULTINPUTLANG
:
1133 ERR("SPI_SETDEFAULTINPUTLANG is unimplemented\n");
1136 case SPI_SETLANGTOGGLE
:
1137 ERR("SPI_SETLANGTOGGLE is unimplemented\n");
1140 case SPI_GETWINDOWSEXTENSION
:
1141 ERR("SPI_GETWINDOWSEXTENSION is unimplemented\n");
1144 case SPI_GETMOUSETRAILS
:
1145 return SpiGetInt(pvParam
, &gspv
.iMouseTrails
, fl
);
1147 case SPI_SETMOUSETRAILS
:
1148 return SpiSetInt(&gspv
.iMouseTrails
, uiParam
, KEY_MOUSE
, VAL_MOUSETRAILS
, fl
);
1150 case SPI_GETSNAPTODEFBUTTON
:
1151 return SpiGetInt(pvParam
, &gspv
.bSnapToDefBtn
, fl
);
1153 case SPI_SETSNAPTODEFBUTTON
:
1154 return SpiSetBool(&gspv
.bSnapToDefBtn
, uiParam
, KEY_MOUSE
, VAL_SNAPDEFBTN
, fl
);
1156 case SPI_GETMOUSEHOVERWIDTH
:
1157 return SpiGetInt(pvParam
, &gspv
.iMouseHoverWidth
, fl
);
1159 case SPI_SETMOUSEHOVERWIDTH
:
1160 return SpiSetInt(&gspv
.iMouseHoverWidth
, uiParam
, KEY_MOUSE
, VAL_HOVERWIDTH
, fl
);
1162 case SPI_GETMOUSEHOVERHEIGHT
:
1163 return SpiGetInt(pvParam
, &gspv
.iMouseHoverHeight
, fl
);
1165 case SPI_SETMOUSEHOVERHEIGHT
:
1166 return SpiSetInt(&gspv
.iMouseHoverHeight
, uiParam
, KEY_MOUSE
, VAL_HOVERHEIGHT
, fl
);
1168 case SPI_GETMOUSEHOVERTIME
:
1169 return SpiGetInt(pvParam
, &gspv
.iMouseHoverTime
, fl
);
1171 case SPI_SETMOUSEHOVERTIME
:
1172 /* see http://msdn2.microsoft.com/en-us/library/ms724947.aspx
1173 * copy text from it, if some agument why xp and 2003 behovir diffent
1174 * only if they do not have SP install
1175 * " Windows Server 2003 and Windows XP: The operating system does not
1176 * enforce the use of USER_TIMER_MAXIMUM and USER_TIMER_MINIMUM until
1177 * Windows Server 2003 SP1 and Windows XP SP2 "
1179 return SpiSetInt(&gspv
.iMouseHoverTime
, uiParam
, KEY_MOUSE
, VAL_HOVERTIME
, fl
);
1181 case SPI_GETWHEELSCROLLLINES
:
1182 return SpiGetInt(pvParam
, &gspv
.iWheelScrollLines
, fl
);
1184 case SPI_SETWHEELSCROLLLINES
:
1185 return SpiSetInt(&gspv
.iWheelScrollLines
, uiParam
, KEY_DESKTOP
, VAL_SCRLLLINES
, fl
);
1187 case SPI_GETMENUSHOWDELAY
:
1188 return SpiGetInt(pvParam
, &gspv
.dwMenuShowDelay
, fl
);
1190 case SPI_SETMENUSHOWDELAY
:
1191 return SpiSetInt(&gspv
.dwMenuShowDelay
, uiParam
, KEY_DESKTOP
, L
"MenuShowDelay", fl
);
1193 #if (_WIN32_WINNT >= 0x0600)
1194 case SPI_GETWHEELSCROLLCHARS
:
1195 return SpiGetInt(pvParam
, &gspv
.uiWheelScrollChars
, fl
);
1197 case SPI_SETWHEELSCROLLCHARS
:
1198 return SpiSetInt(&gspv
.uiWheelScrollChars
, uiParam
, KEY_DESKTOP
, VAL_SCRLLCHARS
, fl
);
1200 case SPI_GETSHOWIMEUI
:
1201 return SpiGetInt(pvParam
, &gspv
.bShowImeUi
, fl
);
1203 case SPI_SETSHOWIMEUI
:
1204 return SpiSetBool(&gspv
.bShowImeUi
, uiParam
, KEY_DESKTOP
, L
"", fl
);
1206 case SPI_GETMOUSESPEED
:
1207 return SpiGetInt(pvParam
, &gspv
.iMouseSpeed
, fl
);
1209 case SPI_SETMOUSESPEED
:
1211 return SpiSetInt(&gspv
.iMouseSpeed
, uiParam
, KEY_MOUSE
, VAL_MOUSE3
, fl
);
1213 case SPI_GETSCREENSAVERRUNNING
:
1214 return SpiGetInt(pvParam
, &gspv
.bScrSaverRunning
, fl
);
1216 case SPI_SETSCREENSAVERRUNNING
:
1217 // FIXME: also return value?
1218 return SpiSetBool(&gspv
.bScrSaverRunning
, uiParam
, KEY_MOUSE
, L
"", fl
);
1220 #if(WINVER >= 0x0600)
1221 case SPI_GETAUDIODESCRIPTION
:
1222 return SpiGet(pvParam
, &gspv
.audiodesription
, sizeof(AUDIODESCRIPTION
), fl
);
1224 case SPI_SETAUDIODESCRIPTION
:
1225 ERR("SPI_SETAUDIODESCRIPTION is unimplemented\n");
1228 case SPI_GETSCREENSAVESECURE
:
1229 return SpiGetInt(pvParam
, &gspv
.bScrSaverSecure
, fl
);
1231 case SPI_SETSCREENSAVESECURE
:
1232 return SpiSetBool(&gspv
.bScrSaverSecure
, uiParam
, KEY_DESKTOP
, L
"ScreenSaverIsSecure", fl
);
1235 case SPI_GETACTIVEWINDOWTRACKING
:
1236 return SpiGetUserPref(UPM_ACTIVEWINDOWTRACKING
, pvParam
, fl
);
1238 case SPI_SETACTIVEWINDOWTRACKING
:
1239 return SpiSetUserPref(UPM_ACTIVEWINDOWTRACKING
, pvParam
, fl
);
1241 case SPI_GETMENUANIMATION
:
1242 return SpiGetUserPref(UPM_MENUANIMATION
, pvParam
, fl
);
1244 case SPI_SETMENUANIMATION
:
1245 return SpiSetUserPref(UPM_MENUANIMATION
, pvParam
, fl
);
1247 case SPI_GETCOMBOBOXANIMATION
:
1248 return SpiGetUserPref(UPM_COMBOBOXANIMATION
, pvParam
, fl
);
1250 case SPI_SETCOMBOBOXANIMATION
:
1251 return SpiSetUserPref(UPM_COMBOBOXANIMATION
, pvParam
, fl
);
1253 case SPI_GETLISTBOXSMOOTHSCROLLING
:
1254 return SpiGetUserPref(UPM_LISTBOXSMOOTHSCROLLING
, pvParam
, fl
);
1256 case SPI_SETLISTBOXSMOOTHSCROLLING
:
1257 return SpiSetUserPref(UPM_LISTBOXSMOOTHSCROLLING
, pvParam
, fl
);
1259 case SPI_GETGRADIENTCAPTIONS
:
1260 return SpiGetUserPref(UPM_GRADIENTCAPTIONS
, pvParam
, fl
);
1262 case SPI_SETGRADIENTCAPTIONS
:
1263 return SpiSetUserPref(UPM_GRADIENTCAPTIONS
, pvParam
, fl
);
1265 case SPI_GETKEYBOARDCUES
:
1266 return SpiGetUserPref(UPM_KEYBOARDCUES
, pvParam
, fl
);
1268 case SPI_SETKEYBOARDCUES
:
1269 return SpiSetUserPref(UPM_KEYBOARDCUES
, pvParam
, fl
);
1271 case SPI_GETACTIVEWNDTRKZORDER
:
1272 return SpiGetUserPref(UPM_ACTIVEWNDTRKZORDER
, pvParam
, fl
);
1274 case SPI_SETACTIVEWNDTRKZORDER
:
1275 return SpiSetUserPref(UPM_ACTIVEWNDTRKZORDER
, pvParam
, fl
);
1277 case SPI_GETHOTTRACKING
:
1278 return SpiGetUserPref(UPM_HOTTRACKING
, pvParam
, fl
);
1280 case SPI_SETHOTTRACKING
:
1281 return SpiSetUserPref(UPM_HOTTRACKING
, pvParam
, fl
);
1283 case SPI_GETMENUFADE
:
1284 return SpiGetUserPref(UPM_MENUFADE
, pvParam
, fl
);
1286 case SPI_SETMENUFADE
:
1287 return SpiSetUserPref(UPM_MENUFADE
, pvParam
, fl
);
1289 case SPI_GETSELECTIONFADE
:
1290 return SpiGetUserPref(UPM_SELECTIONFADE
, pvParam
, fl
);
1292 case SPI_SETSELECTIONFADE
:
1293 return SpiSetUserPref(UPM_SELECTIONFADE
, pvParam
, fl
);
1295 case SPI_GETTOOLTIPANIMATION
:
1296 return SpiGetUserPref(UPM_TOOLTIPANIMATION
, pvParam
, fl
);
1298 case SPI_SETTOOLTIPANIMATION
:
1299 return SpiSetUserPref(UPM_TOOLTIPANIMATION
, pvParam
, fl
);
1301 case SPI_GETTOOLTIPFADE
:
1302 return SpiGetUserPref(UPM_TOOLTIPFADE
, pvParam
, fl
);
1304 case SPI_SETTOOLTIPFADE
:
1305 return SpiSetUserPref(UPM_TOOLTIPFADE
, pvParam
, fl
);
1307 case SPI_GETCURSORSHADOW
:
1308 return SpiGetUserPref(UPM_CURSORSHADOW
, pvParam
, fl
);
1310 case SPI_SETCURSORSHADOW
:
1311 gspv
.bMouseCursorShadow
= (BOOL
)pvParam
;
1312 return SpiSetUserPref(UPM_CURSORSHADOW
, pvParam
, fl
);
1314 case SPI_GETUIEFFECTS
:
1315 return SpiGetUserPref(UPM_UIEFFECTS
, pvParam
, fl
);
1317 case SPI_SETUIEFFECTS
:
1318 return SpiSetUserPref(UPM_UIEFFECTS
, pvParam
, fl
);
1320 case SPI_GETMOUSESONAR
:
1321 return SpiGetInt(pvParam
, &gspv
.bMouseSonar
, fl
);
1323 case SPI_SETMOUSESONAR
:
1324 return SpiSetBool(&gspv
.bMouseSonar
, uiParam
, KEY_MOUSE
, L
"", fl
);
1326 case SPI_GETMOUSECLICKLOCK
:
1327 return SpiGetUserPref(UPM_CLICKLOCK
, pvParam
, fl
);
1329 case SPI_SETMOUSECLICKLOCK
:
1330 gspv
.bMouseClickLock
= (BOOL
)pvParam
;
1331 return SpiSetUserPref(UPM_CLICKLOCK
, pvParam
, fl
);
1333 case SPI_GETMOUSEVANISH
:
1334 return SpiGetInt(pvParam
, &gspv
.bMouseVanish
, fl
);
1336 case SPI_SETMOUSEVANISH
:
1337 return SpiSetBool(&gspv
.bMouseVanish
, uiParam
, KEY_MOUSE
, L
"", fl
);
1339 case SPI_GETFLATMENU
:
1340 return SpiGetInt(pvParam
, &gspv
.bFlatMenu
, fl
);
1342 case SPI_SETFLATMENU
:
1343 return SpiSetBool(&gspv
.bFlatMenu
, uiParam
, KEY_MOUSE
, L
"", fl
);
1345 case SPI_GETDROPSHADOW
:
1346 return SpiGetInt(pvParam
, &gspv
.bDropShadow
, fl
);
1348 case SPI_SETDROPSHADOW
:
1349 return SpiSetBool(&gspv
.bDropShadow
, uiParam
, KEY_MOUSE
, L
"", fl
);
1351 case SPI_GETBLOCKSENDINPUTRESETS
:
1352 return SpiGetInt(pvParam
, &gspv
.bBlockSendInputResets
, fl
);
1354 case SPI_SETBLOCKSENDINPUTRESETS
:
1355 return SpiSetBool(&gspv
.bBlockSendInputResets
, uiParam
, KEY_MOUSE
, L
"", fl
);
1357 #if(_WIN32_WINNT >= 0x0600)
1358 case SPI_GETDISABLEOVERLAPPEDCONTENT
:
1359 return SpiGetInt(pvParam
, &gspv
.bDisableOverlappedContent
, fl
);
1361 case SPI_SETDISABLEOVERLAPPEDCONTENT
:
1362 return SpiSetBool(&gspv
.bDisableOverlappedContent
, uiParam
, KEY_MOUSE
, L
"", fl
);
1364 case SPI_GETCLIENTAREAANIMATION
:
1365 return SpiGetInt(pvParam
, &gspv
.bClientAnimation
, fl
);
1367 case SPI_SETCLIENTAREAANIMATION
:
1368 return SpiSetBool(&gspv
.bClientAnimation
, uiParam
, KEY_MOUSE
, L
"", fl
);
1370 case SPI_GETCLEARTYPE
:
1371 return SpiGetInt(pvParam
, &gspv
.bClearType
, fl
);
1373 case SPI_SETCLEARTYPE
:
1374 return SpiSetBool(&gspv
.bClearType
, uiParam
, KEY_MOUSE
, L
"", fl
);
1376 case SPI_GETSPEECHRECOGNITION
:
1377 return SpiGetInt(pvParam
, &gspv
.bSpeechRecognition
, fl
);
1379 case SPI_SETSPEECHRECOGNITION
:
1380 return SpiSetBool(&gspv
.bSpeechRecognition
, uiParam
, KEY_MOUSE
, L
"", fl
);
1383 case SPI_GETFOREGROUNDLOCKTIMEOUT
:
1384 return SpiGetInt(pvParam
, &gspv
.dwForegroundLockTimeout
, fl
);
1386 case SPI_SETFOREGROUNDLOCKTIMEOUT
:
1387 return SpiSetInt(&gspv
.dwForegroundLockTimeout
, uiParam
, KEY_MOUSE
, L
"", fl
);
1389 case SPI_GETACTIVEWNDTRKTIMEOUT
:
1390 return SpiGetInt(pvParam
, &gspv
.dwActiveTrackingTimeout
, fl
);
1392 case SPI_SETACTIVEWNDTRKTIMEOUT
:
1393 return SpiSetInt(&gspv
.dwActiveTrackingTimeout
, uiParam
, KEY_MOUSE
, L
"", fl
);
1395 case SPI_GETFOREGROUNDFLASHCOUNT
:
1396 return SpiGetInt(pvParam
, &gspv
.dwForegroundFlashCount
, fl
);
1398 case SPI_SETFOREGROUNDFLASHCOUNT
:
1399 return SpiSetInt(&gspv
.dwForegroundFlashCount
, uiParam
, KEY_MOUSE
, L
"", fl
);
1401 case SPI_GETCARETWIDTH
:
1402 return SpiGetInt(pvParam
, &gspv
.dwCaretWidth
, fl
);
1404 case SPI_SETCARETWIDTH
:
1405 return SpiSetInt(&gspv
.dwCaretWidth
, uiParam
, KEY_MOUSE
, L
"", fl
);
1407 case SPI_GETMOUSECLICKLOCKTIME
:
1408 return SpiGetInt(pvParam
, &gspv
.dwMouseClickLockTime
, fl
);
1410 case SPI_SETMOUSECLICKLOCKTIME
:
1411 return SpiSetDWord(&gspv
.dwMouseClickLockTime
, uiParam
, KEY_DESKTOP
, VAL_CLICKLOCKTIME
, fl
);
1413 case SPI_GETFONTSMOOTHINGTYPE
:
1414 return SpiGetInt(pvParam
, &gspv
.uiFontSmoothingType
, fl
);
1416 case SPI_SETFONTSMOOTHINGTYPE
:
1417 return SpiSetInt(&gspv
.uiFontSmoothingType
, uiParam
, KEY_MOUSE
, L
"", fl
);
1419 case SPI_GETFONTSMOOTHINGCONTRAST
:
1420 return SpiGetInt(pvParam
, &gspv
.uiFontSmoothingContrast
, fl
);
1422 case SPI_SETFONTSMOOTHINGCONTRAST
:
1423 return SpiSetInt(&gspv
.uiFontSmoothingContrast
, uiParam
, KEY_MOUSE
, L
"", fl
);
1425 case SPI_GETFOCUSBORDERWIDTH
:
1426 return SpiGetInt(pvParam
, &gspv
.uiFocusBorderWidth
, fl
);
1428 case SPI_SETFOCUSBORDERWIDTH
:
1429 return SpiSetInt(&gspv
.uiFocusBorderWidth
, uiParam
, KEY_MOUSE
, L
"", fl
);
1431 case SPI_GETFOCUSBORDERHEIGHT
:
1432 return SpiGetInt(pvParam
, &gspv
.uiFocusBorderHeight
, fl
);
1434 case SPI_SETFOCUSBORDERHEIGHT
:
1435 return SpiSetInt(&gspv
.uiFocusBorderHeight
, uiParam
, KEY_MOUSE
, L
"", fl
);
1437 case SPI_GETFONTSMOOTHINGORIENTATION
:
1438 return SpiGetInt(pvParam
, &gspv
.uiFontSmoothingOrientation
, fl
);
1440 case SPI_SETFONTSMOOTHINGORIENTATION
:
1441 return SpiSetInt(&gspv
.uiFontSmoothingOrientation
, uiParam
, KEY_MOUSE
, L
"", fl
);
1443 /* The following are undocumented, but valid SPI values */
1468 ERR("Undocumented SPI value %x is unimplemented\n", uiAction
);
1472 ERR("Invalid SPI value: %d\n", uiAction
);
1473 EngSetLastError(ERROR_INVALID_PARAMETER
);
1482 UserSystemParametersInfo(
1490 if (!gbSpiInitialized
)
1492 KeRosDumpStackFrames(NULL
, 20);
1496 /* Get a pointer to the current Windowstation */
1497 gpwinstaCurrent
= IntGetWinStaObj();
1499 if (!gpwinstaCurrent
)
1501 ERR("UserSystemParametersInfo called without active windowstation.\n");
1502 //KeRosDumpStackFrames(NULL, 0);
1505 /* Do the actual operation */
1506 ulResult
= SpiGetSet(uiAction
, uiParam
, pvParam
, fWinIni
);
1508 /* Did we change something? */
1513 /* Update system metrics */
1516 /* Send notification to toplevel windows, if requested */
1517 if (fWinIni
& (SPIF_SENDCHANGE
| SPIF_SENDWININICHANGE
))
1519 /* Send WM_SETTINGCHANGE to all toplevel windows */
1520 co_IntSendMessageTimeout(HWND_BROADCAST
,
1531 /* Dereference the windowstation */
1532 if (gpwinstaCurrent
)
1534 ObDereferenceObject(gpwinstaCurrent
);
1535 gpwinstaCurrent
= NULL
;
1543 NtUserSystemParametersInfo(
1551 TRACE("Enter NtUserSystemParametersInfo(%d)\n", uiAction
);
1552 UserEnterExclusive();
1554 // FIXME: get rid of the flags and only use this from um. kernel can access data directly.
1555 /* Set UM memory protection flag */
1556 fWinIni
|= SPIF_PROTECT
;
1558 /* Call internal function */
1559 bResult
= UserSystemParametersInfo(uiAction
, uiParam
, pvParam
, fWinIni
);
1561 TRACE("Leave NtUserSystemParametersInfo, returning %d\n", bResult
);