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
21 #define KeRosDumpStackFrames(Frames, Count) KdSystemDebugControl('DsoR', (PVOID)Frames, Count, NULL, 0, NULL, KernelMode)
22 HBITMAP NTAPI
UserLoadImage(PCWSTR
);
23 BOOL NTAPI
W32kDosPathNameToNtPathName(PCWSTR
, PUNICODE_STRING
);
27 BOOL gbSpiInitialized
= FALSE
;
28 PWINSTATION_OBJECT gpwinstaCurrent
= NULL
;
30 // HACK! We initialize SPI before we have a proper surface to get this from.
32 //(pPrimarySurface->GDIInfo.ulLogPixelsY)
33 #define REG2METRIC(reg) (reg > 0 ? reg : ((-(reg) * dpi + 720) / 1440))
34 #define METRIC2REG(met) (-((((met) * 1440)- 0) / dpi))
36 #define REQ_INTERACTIVE_WINSTA(err) \
37 if (gpwinstaCurrent != InputWindowStation) \
39 SetLastWin32Error(err); \
43 #define DPRINTX if (gbDebug) DPRINT1
45 static const WCHAR
* KEY_MOUSE
= L
"Control Panel\\Mouse";
46 static const WCHAR
* VAL_MOUSE1
= L
"MouseThreshold1";
47 static const WCHAR
* VAL_MOUSE2
= L
"MouseThreshold2";
48 static const WCHAR
* VAL_MOUSE3
= L
"MouseSpeed";
49 static const WCHAR
* VAL_MOUSETRAILS
= L
"MouseTrails";
50 static const WCHAR
* VAL_DBLCLKWIDTH
= L
"DoubleClickWidth";
51 static const WCHAR
* VAL_DBLCLKHEIGHT
= L
"DoubleClickHeight";
52 static const WCHAR
* VAL_DBLCLKTIME
= L
"DoubleClickSpeed";
53 static const WCHAR
* VAL_SNAPDEFBTN
= L
"SnapToDefaultButton";
54 static const WCHAR
* VAL_SWAP
= L
"SwapMouseButtons";
55 static const WCHAR
* VAL_HOVERTIME
= L
"MouseHoverTime";
56 static const WCHAR
* VAL_HOVERWIDTH
= L
"MouseHoverWidth";
57 static const WCHAR
* VAL_HOVERHEIGHT
= L
"MouseHoverHeight";
58 //static const WCHAR* VAL_SENSITIVITY = L"MouseSensitivity";
60 static const WCHAR
* KEY_DESKTOP
= L
"Control Panel\\Desktop";
61 static const WCHAR
* VAL_SCRTO
= L
"ScreenSaveTimeOut";
62 static const WCHAR
* VAL_SCRACT
= L
"ScreenSaveActive";
63 static const WCHAR
* VAL_GRID
= L
"GridGranularity";
64 static const WCHAR
* VAL_DRAG
= L
"DragFullWindows";
65 static const WCHAR
* VAL_DRAGHEIGHT
= L
"DragHeight";
66 static const WCHAR
* VAL_DRAGWIDTH
= L
"DragWidth";
67 static const WCHAR
* VAL_FNTSMOOTH
= L
"FontSmoothing";
68 static const WCHAR
* VAL_SCRLLLINES
= L
"WheelScrollLines";
69 static const WCHAR
* VAL_CLICKLOCKTIME
= L
"ClickLockTime";
70 #if (_WIN32_WINNT >= 0x0600)
71 static const WCHAR
* VAL_SCRLLCHARS
= L
"WheelScrollChars";
73 static const WCHAR
* VAL_USERPREFMASK
= L
"UserPreferencesMask";
75 static const WCHAR
* KEY_MDALIGN
= L
"Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows";
76 static const WCHAR
* VAL_MDALIGN
= L
"MenuDropAlignment";
78 static const WCHAR
* KEY_METRIC
= L
"Control Panel\\Desktop\\WindowMetrics";
79 static const WCHAR
* VAL_BORDER
= L
"BorderWidth";
80 static const WCHAR
* VAL_ICONSPC
= L
"IconSpacing";
81 static const WCHAR
* VAL_ICONVSPC
= L
"IconVerticalspacing";
82 static const WCHAR
* VAL_ITWRAP
= L
"IconTitleWrap";
84 static const WCHAR
* KEY_SOUND
= L
"Control Panel\\Sound";
85 static const WCHAR
* VAL_BEEP
= L
"Beep";
87 static const WCHAR
* KEY_KBD
= L
"Control Panel\\Keyboard";
88 static const WCHAR
* VAL_KBDSPD
= L
"KeyboardSpeed";
89 static const WCHAR
* VAL_KBDDELAY
= L
"KeyboardDelay";
91 static const WCHAR
* KEY_SHOWSNDS
= L
"Control Panel\\Accessibility\\ShowSounds";
92 static const WCHAR
* KEY_KDBPREF
= L
"Control Panel\\Accessibility\\Keyboard Preference";
93 static const WCHAR
* KEY_SCRREAD
= L
"Control Panel\\Accessibility\\Blind Access";
94 static const WCHAR
* VAL_ON
= L
"On";
98 /** Loading the settings ******************************************************/
102 SpiLoadDWord(PCWSTR pwszKey
, PCWSTR pwszValue
, INT iValue
)
105 if (!RegReadUserSetting(pwszKey
, pwszValue
, REG_DWORD
, &Result
, sizeof(Result
)))
114 SpiLoadInt(PCWSTR pwszKey
, PCWSTR pwszValue
, INT iValue
)
119 cbSize
= sizeof(awcBuffer
);
120 if (!RegReadUserSetting(pwszKey
, pwszValue
, REG_SZ
, awcBuffer
, cbSize
))
124 return _wtoi(awcBuffer
);
129 SpiLoadUserPrefMask(DWORD dValue
)
132 if (!RegReadUserSetting(KEY_DESKTOP
, VAL_USERPREFMASK
, REG_BINARY
, &Result
, sizeof(Result
)))
141 SpiLoadMouse(PCWSTR pwszValue
, INT iValue
)
143 return SpiLoadInt(KEY_MOUSE
, pwszValue
, iValue
);
148 SpiLoadMetric(PCWSTR pwszValue
, INT iValue
)
152 iRegVal
= SpiLoadInt(KEY_METRIC
, pwszValue
, METRIC2REG(iValue
));
153 DPRINT("Loaded metric setting '%S', iValue=%d(reg:%d), ret=%d(reg:%d)\n",
154 pwszValue
, iValue
, METRIC2REG(iValue
), REG2METRIC(iRegVal
), iRegVal
);
155 return REG2METRIC(iRegVal
);
160 SpiLoadFont(PLOGFONTW plfOut
, LPWSTR pwszValueName
, PLOGFONTW plfDefault
)
164 bResult
= RegReadUserSetting(KEY_METRIC
,
170 *plfOut
= *plfDefault
;
178 gspv
.ncm
.iCaptionWidth
= max(gspv
.ncm
.iCaptionWidth
, 8);
179 gspv
.ncm
.iBorderWidth
= max(gspv
.ncm
.iBorderWidth
, 1);
180 gspv
.ncm
.iScrollWidth
= max(gspv
.ncm
.iScrollWidth
, 8);
181 gspv
.ncm
.iScrollHeight
= max(gspv
.ncm
.iScrollHeight
, 8);
182 // gspv.ncm.iMenuHeight = max(gspv.ncm.iMenuHeight, gspv.tmMenuFont.tmHeight);
183 // gspv.ncm.iMenuHeight = max(gspv.ncm.iMenuHeight,
184 // 2 + gspv.tmMenuFont.tmHeight +
185 // gspv.tmMenuFont.tmExternalLeading);
186 if (gspv
.iDblClickTime
== 0) gspv
.iDblClickTime
= 500;
189 gspv
.tmMenuFont
.tmHeight
= 11;
190 gspv
.tmMenuFont
.tmExternalLeading
= 2;
192 gspv
.tmCaptionFont
.tmHeight
= 11;
193 gspv
.tmCaptionFont
.tmExternalLeading
= 2;
199 SpiUpdatePerUserSystemParameters()
201 static LOGFONTW lf1
= {-11, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
,
202 FALSE
, ANSI_CHARSET
, 0, 0, DEFAULT_QUALITY
,
203 VARIABLE_PITCH
| FF_SWISS
, L
"MS Sans Serif"};
204 static LOGFONTW lf2
= {-11, 0, 0, 0, FW_BOLD
, FALSE
, FALSE
,
205 FALSE
, ANSI_CHARSET
, 0, 0, DEFAULT_QUALITY
,
206 VARIABLE_PITCH
| FF_SWISS
, L
"MS Sans Serif"};
208 DPRINT("Enter SpiUpdatePerUserSystemParameters\n");
210 /* Clear the structure */
211 memset(&gspv
, 0, sizeof(gspv
));
213 /* Load mouse settings */
214 gspv
.caiMouse
.FirstThreshold
= SpiLoadMouse(VAL_MOUSE1
, 6);
215 gspv
.caiMouse
.SecondThreshold
= SpiLoadMouse(VAL_MOUSE2
, 10);
216 gspv
.caiMouse
.Acceleration
= gspv
.iMouseSpeed
= SpiLoadMouse(VAL_MOUSE3
, 1);
217 gspv
.bMouseBtnSwap
= SpiLoadMouse(VAL_SWAP
, 0);
218 gspv
.bSnapToDefBtn
= SpiLoadMouse(VAL_SNAPDEFBTN
, 0);
219 gspv
.iMouseTrails
= SpiLoadMouse(VAL_MOUSETRAILS
, 0);
220 gspv
.iDblClickTime
= SpiLoadMouse(VAL_DBLCLKTIME
, 500);
221 gspv
.iDblClickWidth
= SpiLoadMouse(VAL_DBLCLKWIDTH
, 4);
222 gspv
.iDblClickHeight
= SpiLoadMouse(VAL_DBLCLKHEIGHT
, 4);
223 gspv
.iMouseHoverTime
= SpiLoadMouse(VAL_HOVERTIME
, 400);
224 gspv
.iMouseHoverWidth
= SpiLoadMouse(VAL_HOVERWIDTH
, 4);
225 gspv
.iMouseHoverHeight
= SpiLoadMouse(VAL_HOVERHEIGHT
, 4);
227 /* Load NONCLIENTMETRICS */
228 gspv
.ncm
.cbSize
= sizeof(NONCLIENTMETRICSW
);
229 gspv
.ncm
.iBorderWidth
= SpiLoadMetric(VAL_BORDER
, 1);
230 gspv
.ncm
.iScrollWidth
= SpiLoadMetric(L
"ScrollWidth", 16);
231 gspv
.ncm
.iScrollHeight
= SpiLoadMetric(L
"ScrollHeight", 16);
232 gspv
.ncm
.iCaptionWidth
= SpiLoadMetric(L
"CaptionWidth", 19);
233 gspv
.ncm
.iCaptionHeight
= SpiLoadMetric(L
"CaptionHeight", 19);
234 gspv
.ncm
.iSmCaptionWidth
= SpiLoadMetric(L
"SmCaptionWidth", 12);
235 gspv
.ncm
.iSmCaptionHeight
= SpiLoadMetric(L
"SmCaptionHeight", 14);
236 gspv
.ncm
.iMenuWidth
= SpiLoadMetric(L
"MenuWidth", 18);
237 gspv
.ncm
.iMenuHeight
= SpiLoadMetric(L
"MenuHeight", 18);
238 #if (WINVER >= 0x0600)
239 gspv
.ncm
.iPaddedBorderWidth
= SpiLoadMetric(L
"PaddedBorderWidth", 18);
241 SpiLoadFont(&gspv
.ncm
.lfCaptionFont
, L
"CaptionFont", &lf2
);
242 SpiLoadFont(&gspv
.ncm
.lfSmCaptionFont
, L
"SmCaptionFont", &lf1
);
243 SpiLoadFont(&gspv
.ncm
.lfMenuFont
, L
"MenuFont", &lf1
);
244 SpiLoadFont(&gspv
.ncm
.lfStatusFont
, L
"StatusFont", &lf1
);
245 SpiLoadFont(&gspv
.ncm
.lfMessageFont
, L
"MessageFont", &lf1
);
247 /* Load MINIMIZEDMETRICS */
248 gspv
.mm
.cbSize
= sizeof(MINIMIZEDMETRICS
);
249 gspv
.mm
.iWidth
= SpiLoadMetric(L
"MinWidth", 160);
250 gspv
.mm
.iHorzGap
= SpiLoadMetric(L
"MinHorzGap", 160);
251 gspv
.mm
.iVertGap
= SpiLoadMetric(L
"MinVertGap", 24);
252 gspv
.mm
.iArrange
= SpiLoadInt(KEY_METRIC
, L
"MinArrange", ARW_HIDE
);
254 /* Load ICONMETRICS */
255 gspv
.im
.cbSize
= sizeof(ICONMETRICSW
);
256 gspv
.im
.iHorzSpacing
= SpiLoadMetric(VAL_ICONSPC
, 64);
257 gspv
.im
.iVertSpacing
= SpiLoadMetric(VAL_ICONVSPC
, 64);
258 gspv
.im
.iTitleWrap
= SpiLoadMetric(VAL_ITWRAP
, 0);
259 SpiLoadFont(&gspv
.im
.lfFont
, L
"IconFont", &lf1
);
261 /* Load desktop settings */
262 gspv
.bDragFullWindows
= SpiLoadInt(KEY_DESKTOP
, VAL_DRAG
, 0);
263 gspv
.iWheelScrollLines
= SpiLoadInt(KEY_DESKTOP
, VAL_SCRLLLINES
, 3);
264 gspv
.dwMouseClickLockTime
= SpiLoadDWord(KEY_DESKTOP
, VAL_CLICKLOCKTIME
, 1200);
265 gspv
.dwUserPrefMask
= SpiLoadUserPrefMask(UPM_DEFAULT
);
266 gspv
.bMouseClickLock
= (gspv
.dwUserPrefMask
& UPM_CLICKLOCK
) != 0;
267 gspv
.bMouseCursorShadow
= (gspv
.dwUserPrefMask
& UPM_CURSORSHADOW
) != 0;
268 #if (_WIN32_WINNT >= 0x0600)
269 gspv
.iWheelScrollChars
= SpiLoadInt(KEY_DESKTOP
, VAL_SCRLLCHARS
, 3);
272 /* Some hardcoded values for now */
274 gspv
.tmCaptionFont
.tmAveCharWidth
= 6;
276 gspv
.bFlatMenu
= FALSE
;
277 gspv
.uiFocusBorderWidth
= 1;
278 gspv
.uiFocusBorderHeight
= 1;
279 gspv
.bMenuDropAlign
= 1;
280 gspv
.bDropShadow
= 1;
281 gspv
.dwMenuShowDelay
= 100;
283 gspv
.iScrSaverTimeout
= 10;
284 gspv
.bScrSaverActive
= FALSE
;
285 gspv
.bScrSaverRunning
= FALSE
;
286 #if(WINVER >= 0x0600)
287 gspv
.bScrSaverSecure
= FALSE
;
290 /* Make sure we don't use broken values */
293 /* Update SystemMetrics */
300 SpiUpdatePerUserSystemParameters();
301 gbSpiInitialized
= TRUE
;
308 NtUserUpdatePerUserSystemParameters(
314 DPRINT("Enter NtUserUpdatePerUserSystemParameters\n");
315 UserEnterExclusive();
317 SpiUpdatePerUserSystemParameters();
318 bResult
= IntDesktopUpdatePerUserSettings(bEnable
);
320 DPRINT("Leave NtUserUpdatePerUserSystemParameters, returning %d\n", bResult
);
327 /** Storing the settings ******************************************************/
331 SpiStoreDWord(PCWSTR pwszKey
, PCWSTR pwszValue
, DWORD Value
)
333 RegWriteUserSetting(pwszKey
,
342 SpiStoreSz(PCWSTR pwszKey
, PCWSTR pwszValue
, PCWSTR pwsz
)
344 RegWriteUserSetting(pwszKey
,
348 wcslen(pwsz
) * sizeof(WCHAR
));
353 SpiStoreSzInt(PCWSTR pwszKey
, PCWSTR pwszValue
, INT iValue
)
357 _itow(iValue
, awcBuffer
, 10);
358 RegWriteUserSetting(pwszKey
,
362 (wcslen(awcBuffer
) + 1) * sizeof(WCHAR
));
367 SpiStoreMetric(LPCWSTR pwszValue
, INT iValue
)
369 SpiStoreSzInt(KEY_METRIC
, pwszValue
, METRIC2REG(iValue
));
374 SpiStoreFont(PCWSTR pwszValue
, LOGFONTW
* plogfont
)
376 RegWriteUserSetting(KEY_METRIC
,
384 /** Get/Set value *************************************************************/
386 // FIXME: get rid of the flags and only use this from um. kernel can access data directly.
389 SpiMemCopy(PVOID pvDst
, PVOID pvSrc
, ULONG cbSize
, BOOL bProtect
, BOOL bToUser
)
391 NTSTATUS Status
= STATUS_SUCCESS
;
399 ProbeForWrite(pvDst
, cbSize
, 1);
403 ProbeForRead(pvSrc
, cbSize
, 1);
405 memcpy(pvDst
, pvSrc
, cbSize
);
407 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
409 Status
= _SEH2_GetExceptionCode();
415 memcpy(pvDst
, pvSrc
, cbSize
);
418 if (!NT_SUCCESS(Status
))
420 SetLastNtError(Status
);
421 DPRINT("SpiMemCopy failed, pvDst=%p, pvSrc=%p, bProtect=%d, bToUser=%d\n", pvDst
, pvSrc
, bProtect
, bToUser
);
423 return NT_SUCCESS(Status
);
428 SpiGet(PVOID pvParam
, PVOID pvData
, ULONG cbSize
, FLONG fl
)
430 REQ_INTERACTIVE_WINSTA(ERROR_ACCESS_DENIED
);
431 return SpiMemCopy(pvParam
, pvData
, cbSize
, fl
& SPIF_PROTECT
, TRUE
);
436 SpiSet(PVOID pvData
, PVOID pvParam
, ULONG cbSize
, FLONG fl
)
438 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION
);
439 return SpiMemCopy(pvData
, pvParam
, cbSize
, fl
& SPIF_PROTECT
, FALSE
);
444 SpiGetEx(PVOID pvParam
, PVOID pvData
, ULONG cbSize
, FLONG fl
)
447 /* Get the cbSite member from UM memory */
448 if (!SpiSet(&cbBufSize
, pvParam
, sizeof(ULONG
), fl
))
450 /* Verify the correct size */
451 if (cbBufSize
!= cbSize
)
453 return SpiGet(pvParam
, pvData
, cbSize
, fl
);
458 SpiGetInt(PVOID pvParam
, PVOID piValue
, FLONG fl
)
460 return SpiGet(pvParam
, piValue
, sizeof(INT
), fl
);
465 SpiSetYesNo(BOOL
*pbData
, BOOL bValue
, PCWSTR pwszKey
, PCWSTR pwszValue
, FLONG fl
)
467 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION
);
468 *pbData
= bValue
? TRUE
: FALSE
;
469 if (fl
& SPIF_UPDATEINIFILE
)
471 SpiStoreSz(pwszKey
, pwszValue
, bValue
? L
"Yes" : L
"No");
473 return (UINT_PTR
)pwszKey
;
478 SpiSetBool(BOOL
*pbData
, INT iValue
, PCWSTR pwszKey
, PCWSTR pwszValue
, FLONG fl
)
480 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION
);
481 *pbData
= iValue
? TRUE
: FALSE
;
482 if (fl
& SPIF_UPDATEINIFILE
)
484 SpiStoreSzInt(pwszKey
, pwszValue
, iValue
);
486 return (UINT_PTR
)pwszKey
;
491 SpiSetDWord(PVOID pvData
, INT iValue
, PCWSTR pwszKey
, PCWSTR pwszValue
, FLONG fl
)
493 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION
);
494 *(INT
*)pvData
= iValue
;
495 if (fl
& SPIF_UPDATEINIFILE
)
497 SpiStoreDWord(pwszKey
, pwszValue
, iValue
);
499 return (UINT_PTR
)pwszKey
;
504 SpiSetInt(PVOID pvData
, INT iValue
, PCWSTR pwszKey
, PCWSTR pwszValue
, FLONG fl
)
506 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION
);
507 *(INT
*)pvData
= iValue
;
508 if (fl
& SPIF_UPDATEINIFILE
)
510 SpiStoreSzInt(pwszKey
, pwszValue
, iValue
);
512 return (UINT_PTR
)pwszKey
;
517 SpiSetMetric(PVOID pvData
, INT iValue
, PCWSTR pwszValue
, FLONG fl
)
519 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION
);
520 *(INT
*)pvData
= iValue
;
521 if (fl
& SPIF_UPDATEINIFILE
)
523 SpiStoreMetric(pwszValue
, iValue
);
525 return (UINT_PTR
)KEY_METRIC
;
530 SpiSetUserPref(DWORD dwMask
, PVOID pvValue
, FLONG fl
)
533 BOOL bValue
= (BOOL
)pvValue
;
535 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION
);
537 /* Set or clear bit according to bValue */
538 gspv
.dwUserPrefMask
= bValue
? gspv
.dwUserPrefMask
| dwMask
:
539 gspv
.dwUserPrefMask
& ~dwMask
;
541 if (fl
& SPIF_UPDATEINIFILE
)
543 /* Read current value */
544 RegReadUserSetting(KEY_DESKTOP
,
550 /* Set or clear bit according to bValue */
551 dwRegMask
= bValue
? dwRegMask
| dwMask
: dwRegMask
& ~dwMask
;
553 /* write back value */
554 RegWriteUserSetting(KEY_DESKTOP
,
561 return (UINT_PTR
)KEY_DESKTOP
;
566 SpiGetUserPref(DWORD dwMask
, PVOID pvParam
, FLONG fl
)
568 INT iValue
= gspv
.dwUserPrefMask
& dwMask
? 1 : 0;
569 return SpiGetInt(pvParam
, &iValue
, fl
);
574 SpiSetWallpaper(PVOID pvParam
, FLONG fl
)
579 HBITMAP hbmp
, hOldBitmap
;
581 ULONG ulTile
, ulStyle
;
583 REQ_INTERACTIVE_WINSTA(ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION
);
587 /* FIXME: Reset Wallpaper to registry value */
588 return (UINT_PTR
)KEY_DESKTOP
;
591 /* Capture UNICODE_STRING */
592 bResult
= SpiMemCopy(&ustr
, pvParam
, sizeof(UNICODE_STRING
), fl
& SPIF_PROTECT
, 0);
593 if (!bResult
) return 0;
594 if (ustr
.Length
> MAX_PATH
* sizeof(WCHAR
))
597 /* Copy the string buffer name */
598 bResult
= SpiMemCopy(gspv
.awcWallpaper
, ustr
.Buffer
, ustr
.Length
, fl
& SPIF_PROTECT
, 0);
599 if (!bResult
) return 0;
601 /* Update the UNICODE_STRING */
602 gspv
.ustrWallpaper
.Buffer
= gspv
.awcWallpaper
;
603 gspv
.ustrWallpaper
.MaximumLength
= MAX_PATH
* sizeof(WCHAR
);
604 gspv
.ustrWallpaper
.Length
= ustr
.Length
;
605 gspv
.awcWallpaper
[ustr
.Length
/ sizeof(WCHAR
)] = 0;
607 DPRINT("SpiSetWallpaper, name=%S\n", gspv
.awcWallpaper
);
609 /* Update registry */
610 if (fl
& SPIF_UPDATEINIFILE
)
612 SpiStoreSz(KEY_DESKTOP
, L
"Wallpaper", gspv
.awcWallpaper
);
615 /* Got a filename? */
616 if (gspv
.awcWallpaper
[0] != 0)
618 /* Convert file name to nt file name */
620 ustr
.MaximumLength
= MAX_PATH
* sizeof(WCHAR
);
622 if (!W32kDosPathNameToNtPathName(gspv
.awcWallpaper
, &ustr
))
624 DPRINT1("RtlDosPathNameToNtPathName_U failed\n");
628 /* Load the Bitmap */
629 hbmp
= UserLoadImage(ustr
.Buffer
);
632 DPRINT1("UserLoadImage failed\n");
636 /* Try to get the size of the wallpaper */
637 if(!(psurfBmp
= SURFACE_LockSurface(hbmp
)))
639 GreDeleteObject(hbmp
);
643 gpwinstaCurrent
->cxWallpaper
= psurfBmp
->SurfObj
.sizlBitmap
.cx
;
644 gpwinstaCurrent
->cyWallpaper
= psurfBmp
->SurfObj
.sizlBitmap
.cy
;
645 gpwinstaCurrent
->WallpaperMode
= wmCenter
;
647 SURFACE_UnlockSurface(psurfBmp
);
649 /* Change the bitmap's ownership */
650 GDIOBJ_SetOwnership(hbmp
, NULL
);
652 /* Yes, Windows really loads the current setting from the registry. */
653 ulTile
= SpiLoadInt(KEY_DESKTOP
, L
"TileWallpaper", 0);
654 ulStyle
= SpiLoadInt(KEY_DESKTOP
, L
"WallpaperStyle", 0);
655 DPRINT("SpiSetWallpaper: ulTile=%ld, ulStyle=%d\n", ulTile
, ulStyle
);
657 /* Check the values we found in the registry */
658 if(ulTile
&& !ulStyle
)
660 gpwinstaCurrent
->WallpaperMode
= wmTile
;
662 else if(!ulTile
&& ulStyle
== 2)
664 gpwinstaCurrent
->WallpaperMode
= wmStretch
;
669 /* Remove wallpaper */
670 gpwinstaCurrent
->cxWallpaper
= 0;
671 gpwinstaCurrent
->cyWallpaper
= 0;
675 /* Take care of the old wallpaper, if any */
676 hOldBitmap
= gpwinstaCurrent
->hbmWallpaper
;
677 if(hOldBitmap
!= NULL
)
679 /* Delete the old wallpaper */
680 GDIOBJ_SetOwnership(hOldBitmap
, PsGetCurrentProcess());
681 GreDeleteObject(hOldBitmap
);
684 /* Set the new wallpaper */
685 gpwinstaCurrent
->hbmWallpaper
= hbmp
;
687 NtUserRedrawWindow(UserGetShellWindow(), NULL
, NULL
, RDW_INVALIDATE
| RDW_ERASE
);
690 return (UINT_PTR
)KEY_DESKTOP
;
695 SpiGetSet(UINT uiAction
, UINT uiParam
, PVOID pvParam
, FLONG fl
)
700 return SpiGetInt(pvParam
, &gspv
.bBeep
, fl
);
703 return SpiSetYesNo(&gspv
.bBeep
, uiParam
, KEY_SOUND
, VAL_BEEP
, fl
);
706 return SpiGet(pvParam
, &gspv
.caiMouse
, 3 * sizeof(INT
), fl
);
709 if (!SpiSet(&gspv
.caiMouse
, pvParam
, 3 * sizeof(INT
), fl
))
711 if (fl
& SPIF_UPDATEINIFILE
)
713 SpiStoreSzInt(KEY_MOUSE
, VAL_MOUSE1
, gspv
.caiMouse
.FirstThreshold
);
714 SpiStoreSzInt(KEY_MOUSE
, VAL_MOUSE2
, gspv
.caiMouse
.SecondThreshold
);
715 SpiStoreSzInt(KEY_MOUSE
, VAL_MOUSE3
, gspv
.caiMouse
.Acceleration
);
717 return (UINT_PTR
)KEY_MOUSE
;
720 return SpiGetInt(pvParam
, &gspv
.ncm
.iBorderWidth
, fl
);
723 uiParam
= max(uiParam
, 1);
724 return SpiSetInt(&gspv
.ncm
.iBorderWidth
, uiParam
, KEY_METRIC
, VAL_BORDER
, fl
);
726 case SPI_GETKEYBOARDSPEED
:
727 return SpiGetInt(pvParam
, &gspv
.dwKbdSpeed
, fl
);
729 case SPI_SETKEYBOARDSPEED
:
730 return SpiSetInt(&gspv
.dwKbdSpeed
, uiParam
, KEY_KBD
, VAL_KBDSPD
, fl
);
733 DPRINT1("SPI_LANGDRIVER is unimplemented\n");
736 case SPI_GETSCREENSAVETIMEOUT
:
737 return SpiGetInt(pvParam
, &gspv
.iScrSaverTimeout
, fl
);
739 case SPI_SETSCREENSAVETIMEOUT
:
740 return SpiSetInt(&gspv
.iScrSaverTimeout
, uiParam
, KEY_DESKTOP
, VAL_SCRTO
, fl
);
742 case SPI_GETSCREENSAVEACTIVE
:
743 return SpiGetInt(pvParam
, &gspv
.bScrSaverActive
, fl
);
745 case SPI_SETSCREENSAVEACTIVE
:
746 return SpiSetInt(&gspv
.bScrSaverActive
, uiParam
, KEY_DESKTOP
, VAL_SCRACT
, fl
);
748 case SPI_GETGRIDGRANULARITY
:
749 return SpiGetInt(pvParam
, &gspv
.uiGridGranularity
, fl
);
751 case SPI_SETGRIDGRANULARITY
:
752 return SpiSetInt(&gspv
.uiGridGranularity
, uiParam
, KEY_DESKTOP
, VAL_GRID
, fl
);
754 case SPI_GETDESKWALLPAPER
:
755 uiParam
= min(uiParam
, gspv
.ustrWallpaper
.Length
+ 1);
756 return SpiGet(pvParam
, gspv
.awcWallpaper
, uiParam
, fl
);
758 case SPI_SETDESKWALLPAPER
:
759 return SpiSetWallpaper(pvParam
, fl
);
761 case SPI_SETDESKPATTERN
:
762 DPRINT1("SPI_SETDESKPATTERN is unimplemented\n");
765 case SPI_GETKEYBOARDDELAY
:
766 return SpiGetInt(pvParam
, &gspv
.iKbdDelay
, fl
);
768 case SPI_SETKEYBOARDDELAY
:
769 return SpiSetInt(&gspv
.iKbdDelay
, uiParam
, KEY_KBD
, VAL_KBDDELAY
, fl
);
771 case SPI_ICONHORIZONTALSPACING
:
774 return SpiGetInt(pvParam
, &gspv
.im
.iHorzSpacing
, fl
);
776 uiParam
= max(uiParam
, 32);
777 return SpiSetMetric(&gspv
.im
.iHorzSpacing
, uiParam
, VAL_ICONSPC
, fl
);
779 case SPI_ICONVERTICALSPACING
:
782 return SpiGetInt(pvParam
, &gspv
.im
.iVertSpacing
, fl
);
784 uiParam
= max(uiParam
, 32);
785 return SpiSetMetric(&gspv
.im
.iVertSpacing
, uiParam
, VAL_ICONVSPC
, fl
);
787 case SPI_GETICONTITLEWRAP
:
788 return SpiGetInt(pvParam
, &gspv
.im
.iTitleWrap
, fl
);
790 case SPI_SETICONTITLEWRAP
:
791 return SpiSetInt(&gspv
.im
.iTitleWrap
, uiParam
, KEY_METRIC
, VAL_ITWRAP
, fl
);
793 case SPI_GETMENUDROPALIGNMENT
:
794 return SpiGetInt(pvParam
, &gspv
.bMenuDropAlign
, fl
);
796 case SPI_SETMENUDROPALIGNMENT
:
797 return SpiSetBool(&gspv
.bMenuDropAlign
, uiParam
, KEY_MDALIGN
, VAL_MDALIGN
, fl
);
799 case SPI_SETDOUBLECLKWIDTH
:
800 return SpiSetInt(&gspv
.iDblClickWidth
, uiParam
, KEY_MOUSE
, VAL_DBLCLKWIDTH
, fl
);
802 case SPI_SETDOUBLECLKHEIGHT
:
803 return SpiSetInt(&gspv
.iDblClickHeight
, uiParam
, KEY_MOUSE
, VAL_DBLCLKHEIGHT
, fl
);
805 case SPI_GETICONTITLELOGFONT
:
806 return SpiGet(pvParam
, &gspv
.im
.lfFont
, sizeof(LOGFONTW
), fl
);
808 case SPI_SETICONTITLELOGFONT
:
809 if (!SpiSet(&gspv
.im
.lfFont
, pvParam
, sizeof(LOGFONTW
), fl
))
811 if (fl
& SPIF_UPDATEINIFILE
)
813 SpiStoreFont(L
"IconFont", &gspv
.im
.lfFont
);
815 return (UINT_PTR
)KEY_METRIC
;
817 case SPI_SETDOUBLECLICKTIME
:
818 return SpiSetInt(&gspv
.iDblClickTime
, uiParam
, KEY_MOUSE
, VAL_DBLCLKTIME
, fl
);
820 case SPI_SETMOUSEBUTTONSWAP
:
821 return SpiSetInt(&gspv
.bMouseBtnSwap
, uiParam
, KEY_MOUSE
, VAL_SWAP
, fl
);
823 case SPI_GETFASTTASKSWITCH
:
824 return SpiGetInt(pvParam
, &gspv
.bFastTaskSwitch
, fl
);
826 case SPI_SETFASTTASKSWITCH
:
827 /* According to Winetest this one is unimplemented */
830 case SPI_GETDRAGFULLWINDOWS
:
831 return SpiGetInt(pvParam
, &gspv
.bDragFullWindows
, fl
);
833 case SPI_SETDRAGFULLWINDOWS
:
834 return SpiSetInt(&gspv
.bDragFullWindows
, uiParam
, KEY_DESKTOP
, VAL_DRAG
, fl
);
836 case SPI_GETNONCLIENTMETRICS
:
837 return SpiGet(pvParam
, &gspv
.ncm
, sizeof(NONCLIENTMETRICSW
), fl
);
839 case SPI_SETNONCLIENTMETRICS
:
840 if (!SpiSet(&gspv
.ncm
, pvParam
, sizeof(NONCLIENTMETRICSW
), fl
))
842 if (fl
& SPIF_UPDATEINIFILE
)
844 SpiStoreMetric(VAL_BORDER
, gspv
.ncm
.iBorderWidth
);
845 SpiStoreMetric(L
"ScrollWidth", gspv
.ncm
.iScrollWidth
);
846 SpiStoreMetric(L
"ScrollHeight", gspv
.ncm
.iScrollHeight
);
847 SpiStoreMetric(L
"CaptionWidth", gspv
.ncm
.iCaptionWidth
);
848 SpiStoreMetric(L
"CaptionHeight", gspv
.ncm
.iCaptionHeight
);
849 SpiStoreMetric(L
"SmCaptionWidth", gspv
.ncm
.iSmCaptionWidth
);
850 SpiStoreMetric(L
"SmCaptionHeight", gspv
.ncm
.iSmCaptionHeight
);
851 SpiStoreMetric(L
"MenuWidth", gspv
.ncm
.iMenuWidth
);
852 SpiStoreMetric(L
"MenuHeight", gspv
.ncm
.iMenuHeight
);
853 #if (WINVER >= 0x0600)
854 SpiStoreMetric(L
"PaddedBorderWidth", gspv
.ncm
.iPaddedBorderWidth
);
856 SpiStoreFont(L
"CaptionFont", &gspv
.ncm
.lfCaptionFont
);
857 SpiStoreFont(L
"SmCaptionFont", &gspv
.ncm
.lfSmCaptionFont
);
858 SpiStoreFont(L
"MenuFont", &gspv
.ncm
.lfMenuFont
);
859 SpiStoreFont(L
"StatusFont", &gspv
.ncm
.lfStatusFont
);
860 SpiStoreFont(L
"MessageFont", &gspv
.ncm
.lfMessageFont
);
862 return (UINT_PTR
)KEY_METRIC
;
864 case SPI_GETMINIMIZEDMETRICS
:
865 return SpiGet(pvParam
, &gspv
.mm
, sizeof(MINIMIZEDMETRICS
), fl
);
867 case SPI_SETMINIMIZEDMETRICS
:
868 if (!SpiSet(&gspv
.mm
, pvParam
, sizeof(MINIMIZEDMETRICS
), fl
))
870 gspv
.mm
.iWidth
= max(0, gspv
.mm
.iWidth
);
871 gspv
.mm
.iHorzGap
= max(0, gspv
.mm
.iHorzGap
);
872 gspv
.mm
.iVertGap
= max(0, gspv
.mm
.iVertGap
);
873 gspv
.mm
.iArrange
= gspv
.mm
.iArrange
& 0xf;
874 if (fl
& SPIF_UPDATEINIFILE
)
876 SpiStoreMetric(L
"MinWidth", gspv
.mm
.iWidth
);
877 SpiStoreMetric(L
"MinHorzGap", gspv
.mm
.iHorzGap
);
878 SpiStoreMetric(L
"MinVertGap", gspv
.mm
.iVertGap
);
879 SpiStoreMetric(L
"MinArrange", gspv
.mm
.iArrange
);
881 return (UINT_PTR
)KEY_METRIC
;
883 case SPI_GETICONMETRICS
:
884 return SpiGet(pvParam
, &gspv
.im
, sizeof(ICONMETRICS
), fl
);
886 case SPI_SETICONMETRICS
:
887 if (!SpiSet(&gspv
.im
, pvParam
, sizeof(ICONMETRICS
), fl
))
889 if (fl
& SPIF_UPDATEINIFILE
)
891 SpiStoreMetric(VAL_ICONSPC
, gspv
.im
.iHorzSpacing
);
892 SpiStoreMetric(VAL_ICONVSPC
, gspv
.im
.iVertSpacing
);
893 SpiStoreMetric(VAL_ITWRAP
, gspv
.im
.iTitleWrap
);
894 SpiStoreFont(L
"IconFont", &gspv
.im
.lfFont
);
896 return (UINT_PTR
)KEY_METRIC
;
898 case SPI_GETWORKAREA
: // FIXME: the workarea should be part of the MONITOR
900 PTHREADINFO pti
= PsGetCurrentThreadWin32Thread();
901 PDESKTOP pdesktop
= pti
->rpdesk
;
907 IntGetDesktopWorkArea(pdesktop
, &rclWorkarea
);
908 return SpiGet(pvParam
, &rclWorkarea
, sizeof(RECTL
), fl
);
911 case SPI_SETWORKAREA
: // FIXME: the workarea should be part of the MONITOR
913 PTHREADINFO pti
= PsGetCurrentThreadWin32Thread();
914 PDESKTOP pdesktop
= pti
->rpdesk
;
920 if (!SpiSet(&rcWorkArea
, pvParam
, sizeof(RECTL
), fl
))
923 /* Verify the new values */
924 if (rcWorkArea
.left
< 0 ||
925 rcWorkArea
.top
< 0 ||
926 rcWorkArea
.right
> gpsi
->aiSysMet
[SM_CXSCREEN
] ||
927 rcWorkArea
.bottom
> gpsi
->aiSysMet
[SM_CYSCREEN
] ||
928 rcWorkArea
.right
<= rcWorkArea
.left
||
929 rcWorkArea
.bottom
<= rcWorkArea
.top
)
932 pdesktop
->WorkArea
= rcWorkArea
;
933 if (fl
& SPIF_UPDATEINIFILE
)
935 // FIXME: what to do?
937 return (UINT_PTR
)KEY_DESKTOP
;
940 case SPI_SETPENWINDOWS
:
941 DPRINT1("SPI_SETPENWINDOWS is unimplemented\n");
944 case SPI_GETFILTERKEYS
:
945 return SpiGet(pvParam
, &gspv
.filterkeys
, sizeof(FILTERKEYS
), fl
);
947 case SPI_SETFILTERKEYS
:
948 if (!SpiSet(&gspv
.filterkeys
, pvParam
, sizeof(FILTERKEYS
), fl
))
950 if (fl
& SPIF_UPDATEINIFILE
)
952 // FIXME: what to do?
954 return (UINT_PTR
)KEY_DESKTOP
;
956 case SPI_GETTOGGLEKEYS
:
957 return SpiGet(pvParam
, &gspv
.togglekeys
, sizeof(TOGGLEKEYS
), fl
);
959 case SPI_SETTOGGLEKEYS
:
960 if (!SpiSet(&gspv
.togglekeys
, pvParam
, sizeof(TOGGLEKEYS
), fl
))
962 if (fl
& SPIF_UPDATEINIFILE
)
964 // FIXME: what to do?
966 return (UINT_PTR
)KEY_DESKTOP
;
968 case SPI_GETMOUSEKEYS
:
969 return SpiGet(pvParam
, &gspv
.mousekeys
, sizeof(MOUSEKEYS
), fl
);
971 case SPI_SETMOUSEKEYS
:
972 if (!SpiSet(&gspv
.mousekeys
, pvParam
, sizeof(MOUSEKEYS
), fl
))
974 if (fl
& SPIF_UPDATEINIFILE
)
976 // FIXME: what to do?
978 return (UINT_PTR
)KEY_DESKTOP
;
980 case SPI_GETSHOWSOUNDS
:
981 return SpiGetInt(pvParam
, &gspv
.bShowSounds
, fl
);
983 case SPI_SETSHOWSOUNDS
:
984 return SpiSetBool(&gspv
.bShowSounds
, uiParam
, KEY_SHOWSNDS
, VAL_ON
, fl
);
986 case SPI_GETSTICKYKEYS
:
987 if (uiParam
!= sizeof(STICKYKEYS
))
989 return SpiGetEx(pvParam
, &gspv
.stickykeys
, sizeof(STICKYKEYS
), fl
);
991 case SPI_SETSTICKYKEYS
:
992 if (!SpiSet(&gspv
.stickykeys
, pvParam
, sizeof(STICKYKEYS
), fl
))
994 if (fl
& SPIF_UPDATEINIFILE
)
996 // FIXME: what to do?
998 return (UINT_PTR
)KEY_DESKTOP
;
1000 case SPI_GETACCESSTIMEOUT
:
1001 if (uiParam
!= 0 && uiParam
!= sizeof(ACCESSTIMEOUT
))
1003 return SpiGetEx(pvParam
, &gspv
.accesstimeout
, sizeof(ACCESSTIMEOUT
), fl
);
1005 case SPI_SETACCESSTIMEOUT
:
1006 if (!SpiSet(&gspv
.accesstimeout
, pvParam
, sizeof(ACCESSTIMEOUT
), fl
))
1008 if (fl
& SPIF_UPDATEINIFILE
)
1010 // FIXME: what to do?
1012 return (UINT_PTR
)KEY_DESKTOP
;
1014 case SPI_GETSERIALKEYS
:
1015 return SpiGet(pvParam
, &gspv
.serialkeys
, sizeof(SERIALKEYS
), fl
);
1017 case SPI_SETSERIALKEYS
:
1018 if (!SpiSet(&gspv
.serialkeys
, pvParam
, sizeof(SERIALKEYS
), fl
))
1020 if (fl
& SPIF_UPDATEINIFILE
)
1022 // FIXME: what to do?
1024 return (UINT_PTR
)KEY_DESKTOP
;
1026 case SPI_GETSOUNDSENTRY
:
1027 return SpiGet(pvParam
, &gspv
.soundsentry
, sizeof(SOUNDSENTRY
), fl
);
1029 case SPI_SETSOUNDSENTRY
:
1030 if (!SpiSet(&gspv
.soundsentry
, pvParam
, sizeof(SOUNDSENTRY
), fl
))
1032 if (fl
& SPIF_UPDATEINIFILE
)
1034 // FIXME: what to do?
1036 return (UINT_PTR
)KEY_DESKTOP
;
1038 case SPI_GETHIGHCONTRAST
:
1039 return SpiGet(pvParam
, &gspv
.highcontrast
, sizeof(HIGHCONTRAST
), fl
);
1041 case SPI_SETHIGHCONTRAST
:
1042 if (!SpiSet(&gspv
.highcontrast
, pvParam
, sizeof(HIGHCONTRAST
), fl
))
1044 if (fl
& SPIF_UPDATEINIFILE
)
1046 // FIXME: what to do?
1048 return (UINT_PTR
)KEY_DESKTOP
;
1050 case SPI_GETKEYBOARDPREF
:
1051 return SpiGetInt(pvParam
, &gspv
.bKbdPref
, fl
);
1053 case SPI_SETKEYBOARDPREF
:
1054 return SpiSetBool(&gspv
.bKbdPref
, uiParam
, KEY_KDBPREF
, VAL_ON
, fl
);
1056 case SPI_GETSCREENREADER
:
1057 return SpiGetInt(pvParam
, &gspv
.bScreenReader
, fl
);
1059 case SPI_SETSCREENREADER
:
1060 return SpiSetBool(&gspv
.bScreenReader
, uiParam
, KEY_SCRREAD
, VAL_ON
, fl
);
1062 case SPI_GETANIMATION
:
1063 return SpiGet(pvParam
, &gspv
.animationinfo
, sizeof(ANIMATIONINFO
), fl
);
1065 case SPI_SETANIMATION
:
1066 if (!SpiSet(&gspv
.animationinfo
, pvParam
, sizeof(ANIMATIONINFO
), fl
))
1068 if (fl
& SPIF_UPDATEINIFILE
)
1070 // FIXME: what to do?
1072 return (UINT_PTR
)KEY_DESKTOP
;
1074 case SPI_GETFONTSMOOTHING
:
1075 return SpiGetInt(pvParam
, &gspv
.bFontSmoothing
, fl
);
1077 case SPI_SETFONTSMOOTHING
:
1078 gspv
.bFontSmoothing
= uiParam
? TRUE
: FALSE
;
1079 if (fl
& SPIF_UPDATEINIFILE
)
1081 SpiStoreSzInt(KEY_DESKTOP
, VAL_FNTSMOOTH
, uiParam
? 2 : 0);
1083 return (UINT_PTR
)KEY_DESKTOP
;
1085 case SPI_SETDRAGWIDTH
:
1086 return SpiSetInt(&gspv
.iDragWidth
, uiParam
, KEY_DESKTOP
, VAL_DRAGWIDTH
, fl
);
1088 case SPI_SETDRAGHEIGHT
:
1089 return SpiSetInt(&gspv
.iDragHeight
, uiParam
, KEY_DESKTOP
, VAL_DRAGHEIGHT
, fl
);
1091 case SPI_SETHANDHELD
:
1092 return SpiSetBool(&gspv
.bHandHeld
, uiParam
, KEY_DESKTOP
, L
"HandHeld", fl
);
1094 case SPI_GETLOWPOWERTIMEOUT
:
1095 return SpiGetInt(pvParam
, &gspv
.iLowPwrTimeout
, fl
);
1097 case SPI_GETPOWEROFFTIMEOUT
:
1098 return SpiGetInt(pvParam
, &gspv
.iPwrOffTimeout
, fl
);
1100 case SPI_SETLOWPOWERTIMEOUT
:
1101 return SpiSetInt(&gspv
.iLowPwrTimeout
, uiParam
, KEY_DESKTOP
, L
"LowPowerTimeOut", fl
);
1103 case SPI_SETPOWEROFFTIMEOUT
:
1104 return SpiSetInt(&gspv
.iPwrOffTimeout
, uiParam
, KEY_DESKTOP
, L
"PowerOffTimeOut", fl
);
1106 case SPI_GETLOWPOWERACTIVE
:
1107 return SpiGetInt(pvParam
, &gspv
.iPwrOffTimeout
, fl
);
1109 case SPI_GETPOWEROFFACTIVE
:
1110 return SpiGetInt(pvParam
, &gspv
.bPwrOffActive
, fl
);
1112 case SPI_SETLOWPOWERACTIVE
:
1113 return SpiSetBool(&gspv
.bLowPwrActive
, uiParam
, KEY_DESKTOP
, L
"LowPowerActive", fl
);
1115 case SPI_SETPOWEROFFACTIVE
:
1116 return SpiSetBool(&gspv
.bPwrOffActive
, uiParam
, KEY_DESKTOP
, L
"PowerOffActive", fl
);
1118 case SPI_SETCURSORS
:
1119 DPRINT1("SPI_SETCURSORS is unimplemented\n");
1123 DPRINT1("SPI_SETICONS is unimplemented\n");
1126 case SPI_GETDEFAULTINPUTLANG
:
1127 DPRINT1("SPI_GETDEFAULTINPUTLANG is unimplemented\n");
1130 case SPI_SETDEFAULTINPUTLANG
:
1131 DPRINT1("SPI_SETDEFAULTINPUTLANG is unimplemented\n");
1134 case SPI_SETLANGTOGGLE
:
1135 DPRINT1("SPI_SETLANGTOGGLE is unimplemented\n");
1138 case SPI_GETWINDOWSEXTENSION
:
1139 DPRINT1("SPI_GETWINDOWSEXTENSION is unimplemented\n");
1142 case SPI_GETMOUSETRAILS
:
1143 return SpiGetInt(pvParam
, &gspv
.iMouseTrails
, fl
);
1145 case SPI_SETMOUSETRAILS
:
1146 return SpiSetInt(&gspv
.iMouseTrails
, uiParam
, KEY_MOUSE
, VAL_MOUSETRAILS
, fl
);
1148 case SPI_GETSNAPTODEFBUTTON
:
1149 return SpiGetInt(pvParam
, &gspv
.bSnapToDefBtn
, fl
);
1151 case SPI_SETSNAPTODEFBUTTON
:
1152 return SpiSetBool(&gspv
.bSnapToDefBtn
, uiParam
, KEY_MOUSE
, VAL_SNAPDEFBTN
, fl
);
1154 case SPI_GETMOUSEHOVERWIDTH
:
1155 return SpiGetInt(pvParam
, &gspv
.iMouseHoverWidth
, fl
);
1157 case SPI_SETMOUSEHOVERWIDTH
:
1158 return SpiSetInt(&gspv
.iMouseHoverWidth
, uiParam
, KEY_MOUSE
, VAL_HOVERWIDTH
, fl
);
1160 case SPI_GETMOUSEHOVERHEIGHT
:
1161 return SpiGetInt(pvParam
, &gspv
.iMouseHoverHeight
, fl
);
1163 case SPI_SETMOUSEHOVERHEIGHT
:
1164 return SpiSetInt(&gspv
.iMouseHoverHeight
, uiParam
, KEY_MOUSE
, VAL_HOVERHEIGHT
, fl
);
1166 case SPI_GETMOUSEHOVERTIME
:
1167 return SpiGetInt(pvParam
, &gspv
.iMouseHoverTime
, fl
);
1169 case SPI_SETMOUSEHOVERTIME
:
1170 /* see http://msdn2.microsoft.com/en-us/library/ms724947.aspx
1171 * copy text from it, if some agument why xp and 2003 behovir diffent
1172 * only if they do not have SP install
1173 * " Windows Server 2003 and Windows XP: The operating system does not
1174 * enforce the use of USER_TIMER_MAXIMUM and USER_TIMER_MINIMUM until
1175 * Windows Server 2003 SP1 and Windows XP SP2 "
1177 return SpiSetInt(&gspv
.iMouseHoverTime
, uiParam
, KEY_MOUSE
, VAL_HOVERTIME
, fl
);
1179 case SPI_GETWHEELSCROLLLINES
:
1180 return SpiGetInt(pvParam
, &gspv
.iWheelScrollLines
, fl
);
1182 case SPI_SETWHEELSCROLLLINES
:
1183 return SpiSetInt(&gspv
.iWheelScrollLines
, uiParam
, KEY_DESKTOP
, VAL_SCRLLLINES
, fl
);
1185 case SPI_GETMENUSHOWDELAY
:
1186 return SpiGetInt(pvParam
, &gspv
.dwMenuShowDelay
, fl
);
1188 case SPI_SETMENUSHOWDELAY
:
1189 return SpiSetInt(&gspv
.dwMenuShowDelay
, uiParam
, KEY_DESKTOP
, L
"MenuShowDelay", fl
);
1191 #if (_WIN32_WINNT >= 0x0600)
1192 case SPI_GETWHEELSCROLLCHARS
:
1193 return SpiGetInt(pvParam
, &gspv
.uiWheelScrollChars
, fl
);
1195 case SPI_SETWHEELSCROLLCHARS
:
1196 return SpiSetInt(&gspv
.uiWheelScrollChars
, uiParam
, KEY_DESKTOP
, VAL_SCRLLCHARS
, fl
);
1198 case SPI_GETSHOWIMEUI
:
1199 return SpiGetInt(pvParam
, &gspv
.bShowImeUi
, fl
);
1201 case SPI_SETSHOWIMEUI
:
1202 return SpiSetBool(&gspv
.bShowImeUi
, uiParam
, KEY_DESKTOP
, L
"", fl
);
1204 case SPI_GETMOUSESPEED
:
1205 return SpiGetInt(pvParam
, &gspv
.iMouseSpeed
, fl
);
1207 case SPI_SETMOUSESPEED
:
1209 return SpiSetInt(&gspv
.iMouseSpeed
, uiParam
, KEY_MOUSE
, VAL_MOUSE3
, fl
);
1211 case SPI_GETSCREENSAVERRUNNING
:
1212 return SpiGetInt(pvParam
, &gspv
.bScrSaverRunning
, fl
);
1214 case SPI_SETSCREENSAVERRUNNING
:
1215 // FIXME: also return value?
1216 return SpiSetBool(&gspv
.bScrSaverRunning
, uiParam
, KEY_MOUSE
, L
"", fl
);
1218 #if(WINVER >= 0x0600)
1219 case SPI_GETAUDIODESCRIPTION
:
1220 return SpiGet(pvParam
, &gspv
.audiodesription
, sizeof(AUDIODESCRIPTION
), fl
);
1222 case SPI_SETAUDIODESCRIPTION
:
1223 DPRINT1("SPI_SETAUDIODESCRIPTION is unimplemented\n");
1226 case SPI_GETSCREENSAVESECURE
:
1227 return SpiGetInt(pvParam
, &gspv
.bScrSaverSecure
, fl
);
1229 case SPI_SETSCREENSAVESECURE
:
1230 return SpiSetBool(&gspv
.bScrSaverSecure
, uiParam
, KEY_DESKTOP
, L
"ScreenSaverIsSecure", fl
);
1233 case SPI_GETACTIVEWINDOWTRACKING
:
1234 return SpiGetUserPref(UPM_ACTIVEWINDOWTRACKING
, pvParam
, fl
);
1236 case SPI_SETACTIVEWINDOWTRACKING
:
1237 return SpiSetUserPref(UPM_ACTIVEWINDOWTRACKING
, pvParam
, fl
);
1239 case SPI_GETMENUANIMATION
:
1240 return SpiGetUserPref(UPM_MENUANIMATION
, pvParam
, fl
);
1242 case SPI_SETMENUANIMATION
:
1243 return SpiSetUserPref(UPM_MENUANIMATION
, pvParam
, fl
);
1245 case SPI_GETCOMBOBOXANIMATION
:
1246 return SpiGetUserPref(UPM_COMBOBOXANIMATION
, pvParam
, fl
);
1248 case SPI_SETCOMBOBOXANIMATION
:
1249 return SpiSetUserPref(UPM_COMBOBOXANIMATION
, pvParam
, fl
);
1251 case SPI_GETLISTBOXSMOOTHSCROLLING
:
1252 return SpiGetUserPref(UPM_LISTBOXSMOOTHSCROLLING
, pvParam
, fl
);
1254 case SPI_SETLISTBOXSMOOTHSCROLLING
:
1255 return SpiSetUserPref(UPM_LISTBOXSMOOTHSCROLLING
, pvParam
, fl
);
1257 case SPI_GETGRADIENTCAPTIONS
:
1258 return SpiGetUserPref(UPM_GRADIENTCAPTIONS
, pvParam
, fl
);
1260 case SPI_SETGRADIENTCAPTIONS
:
1261 return SpiSetUserPref(UPM_GRADIENTCAPTIONS
, pvParam
, fl
);
1263 case SPI_GETKEYBOARDCUES
:
1264 return SpiGetUserPref(UPM_KEYBOARDCUES
, pvParam
, fl
);
1266 case SPI_SETKEYBOARDCUES
:
1267 return SpiSetUserPref(UPM_KEYBOARDCUES
, pvParam
, fl
);
1269 case SPI_GETACTIVEWNDTRKZORDER
:
1270 return SpiGetUserPref(UPM_ACTIVEWNDTRKZORDER
, pvParam
, fl
);
1272 case SPI_SETACTIVEWNDTRKZORDER
:
1273 return SpiSetUserPref(UPM_ACTIVEWNDTRKZORDER
, pvParam
, fl
);
1275 case SPI_GETHOTTRACKING
:
1276 return SpiGetUserPref(UPM_HOTTRACKING
, pvParam
, fl
);
1278 case SPI_SETHOTTRACKING
:
1279 return SpiSetUserPref(UPM_HOTTRACKING
, pvParam
, fl
);
1281 case SPI_GETMENUFADE
:
1282 return SpiGetUserPref(UPM_MENUFADE
, pvParam
, fl
);
1284 case SPI_SETMENUFADE
:
1285 return SpiSetUserPref(UPM_MENUFADE
, pvParam
, fl
);
1287 case SPI_GETSELECTIONFADE
:
1288 return SpiGetUserPref(UPM_SELECTIONFADE
, pvParam
, fl
);
1290 case SPI_SETSELECTIONFADE
:
1291 return SpiSetUserPref(UPM_SELECTIONFADE
, pvParam
, fl
);
1293 case SPI_GETTOOLTIPANIMATION
:
1294 return SpiGetUserPref(UPM_TOOLTIPANIMATION
, pvParam
, fl
);
1296 case SPI_SETTOOLTIPANIMATION
:
1297 return SpiSetUserPref(UPM_TOOLTIPANIMATION
, pvParam
, fl
);
1299 case SPI_GETTOOLTIPFADE
:
1300 return SpiGetUserPref(UPM_TOOLTIPFADE
, pvParam
, fl
);
1302 case SPI_SETTOOLTIPFADE
:
1303 return SpiSetUserPref(UPM_TOOLTIPFADE
, pvParam
, fl
);
1305 case SPI_GETCURSORSHADOW
:
1306 return SpiGetUserPref(UPM_CURSORSHADOW
, pvParam
, fl
);
1308 case SPI_SETCURSORSHADOW
:
1309 gspv
.bMouseCursorShadow
= (BOOL
)pvParam
;
1310 return SpiSetUserPref(UPM_CURSORSHADOW
, pvParam
, fl
);
1312 case SPI_GETUIEFFECTS
:
1313 return SpiGetUserPref(UPM_UIEFFECTS
, pvParam
, fl
);
1315 case SPI_SETUIEFFECTS
:
1316 return SpiSetUserPref(UPM_UIEFFECTS
, pvParam
, fl
);
1318 case SPI_GETMOUSESONAR
:
1319 return SpiGetInt(pvParam
, &gspv
.bMouseSonar
, fl
);
1321 case SPI_SETMOUSESONAR
:
1322 return SpiSetBool(&gspv
.bMouseSonar
, uiParam
, KEY_MOUSE
, L
"", fl
);
1324 case SPI_GETMOUSECLICKLOCK
:
1325 return SpiGetUserPref(UPM_CLICKLOCK
, pvParam
, fl
);
1327 case SPI_SETMOUSECLICKLOCK
:
1328 gspv
.bMouseClickLock
= (BOOL
)pvParam
;
1329 return SpiSetUserPref(UPM_CLICKLOCK
, pvParam
, fl
);
1331 case SPI_GETMOUSEVANISH
:
1332 return SpiGetInt(pvParam
, &gspv
.bMouseVanish
, fl
);
1334 case SPI_SETMOUSEVANISH
:
1335 return SpiSetBool(&gspv
.bMouseVanish
, uiParam
, KEY_MOUSE
, L
"", fl
);
1337 case SPI_GETFLATMENU
:
1338 return SpiGetInt(pvParam
, &gspv
.bFlatMenu
, fl
);
1340 case SPI_SETFLATMENU
:
1341 return SpiSetBool(&gspv
.bFlatMenu
, uiParam
, KEY_MOUSE
, L
"", fl
);
1343 case SPI_GETDROPSHADOW
:
1344 return SpiGetInt(pvParam
, &gspv
.bDropShadow
, fl
);
1346 case SPI_SETDROPSHADOW
:
1347 return SpiSetBool(&gspv
.bDropShadow
, uiParam
, KEY_MOUSE
, L
"", fl
);
1349 case SPI_GETBLOCKSENDINPUTRESETS
:
1350 return SpiGetInt(pvParam
, &gspv
.bBlockSendInputResets
, fl
);
1352 case SPI_SETBLOCKSENDINPUTRESETS
:
1353 return SpiSetBool(&gspv
.bBlockSendInputResets
, uiParam
, KEY_MOUSE
, L
"", fl
);
1355 #if(_WIN32_WINNT >= 0x0600)
1356 case SPI_GETDISABLEOVERLAPPEDCONTENT
:
1357 return SpiGetInt(pvParam
, &gspv
.bDisableOverlappedContent
, fl
);
1359 case SPI_SETDISABLEOVERLAPPEDCONTENT
:
1360 return SpiSetBool(&gspv
.bDisableOverlappedContent
, uiParam
, KEY_MOUSE
, L
"", fl
);
1362 case SPI_GETCLIENTAREAANIMATION
:
1363 return SpiGetInt(pvParam
, &gspv
.bClientAnimation
, fl
);
1365 case SPI_SETCLIENTAREAANIMATION
:
1366 return SpiSetBool(&gspv
.bClientAnimation
, uiParam
, KEY_MOUSE
, L
"", fl
);
1368 case SPI_GETCLEARTYPE
:
1369 return SpiGetInt(pvParam
, &gspv
.bClearType
, fl
);
1371 case SPI_SETCLEARTYPE
:
1372 return SpiSetBool(&gspv
.bClearType
, uiParam
, KEY_MOUSE
, L
"", fl
);
1374 case SPI_GETSPEECHRECOGNITION
:
1375 return SpiGetInt(pvParam
, &gspv
.bSpeechRecognition
, fl
);
1377 case SPI_SETSPEECHRECOGNITION
:
1378 return SpiSetBool(&gspv
.bSpeechRecognition
, uiParam
, KEY_MOUSE
, L
"", fl
);
1381 case SPI_GETFOREGROUNDLOCKTIMEOUT
:
1382 return SpiGetInt(pvParam
, &gspv
.dwForegroundLockTimeout
, fl
);
1384 case SPI_SETFOREGROUNDLOCKTIMEOUT
:
1385 return SpiSetInt(&gspv
.dwForegroundLockTimeout
, uiParam
, KEY_MOUSE
, L
"", fl
);
1387 case SPI_GETACTIVEWNDTRKTIMEOUT
:
1388 return SpiGetInt(pvParam
, &gspv
.dwActiveTrackingTimeout
, fl
);
1390 case SPI_SETACTIVEWNDTRKTIMEOUT
:
1391 return SpiSetInt(&gspv
.dwActiveTrackingTimeout
, uiParam
, KEY_MOUSE
, L
"", fl
);
1393 case SPI_GETFOREGROUNDFLASHCOUNT
:
1394 return SpiGetInt(pvParam
, &gspv
.dwForegroundFlashCount
, fl
);
1396 case SPI_SETFOREGROUNDFLASHCOUNT
:
1397 return SpiSetInt(&gspv
.dwForegroundFlashCount
, uiParam
, KEY_MOUSE
, L
"", fl
);
1399 case SPI_GETCARETWIDTH
:
1400 return SpiGetInt(pvParam
, &gspv
.dwCaretWidth
, fl
);
1402 case SPI_SETCARETWIDTH
:
1403 return SpiSetInt(&gspv
.dwCaretWidth
, uiParam
, KEY_MOUSE
, L
"", fl
);
1405 case SPI_GETMOUSECLICKLOCKTIME
:
1406 return SpiGetInt(pvParam
, &gspv
.dwMouseClickLockTime
, fl
);
1408 case SPI_SETMOUSECLICKLOCKTIME
:
1409 return SpiSetDWord(&gspv
.dwMouseClickLockTime
, uiParam
, KEY_DESKTOP
, VAL_CLICKLOCKTIME
, fl
);
1411 case SPI_GETFONTSMOOTHINGTYPE
:
1412 return SpiGetInt(pvParam
, &gspv
.uiFontSmoothingType
, fl
);
1414 case SPI_SETFONTSMOOTHINGTYPE
:
1415 return SpiSetInt(&gspv
.uiFontSmoothingType
, uiParam
, KEY_MOUSE
, L
"", fl
);
1417 case SPI_GETFONTSMOOTHINGCONTRAST
:
1418 return SpiGetInt(pvParam
, &gspv
.uiFontSmoothingContrast
, fl
);
1420 case SPI_SETFONTSMOOTHINGCONTRAST
:
1421 return SpiSetInt(&gspv
.uiFontSmoothingContrast
, uiParam
, KEY_MOUSE
, L
"", fl
);
1423 case SPI_GETFOCUSBORDERWIDTH
:
1424 return SpiGetInt(pvParam
, &gspv
.uiFocusBorderWidth
, fl
);
1426 case SPI_SETFOCUSBORDERWIDTH
:
1427 return SpiSetInt(&gspv
.uiFocusBorderWidth
, uiParam
, KEY_MOUSE
, L
"", fl
);
1429 case SPI_GETFOCUSBORDERHEIGHT
:
1430 return SpiGetInt(pvParam
, &gspv
.uiFocusBorderHeight
, fl
);
1432 case SPI_SETFOCUSBORDERHEIGHT
:
1433 return SpiSetInt(&gspv
.uiFocusBorderHeight
, uiParam
, KEY_MOUSE
, L
"", fl
);
1435 case SPI_GETFONTSMOOTHINGORIENTATION
:
1436 return SpiGetInt(pvParam
, &gspv
.uiFontSmoothingOrientation
, fl
);
1438 case SPI_SETFONTSMOOTHINGORIENTATION
:
1439 return SpiSetInt(&gspv
.uiFontSmoothingOrientation
, uiParam
, KEY_MOUSE
, L
"", fl
);
1441 /* The following are undocumented, but valid SPI values */
1466 DPRINT1("Undocumented SPI value %x is unimplemented\n", uiAction
);
1470 DPRINT1("Invalid SPI value: %d\n", uiAction
);
1471 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1480 UserSystemParametersInfo(
1488 if (!gbSpiInitialized
)
1490 KeRosDumpStackFrames(NULL
, 20);
1494 /* Get a pointer to the current Windowstation */
1495 gpwinstaCurrent
= IntGetWinStaObj();
1497 if (!gpwinstaCurrent
)
1499 DPRINT1("UserSystemParametersInfo called without active windowstation.\n");
1500 //KeRosDumpStackFrames(NULL, 0);
1503 /* Do the actual operation */
1504 ulResult
= SpiGetSet(uiAction
, uiParam
, pvParam
, fWinIni
);
1506 /* Did we change something? */
1511 /* Update system metrics */
1514 /* Send notification to toplevel windows, if requested */
1515 if (fWinIni
& (SPIF_SENDCHANGE
| SPIF_SENDWININICHANGE
))
1517 /* Send WM_SETTINGCHANGE to all toplevel windows */
1518 co_IntSendMessageTimeout(HWND_BROADCAST
,
1529 /* Dereference the windowstation */
1530 if (gpwinstaCurrent
)
1532 ObDereferenceObject(gpwinstaCurrent
);
1533 gpwinstaCurrent
= NULL
;
1541 NtUserSystemParametersInfo(
1549 DPRINT("Enter NtUserSystemParametersInfo(%d)\n", uiAction
);
1550 UserEnterExclusive();
1552 //if (uiAction == SPI_SETMOUSE) gbDebug = 1;
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 //DPRINTX("NtUserSystemParametersInfo SPI_ICONHORIZONTALSPACING uiParam=%d, pvParam=%p, pvParam=%d bResult=%d\n",
1562 // uiParam, pvParam, pvParam?*(UINT*)pvParam:0, bResult);
1564 DPRINT("Leave NtUserSystemParametersInfo, returning %d\n", bResult
);
1567 //DPRINTX("NtUserSystemParametersInfo SPI_ICONHORIZONTALSPACING bResult=%d\n", bResult);