added very basic support for desktop wallpapers

svn path=/trunk/; revision=10578
This commit is contained in:
Thomas Bluemel 2004-08-17 21:47:36 +00:00
parent 2ac9e121e9
commit c6a9402e60
7 changed files with 362 additions and 8 deletions

View file

@ -7,6 +7,7 @@ HKCU,"Control Panel",,0x00000012
HKCU,"Control Panel\Appearance",,0x00000012
HKCU,"Control Panel\Desktop","CursorBlinkRate",0x00000002,"530"
HKCU,"Control Panel\Desktop","DragFullWindows",0x00000002,"0"
HKCU,"Control Panel\Desktop","Wallpaper",0x00000000,""
HKCU,"Control Panel\International",,0x00000012
HKCU,"Control Panel\International","Locale",0x00000000,"0409"

View file

@ -1,4 +1,4 @@
# $Id: Makefile,v 1.39 2004/08/15 21:36:25 chorns Exp $
# $Id: Makefile,v 1.40 2004/08/17 21:47:36 weiden Exp $
PATH_TO_TOP = ../..
@ -10,7 +10,7 @@ TARGET_PCH = include/user32.h
TARGET_BASE = $(TARGET_BASE_LIB_USER32)
TARGET_SDKLIBS = libwine.a ntdll.a kernel32.a gdi32.a rosrtl.a
TARGET_SDKLIBS = libwine.a ntdll.a gdi32.a rosrtl.a kernel32.a advapi32.a
TARGET_CFLAGS = \
-I./include \

View file

@ -1,4 +1,4 @@
/* $Id: desktop.c,v 1.32 2004/08/15 21:36:27 chorns Exp $
/* $Id: desktop.c,v 1.33 2004/08/17 21:47:36 weiden Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS user32.dll
@ -45,9 +45,21 @@ SystemParametersInfoA(UINT uiAction,
{
switch (uiAction)
{
case SPI_SETDOUBLECLKWIDTH:
case SPI_SETDOUBLECLKHEIGHT:
case SPI_SETDOUBLECLICKTIME:
case SPI_SETGRADIENTCAPTIONS:
case SPI_SETFONTSMOOTHING:
case SPI_SETFOCUSBORDERHEIGHT:
case SPI_SETFOCUSBORDERWIDTH:
case SPI_SETWORKAREA:
case SPI_GETWORKAREA:
case SPI_GETFONTSMOOTHING:
case SPI_GETGRADIENTCAPTIONS:
case SPI_GETFOCUSBORDERHEIGHT:
case SPI_GETFOCUSBORDERWIDTH:
{
return SystemParametersInfoW(uiAction, uiParam, pvParam, fWinIni);
return NtUserSystemParametersInfo(uiAction, uiParam, pvParam, fWinIni);
}
case SPI_GETNONCLIENTMETRICS:
{
@ -83,6 +95,91 @@ SystemParametersInfoA(UINT uiAction,
RosRtlLogFontW2A(pvParam, &lfw);
return TRUE;
}
case SPI_GETDESKWALLPAPER:
{
HKEY hKey;
BOOL Ret = FALSE;
#if 0
/* Get the desktop bitmap handle, this does NOT return the file name! */
if(!NtUserSystemParametersInfo(SPI_GETDESKWALLPAPER, 0, &hbmWallpaper, 0))
{
/* Return an empty string, no wallpapaper is set */
*(CHAR*)pvParam = '\0';
return TRUE;
}
#endif
/* FIXME - Read the registry key for now, but what happens if the wallpaper was
changed without SPIF_UPDATEINIFILE?! */
if(RegOpenKeyExW(HKEY_CURRENT_USER,
L"Control Panel\\Desktop",
0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
{
DWORD Type, Size;
Size = uiParam;
if(RegQueryValueExA(hKey,
"Wallpaper",
NULL,
&Type,
(LPBYTE)pvParam,
&Size) == ERROR_SUCCESS
&& Type == REG_SZ)
{
Ret = TRUE;
}
RegCloseKey(hKey);
}
return Ret;
}
case SPI_SETDESKWALLPAPER:
{
HBITMAP hNewWallpaper;
BOOL Ret;
LPSTR lpWallpaper = (LPSTR)pvParam;
if(lpWallpaper != NULL && *lpWallpaper != '\0')
{
hNewWallpaper = LoadImageA(0, lpWallpaper, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
if(hNewWallpaper == NULL)
{
return FALSE;
}
}
else
{
hNewWallpaper = NULL;
lpWallpaper = NULL;
}
/* Set the wallpaper bitmap */
if(!NtUserSystemParametersInfo(SPI_SETDESKWALLPAPER, 0, &hNewWallpaper, fWinIni & SPIF_SENDCHANGE))
{
if(hNewWallpaper != NULL)
DeleteObject(hNewWallpaper);
return FALSE;
}
/* Do not use the bitmap handle anymore, it doesn't belong to our process anymore! */
Ret = TRUE;
if(fWinIni & SPIF_UPDATEINIFILE)
{
/* Save the path to the file in the registry */
HKEY hKey;
if(RegOpenKeyExW(HKEY_CURRENT_USER,
L"Control Panel\\Desktop",
0, KEY_SET_VALUE, &hKey) == ERROR_SUCCESS)
{
Ret = RegSetValueExA(hKey, "Wallpaper", 0, REG_SZ, (lpWallpaper != NULL ? lpWallpaper : ""),
(lpWallpaper != NULL ? (lstrlenA(lpWallpaper) + 1) * sizeof(CHAR) : sizeof(CHAR)) == ERROR_SUCCESS);
RegCloseKey(hKey);
}
}
RedrawWindow(GetDesktopWindow(), NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
return Ret;
}
}
return FALSE;
@ -98,6 +195,95 @@ SystemParametersInfoW(UINT uiAction,
PVOID pvParam,
UINT fWinIni)
{
switch(uiAction)
{
case SPI_GETDESKWALLPAPER:
{
HKEY hKey;
BOOL Ret = FALSE;
#if 0
/* Get the desktop bitmap handle, this does NOT return the file name! */
if(!NtUserSystemParametersInfo(SPI_GETDESKWALLPAPER, 0, &hbmWallpaper, 0))
{
/* Return an empty string, no wallpapaper is set */
*(WCHAR*)pvParam = L'\0';
return TRUE;
}
#endif
/* FIXME - Read the registry key for now, but what happens if the wallpaper was
changed without SPIF_UPDATEINIFILE?! */
if(RegOpenKeyExW(HKEY_CURRENT_USER,
L"Control Panel\\Desktop",
0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
{
DWORD Type, Size;
Size = uiParam * sizeof(WCHAR);
if(RegQueryValueExW(hKey,
L"Wallpaper",
NULL,
&Type,
(LPBYTE)pvParam,
&Size) == ERROR_SUCCESS
&& Type == REG_SZ)
{
Ret = TRUE;
}
RegCloseKey(hKey);
}
return Ret;
}
case SPI_SETDESKWALLPAPER:
{
HBITMAP hNewWallpaper;
BOOL Ret;
LPWSTR lpWallpaper = (LPWSTR)pvParam;
if(lpWallpaper != NULL && *lpWallpaper != L'\0')
{
hNewWallpaper = LoadImageW(0, lpWallpaper, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
if(hNewWallpaper == NULL)
{
return FALSE;
}
}
else
{
hNewWallpaper = NULL;
lpWallpaper = NULL;
}
/* Set the wallpaper bitmap */
if(!NtUserSystemParametersInfo(SPI_SETDESKWALLPAPER, 0, &hNewWallpaper, fWinIni & SPIF_SENDCHANGE))
{
if(hNewWallpaper != NULL)
DeleteObject(hNewWallpaper);
return FALSE;
}
/* Do not use the bitmap handle anymore, it doesn't belong to our process anymore! */
Ret = TRUE;
if(fWinIni & SPIF_UPDATEINIFILE)
{
/* Save the path to the file in the registry */
HKEY hKey;
if(RegOpenKeyExW(HKEY_CURRENT_USER,
L"Control Panel\\Desktop",
0, KEY_SET_VALUE, &hKey) == ERROR_SUCCESS)
{
Ret = RegSetValueExW(hKey, L"Wallpaper", 0, REG_SZ, (lpWallpaper != NULL ? (LPBYTE)lpWallpaper : (LPBYTE)L""),
(lpWallpaper != NULL ? (lstrlenW(lpWallpaper) + 1) * sizeof(WCHAR) : sizeof(WCHAR)) == ERROR_SUCCESS);
RegCloseKey(hKey);
}
}
RedrawWindow(GetDesktopWindow(), NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
return Ret;
}
}
return NtUserSystemParametersInfo(uiAction, uiParam, pvParam, fWinIni);
}

View file

@ -8,6 +8,13 @@
#define NTOS_MODE_KERNEL
#include <ntos.h>
typedef enum
{
wmCenter = 0,
wmTile,
wmStretch
} WALLPAPER_MODE;
typedef struct _WINSTATION_OBJECT
{
CSHORT Type;
@ -22,6 +29,12 @@ typedef struct _WINSTATION_OBJECT
UINT CaretBlinkRate;
HANDLE ShellWindow;
HANDLE ShellListView;
/* Wallpaper */
HANDLE hbmWallpaper;
ULONG cxWallpaper, cyWallpaper;
WALLPAPER_MODE WallpaperMode;
ULONG Flags;
struct _DESKTOP_OBJECT* ActiveDesktop;
/* FIXME: Clipboard */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: userinit.c,v 1.3 2003/12/27 11:09:58 weiden Exp $
/* $Id: userinit.c,v 1.4 2004/08/17 21:47:36 weiden Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Userinit Logon Application
@ -104,12 +104,45 @@ void StartShell(void)
MessageBox(0, L"Userinit failed to start the shell!\n", NULL, 0);
}
static
void SetUserSettings(void)
{
HKEY hKey;
DWORD Type, Size;
WCHAR szWallpaper[MAX_PATH + 1];
if(RegOpenKeyEx(HKEY_CURRENT_USER,
L"Control Panel\\Desktop",
0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
{
Size = sizeof(szWallpaper);
if(RegQueryValueEx(hKey,
L"Wallpaper",
NULL,
&Type,
(LPBYTE)szWallpaper,
&Size) == ERROR_SUCCESS
&& Type == REG_SZ)
{
/* Change the wallpaper */
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, szWallpaper, SPIF_SENDCHANGE);
}
else
{
/* Set the default wallpaper */
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, NULL, SPIF_SENDCHANGE);
}
RegCloseKey(hKey);
}
}
int WINAPI
WinMain(HINSTANCE hInst,
HINSTANCE hPrevInstance,
LPSTR lpszCmdLine,
int nCmdShow)
{
SetUserSettings();
StartShell();
return 0;
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: desktop.c,v 1.18 2004/08/08 17:57:34 weiden Exp $
* $Id: desktop.c,v 1.19 2004/08/17 21:47:36 weiden Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -688,6 +688,7 @@ NtUserPaintDesktop(HDC hDC)
RECT Rect;
HBRUSH DesktopBrush, PreviousBrush;
HWND hWndDesktop;
PWINSTATION_OBJECT WinSta = PsGetWin32Thread()->Desktop->WindowStation;
IntGdiGetClipBox(hDC, &Rect);
@ -698,6 +699,46 @@ NtUserPaintDesktop(HDC hDC)
* Paint desktop background
*/
if(WinSta->hbmWallpaper != NULL)
{
PWINDOW_OBJECT DeskWin;
DbgPrint("Paint 1\n");
if((DeskWin = IntGetWindowObject(hWndDesktop)))
{
SIZE sz;
int x, y;
HDC hWallpaperDC;
sz.cx = DeskWin->WindowRect.right - DeskWin->WindowRect.left;
sz.cy = DeskWin->WindowRect.bottom - DeskWin->WindowRect.top;
IntReleaseWindowObject(DeskWin);
DbgPrint("Paint 2\n");
x = (sz.cx / 2) - (WinSta->cxWallpaper / 2);
y = (sz.cy / 2) - (WinSta->cyWallpaper / 2);
hWallpaperDC = NtGdiCreateCompatableDC(hDC);
if(hWallpaperDC != NULL)
{
HBITMAP hOldBitmap;
DbgPrint("Paint 3->%d, %d, %d, %d\n", x, y, sz.cx, sz.cy);
if(x > 0 || y > 0)
{
/* FIXME - clip out the bitmap */
PreviousBrush = NtGdiSelectObject(hDC, DesktopBrush);
NtGdiPatBlt(hDC, Rect.left, Rect.top, Rect.right, Rect.bottom, PATCOPY);
NtGdiSelectObject(hDC, PreviousBrush);
}
hOldBitmap = NtGdiSelectObject(hWallpaperDC, WinSta->hbmWallpaper);
NtGdiBitBlt(hDC, x, y, WinSta->cxWallpaper, WinSta->cyWallpaper, hWallpaperDC, 0, 0, SRCCOPY);
NtGdiSelectObject(hWallpaperDC, hOldBitmap);
NtGdiDeleteDC(hWallpaperDC);
if(x <= 0 && y <= 0) return TRUE;
}
}
}
PreviousBrush = NtGdiSelectObject(hDC, DesktopBrush);
NtGdiPatBlt(hDC, Rect.left, Rect.top, Rect.right, Rect.bottom, PATCOPY);
NtGdiSelectObject(hDC, PreviousBrush);

View file

@ -1,4 +1,4 @@
/* $Id: misc.c,v 1.83 2004/07/12 20:09:35 gvg Exp $
/* $Id: misc.c,v 1.84 2004/08/17 21:47:36 weiden Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -677,6 +677,8 @@ IntSystemParametersInfo(
case SPI_SETDOUBLECLKWIDTH:
case SPI_SETDOUBLECLKHEIGHT:
case SPI_SETDOUBLECLICKTIME:
case SPI_SETDESKWALLPAPER:
case SPI_GETDESKWALLPAPER:
{
PSYSTEM_CURSORINFO CurInfo;
@ -690,21 +692,68 @@ IntSystemParametersInfo(
return (DWORD)FALSE;
}
CurInfo = IntGetSysCursorInfo(WinStaObject);
switch(uiAction)
{
case SPI_SETDOUBLECLKWIDTH:
CurInfo = IntGetSysCursorInfo(WinStaObject);
/* FIXME limit the maximum value? */
CurInfo->DblClickWidth = uiParam;
break;
case SPI_SETDOUBLECLKHEIGHT:
CurInfo = IntGetSysCursorInfo(WinStaObject);
/* FIXME limit the maximum value? */
CurInfo->DblClickHeight = uiParam;
break;
case SPI_SETDOUBLECLICKTIME:
CurInfo = IntGetSysCursorInfo(WinStaObject);
/* FIXME limit the maximum time to 1000 ms? */
CurInfo->DblClickSpeed = uiParam;
break;
case SPI_SETDESKWALLPAPER:
{
/* This function expects different parameters than the user mode version!
We let the user mode code load the bitmap, it passed the handle to
the bitmap. We'll change it's ownership to system and replace it with
the current wallpaper bitmap */
HBITMAP hOldBitmap, hNewBitmap;
ASSERT(pvParam);
hNewBitmap = *(HBITMAP*)pvParam;
if(hNewBitmap != NULL)
{
BITMAPOBJ *bmp;
/* try to get the size of the wallpaper */
if(!(bmp = BITMAPOBJ_LockBitmap(hNewBitmap)))
{
ObDereferenceObject(WinStaObject);
return FALSE;
}
WinStaObject->cxWallpaper = bmp->SurfObj.sizlBitmap.cx;
WinStaObject->cyWallpaper = bmp->SurfObj.sizlBitmap.cy;
BITMAPOBJ_UnlockBitmap(hNewBitmap);
/* change the bitmap's ownership */
GDIOBJ_SetOwnership(hNewBitmap, NULL);
}
hOldBitmap = (HBITMAP)InterlockedExchange((LONG*)&WinStaObject->hbmWallpaper, (LONG)hNewBitmap);
if(hOldBitmap != NULL)
{
/* delete the old wallpaper */
NtGdiDeleteObject(hOldBitmap);
}
break;
}
case SPI_GETDESKWALLPAPER:
/* This function expects different parameters than the user mode version!
We basically return the current wallpaper handle - if any. The user
mode version should load the string from the registry and return it
without calling this function */
ASSERT(pvParam);
*(HBITMAP*)pvParam = (HBITMAP)WinStaObject->hbmWallpaper;
break;
}
/* FIXME save the value to the registry */
@ -895,6 +944,37 @@ NtUserSystemParametersInfo(
}
return TRUE;
}
case SPI_SETDESKWALLPAPER:
{
/* !!! As opposed to the user mode version this version accepts a handle
to the bitmap! */
HBITMAP hbmWallpaper;
Status = MmCopyFromCaller(&hbmWallpaper, pvParam, sizeof(HBITMAP));
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return FALSE;
}
return IntSystemParametersInfo(SPI_SETDESKWALLPAPER, 0, &hbmWallpaper, fWinIni);
}
case SPI_GETDESKWALLPAPER:
{
/* !!! As opposed to the user mode version this version returns a handle
to the bitmap! */
HBITMAP hbmWallpaper;
BOOL Ret;
Ret = IntSystemParametersInfo(SPI_GETDESKWALLPAPER, 0, &hbmWallpaper, fWinIni);
Status = MmCopyToCaller(pvParam, &hbmWallpaper, sizeof(HBITMAP));
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return FALSE;
}
return Ret;
}
case SPI_GETICONTITLELOGFONT:
{
LOGFONTW IconFont;