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\Appearance",,0x00000012
HKCU,"Control Panel\Desktop","CursorBlinkRate",0x00000002,"530" HKCU,"Control Panel\Desktop","CursorBlinkRate",0x00000002,"530"
HKCU,"Control Panel\Desktop","DragFullWindows",0x00000002,"0" HKCU,"Control Panel\Desktop","DragFullWindows",0x00000002,"0"
HKCU,"Control Panel\Desktop","Wallpaper",0x00000000,""
HKCU,"Control Panel\International",,0x00000012 HKCU,"Control Panel\International",,0x00000012
HKCU,"Control Panel\International","Locale",0x00000000,"0409" 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 = ../.. PATH_TO_TOP = ../..
@ -10,7 +10,7 @@ TARGET_PCH = include/user32.h
TARGET_BASE = $(TARGET_BASE_LIB_USER32) 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 = \ TARGET_CFLAGS = \
-I./include \ -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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS user32.dll * PROJECT: ReactOS user32.dll
@ -45,9 +45,21 @@ SystemParametersInfoA(UINT uiAction,
{ {
switch (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_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: case SPI_GETNONCLIENTMETRICS:
{ {
@ -83,6 +95,91 @@ SystemParametersInfoA(UINT uiAction,
RosRtlLogFontW2A(pvParam, &lfw); RosRtlLogFontW2A(pvParam, &lfw);
return TRUE; 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; return FALSE;
@ -98,6 +195,95 @@ SystemParametersInfoW(UINT uiAction,
PVOID pvParam, PVOID pvParam,
UINT fWinIni) 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); return NtUserSystemParametersInfo(uiAction, uiParam, pvParam, fWinIni);
} }

View file

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

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Userinit Logon Application * PROJECT: ReactOS Userinit Logon Application
@ -104,12 +104,45 @@ void StartShell(void)
MessageBox(0, L"Userinit failed to start the shell!\n", NULL, 0); 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 int WINAPI
WinMain(HINSTANCE hInst, WinMain(HINSTANCE hInst,
HINSTANCE hPrevInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, LPSTR lpszCmdLine,
int nCmdShow) int nCmdShow)
{ {
SetUserSettings();
StartShell(); StartShell();
return 0; return 0;
} }

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -688,6 +688,7 @@ NtUserPaintDesktop(HDC hDC)
RECT Rect; RECT Rect;
HBRUSH DesktopBrush, PreviousBrush; HBRUSH DesktopBrush, PreviousBrush;
HWND hWndDesktop; HWND hWndDesktop;
PWINSTATION_OBJECT WinSta = PsGetWin32Thread()->Desktop->WindowStation;
IntGdiGetClipBox(hDC, &Rect); IntGdiGetClipBox(hDC, &Rect);
@ -698,6 +699,46 @@ NtUserPaintDesktop(HDC hDC)
* Paint desktop background * 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); PreviousBrush = NtGdiSelectObject(hDC, DesktopBrush);
NtGdiPatBlt(hDC, Rect.left, Rect.top, Rect.right, Rect.bottom, PATCOPY); NtGdiPatBlt(hDC, Rect.left, Rect.top, Rect.right, Rect.bottom, PATCOPY);
NtGdiSelectObject(hDC, PreviousBrush); 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -677,6 +677,8 @@ IntSystemParametersInfo(
case SPI_SETDOUBLECLKWIDTH: case SPI_SETDOUBLECLKWIDTH:
case SPI_SETDOUBLECLKHEIGHT: case SPI_SETDOUBLECLKHEIGHT:
case SPI_SETDOUBLECLICKTIME: case SPI_SETDOUBLECLICKTIME:
case SPI_SETDESKWALLPAPER:
case SPI_GETDESKWALLPAPER:
{ {
PSYSTEM_CURSORINFO CurInfo; PSYSTEM_CURSORINFO CurInfo;
@ -690,21 +692,68 @@ IntSystemParametersInfo(
return (DWORD)FALSE; return (DWORD)FALSE;
} }
CurInfo = IntGetSysCursorInfo(WinStaObject);
switch(uiAction) switch(uiAction)
{ {
case SPI_SETDOUBLECLKWIDTH: case SPI_SETDOUBLECLKWIDTH:
CurInfo = IntGetSysCursorInfo(WinStaObject);
/* FIXME limit the maximum value? */ /* FIXME limit the maximum value? */
CurInfo->DblClickWidth = uiParam; CurInfo->DblClickWidth = uiParam;
break; break;
case SPI_SETDOUBLECLKHEIGHT: case SPI_SETDOUBLECLKHEIGHT:
CurInfo = IntGetSysCursorInfo(WinStaObject);
/* FIXME limit the maximum value? */ /* FIXME limit the maximum value? */
CurInfo->DblClickHeight = uiParam; CurInfo->DblClickHeight = uiParam;
break; break;
case SPI_SETDOUBLECLICKTIME: case SPI_SETDOUBLECLICKTIME:
CurInfo = IntGetSysCursorInfo(WinStaObject);
/* FIXME limit the maximum time to 1000 ms? */ /* FIXME limit the maximum time to 1000 ms? */
CurInfo->DblClickSpeed = uiParam; CurInfo->DblClickSpeed = uiParam;
break; 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 */ /* FIXME save the value to the registry */
@ -895,6 +944,37 @@ NtUserSystemParametersInfo(
} }
return TRUE; 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: case SPI_GETICONTITLELOGFONT:
{ {
LOGFONTW IconFont; LOGFONTW IconFont;