Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1751 lines
52 KiB

/****************************** Module Header ******************************\
* Module Name: dtbitmap.c
*
* Copyright (c) 1985 - 1999, Microsoft Corporation
*
* Desktop Wallpaper Routines.
*
* History:
* 29-Jul-1991 MikeKe From win31
\***************************************************************************/
#include "precomp.h"
#pragma hdrstop
/*
* Local Constants.
*/
#define MAXPAL 256
#define MAXSTATIC 20
#define TILE_XMINSIZE 2
#define TILE_YMINSIZE 4
/*
* The version strings are stored in a contiguous-buffer. Each string
* is of size MAXVERSIONSTRING.
*/
// Size of each string buffer.
#define MAXVERSIONSTRING 128
// Offset into verbuffer of build-string.
#define OFFSET_BLDSTRING 0
// Offset into verbuffer of CSD string.
#define OFFSET_CSDSTRING OFFSET_BLDSTRING + MAXVERSIONSTRING
// Max size of buffer (contains all 3 strings).
#define MAXVERSIONBUFFER OFFSET_CSDSTRING + MAXVERSIONSTRING
WCHAR wszSafeMode[MAX_PATH + 3 * MAXVERSIONSTRING];
WCHAR SafeModeStr[64];
int SafeModeStrLen;
WCHAR wszProductName[MAXVERSIONSTRING];
WCHAR wszProductBuild[2 * MAXVERSIONSTRING];
__inline PWND _GetShellWindow(
PDESKTOP pdesk)
{
if (pdesk == NULL) {
return NULL;
} else {
return pdesk->pDeskInfo->spwndShell;
}
}
/***************************************************************************\
* GetVersionInfo
*
* Outputs a string on the desktop indicating debug-version.
*
* History:
\***************************************************************************/
VOID
GetVersionInfo(
BOOL Verbose)
{
WCHAR NameBuffer[MAXVERSIONBUFFER];
WCHAR Title1[MAXVERSIONSTRING];
WCHAR Title2[MAXVERSIONSTRING];
WCHAR wszPID[MAXVERSIONSTRING];
WCHAR wszProduct[MAXVERSIONSTRING];
WCHAR wszPBuild[MAXVERSIONSTRING];
WCHAR wszEvaluation[MAXVERSIONSTRING];
UNICODE_STRING UserBuildString;
UNICODE_STRING UserCSDString;
NTSTATUS Status;
UINT uProductStrId;
/*
* Temporary code name handling. Used internally and turned off by ""
* for release. The matching string in strid.mc doesn't have a space
* separator between code name and the rest of the title, so this
* space must be included at end of this code name string.
*/
WCHAR wszCodeName[] = L"";
RTL_QUERY_REGISTRY_TABLE BaseServerRegistryConfigurationTable[] = {
{NULL,
RTL_QUERY_REGISTRY_DIRECT,
#ifdef PRERELEASE
L"BuildLab",
#else
L"CurrentBuildNumber",
#endif // PRERELEASE
&UserBuildString,
REG_NONE,
NULL,
0},
{NULL,
RTL_QUERY_REGISTRY_DIRECT,
L"CSDVersion",
&UserCSDString,
REG_NONE,
NULL,
0},
{NULL,
0,
NULL,
NULL,
REG_NONE,
NULL,
0}
};
UserBuildString.Buffer = &NameBuffer[OFFSET_BLDSTRING];
UserBuildString.Length = 0;
UserBuildString.MaximumLength = MAXVERSIONSTRING * sizeof(WCHAR);
UserCSDString.Buffer = &NameBuffer[OFFSET_CSDSTRING];
UserCSDString.Length = 0;
UserCSDString.MaximumLength = MAXVERSIONSTRING * sizeof(WCHAR);
Status = RtlQueryRegistryValues(RTL_REGISTRY_WINDOWS_NT,
L"",
BaseServerRegistryConfigurationTable,
NULL,
NULL);
if (!NT_SUCCESS(Status)) {
RIPMSG1(RIP_WARNING, "GetVersionInfo failed with status %x", Status);
return;
}
ServerLoadString(hModuleWin, STR_DTBS_PRODUCTID, wszPID, ARRAY_SIZE(wszPID));
ServerLoadString(hModuleWin, STR_DTBS_PRODUCTBUILD, wszPBuild, ARRAY_SIZE(wszPBuild));
/*
* Write out Debugging Version message.
*/
/*
* Bug 280256 - joejo
* Create new desktop build information strings
*/
if (USER_SHARED_DATA->SuiteMask & (1 << EmbeddedNT)) {
uProductStrId = STR_DTBS_PRODUCTEMB;
} else if (USER_SHARED_DATA->NtProductType == NtProductWinNt) {
#ifdef _WIN64
uProductStrId = STR_DTBS_PRODUCTWKS64;
#else
if (USER_SHARED_DATA->SuiteMask & (1 << Personal)) {
uProductStrId = STR_DTBS_PRODUCTPER;
} else {
uProductStrId = STR_DTBS_PRODUCTPRO;
}
#endif
} else {
#ifdef _WIN64
if (USER_SHARED_DATA->SuiteMask & (1 << DataCenter)) {
uProductStrId = STR_DTBS_PRODUCTDTC64;
} else if (USER_SHARED_DATA->SuiteMask & (1 << Enterprise)) {
uProductStrId = STR_DTBS_PRODUCTADV64;
} else {
uProductStrId = STR_DTBS_PRODUCTSRV64;
}
#else
if (USER_SHARED_DATA->SuiteMask & (1 << DataCenter)) {
uProductStrId = STR_DTBS_PRODUCTDTC;
} else if (USER_SHARED_DATA->SuiteMask & (1 << Enterprise)) {
uProductStrId = STR_DTBS_PRODUCTADV;
} else if (USER_SHARED_DATA->SuiteMask & (1 << Blade)) {
uProductStrId = STR_DTBS_PRODUCTBLA;
} else if(USER_SHARED_DATA->SuiteMask & (1 << SmallBusinessRestricted)) {
uProductStrId = STR_DTBS_PRODUCTSBS;
} else {
uProductStrId = STR_DTBS_PRODUCTSRV;
}
#endif /* _WIN64 */
}
ServerLoadString(hModuleWin, uProductStrId, wszProduct, ARRAY_SIZE(wszProduct));
swprintf(
wszProductName,
wszPID,
wszCodeName,
wszProduct);
if (gfUnsignedDrivers) {
/* This takes precedence */
ServerLoadString(hModuleWin, STR_TESTINGONLY, wszEvaluation, ARRAY_SIZE(wszEvaluation));
} else if (USER_SHARED_DATA->SystemExpirationDate.QuadPart) {
ServerLoadString(hModuleWin, STR_DTBS_EVALUATION, wszEvaluation, ARRAY_SIZE(wszEvaluation));
} else {
wszEvaluation[0] = '\0';
}
swprintf(
wszProductBuild,
wszPBuild,
wszEvaluation,
UserBuildString.Buffer
);
if (Verbose) {
ServerLoadString(hModuleWin, STR_SAFEMODE_TITLE1, Title1, ARRAY_SIZE(Title1));
ServerLoadString(hModuleWin, STR_SAFEMODE_TITLE2, Title2, ARRAY_SIZE(Title2));
swprintf(
wszSafeMode,
UserCSDString.Length == 0 ? Title1 : Title2,
wszCodeName,
UserBuildString.Buffer,
UserCSDString.Buffer,
USER_SHARED_DATA->NtSystemRoot
);
} else {
ServerLoadString(hModuleWin, STR_SAFEMODE_TITLE3, Title1, ARRAY_SIZE(Title1));
ServerLoadString(hModuleWin, STR_SAFEMODE_TITLE4, Title2, ARRAY_SIZE(Title2));
swprintf(
wszSafeMode,
UserCSDString.Length == 0 ? Title1 : Title2,
wszCodeName,
UserBuildString.Buffer,
UserCSDString.Buffer);
}
}
/***************************************************************************\
* GetDefaultWallpaperName
*
* Get initial bitmap name
*
* History:
* 21-Feb-1995 JimA Created.
* 06-Mar-1996 ChrisWil Moved to kernel to facilite ChangeDisplaySettings.
\***************************************************************************/
VOID
GetDefaultWallpaperName(
LPWSTR lpszWallpaper)
{
/*
* Set the initial global wallpaper bitmap name for (Default)
* The global name is an at most 8 character name with no
* extension. It is "winnt" for workstation or "lanmannt"
* for server or server upgrade. It is followed by 256 it
* is for 256 color devices.
*/
if (USER_SHARED_DATA->NtProductType == NtProductWinNt) {
wcsncpycch(lpszWallpaper, L"winnt", 8);
} else {
wcsncpycch(lpszWallpaper, L"lanmannt", 8);
}
lpszWallpaper[8] = (WCHAR)0;
if (gpsi->BitsPixel * gpsi->Planes > 4) {
int iStart = wcslen(lpszWallpaper);
iStart = min(iStart, 5);
lpszWallpaper[iStart] = (WCHAR)0;
wcscat(lpszWallpaper, L"256");
}
}
/***************************************************************************\
* GetDeskWallpaperName
*
* History:
* 19-Dec-1994 JimA Created.
* 29-Sep-1995 ChrisWil ReWrote to return filename.
\***************************************************************************/
#define GDWPN_KEYSIZE 40
#define GDWPN_BITSIZE 256
LPWSTR GetDeskWallpaperName(PUNICODE_STRING pProfileUserName,
LPWSTR lpszFile
)
{
WCHAR wszKey[GDWPN_KEYSIZE];
WCHAR wszNone[GDWPN_KEYSIZE];
LPWSTR lpszBitmap = NULL;
/*
* Load the none-string. This will be used for comparisons later.
*/
ServerLoadString(hModuleWin, STR_NONE, wszNone, ARRAY_SIZE(wszNone));
if ((lpszFile == NULL) ||
(lpszFile == SETWALLPAPER_DEFAULT) ||
(lpszFile == SETWALLPAPER_METRICS)) {
/*
* Allocate a buffer for the wallpaper. We will assume
* a default-size in this case.
*/
lpszBitmap = UserAllocPool(GDWPN_BITSIZE * sizeof(WCHAR), TAG_SYSTEM);
if (lpszBitmap == NULL)
return NULL;
/*
* Get the "Wallpaper" string from WIN.INI's [Desktop] section. The
* section name is not localized, so hard code it. If the string
* returned is Empty, then set it up for a none-wallpaper.
*
* Unlike the rest of per user settings that got updated in
* xxxUpdatePerUserSystemParameters, wallpaper is being updated via a
* direct call to SystemParametersInfo from UpdatePerUserSystemParameters.
* Force remote settings check in this case.
*/
if (!FastGetProfileStringFromIDW(pProfileUserName,
PMAP_DESKTOP,
STR_DTBITMAP,
wszNone,
lpszBitmap,
GDWPN_BITSIZE,
POLICY_REMOTE
)) {
wcscpy(lpszBitmap, wszNone);
}
} else {
UINT uLen;
uLen = wcslen(lpszFile) + 1;
uLen = max(uLen, GDWPN_BITSIZE);
/*
* Allocate enough space to store the name passed in. Returning
* NULL will allow the wallpaper to redraw. As well, if we're
* out of memory, then no need to load a wallpaper anyway.
*/
lpszBitmap = UserAllocPool(uLen * sizeof(WCHAR), TAG_SYSTEM);
if (lpszBitmap == NULL)
return NULL;
wcscpy(lpszBitmap, lpszFile);
}
/*
* No bitmap if NULL passed in or if (NONE) in win.ini entry. We
* return NULL to force the redraw of the wallpaper in the kernel.
*/
if ((*lpszBitmap == (WCHAR)0) || (_wcsicmp(lpszBitmap, wszNone) == 0)) {
UserFreePool(lpszBitmap);
return NULL;
}
/*
* If bitmap name set to (DEFAULT) then set it to the system bitmap.
*/
ServerLoadString(hModuleWin, STR_DEFAULT, wszKey, ARRAY_SIZE(wszKey));
if (_wcsicmp(lpszBitmap, wszKey) == 0) {
GetDefaultWallpaperName(lpszBitmap);
}
return lpszBitmap;
}
/***************************************************************************\
* TestVGAColors
*
* Tests whether the log-palette is just a standard 20 palette.
*
* History:
* 29-Sep-1995 ChrisWil Created.
\***************************************************************************/
BOOL TestVGAColors(
LPLOGPALETTE ppal)
{
int i;
int n;
int size;
COLORREF clr;
static CONST DWORD StupidColors[] = {
0x00000000, // 0 Sys Black
0x00000080, // 1 Sys Dk Red
0x00008000, // 2 Sys Dk Green
0x00008080, // 3 Sys Dk Yellow
0x00800000, // 4 Sys Dk Blue
0x00800080, // 5 Sys Dk Violet
0x00808000, // 6 Sys Dk Cyan
0x00c0c0c0, // 7 Sys Lt Grey
0x00808080, // 248 Sys Lt Gray
0x000000ff, // 249 Sys Red
0x0000ff00, // 250 Sys Green
0x0000ffff, // 251 Sys Yellow
0x00ff0000, // 252 Sys Blue
0x00ff00ff, // 253 Sys Violet
0x00ffff00, // 254 Sys Cyan
0x00ffffff, // 255 Sys White
0x000000BF, // 1 Sys Dk Red again
0x0000BF00, // 2 Sys Dk Green again
0x0000BFBF, // 3 Sys Dk Yellow again
0x00BF0000, // 4 Sys Dk Blue again
0x00BF00BF, // 5 Sys Dk Violet again
0x00BFBF00, // 6 Sys Dk Cyan again
0x000000C0, // 1 Sys Dk Red again
0x0000C000, // 2 Sys Dk Green again
0x0000C0C0, // 3 Sys Dk Yellow again
0x00C00000, // 4 Sys Dk Blue again
0x00C000C0, // 5 Sys Dk Violet again
0x00C0C000, // 6 Sys Dk Cyan again
};
size = (sizeof(StupidColors) / sizeof(StupidColors[0]));
for (i = 0; i < (int)ppal->palNumEntries; i++) {
clr = ((LPDWORD)ppal->palPalEntry)[i];
for (n = 0; n < size; n++) {
if (StupidColors[n] == clr)
break;
}
if (n == size)
return FALSE;
}
return TRUE;
}
/***************************************************************************\
* DoHTColorAdjustment
*
* The default HT-Gamma adjustment was 2.0 on 3.5 (internal to gdi). For
* 3.51 this value was decreased to 1.0 to accomdate printing. For our
* desktop-wallpaper we are going to darken it slightly to that the image
* doesn't appear to light. For the Shell-Release we will provid a UI to
* allow users to change this for themselves.
*
*
* History:
* 11-May-1995 ChrisWil Created.
\***************************************************************************/
#define FIXED_GAMMA (WORD)13000
VOID DoHTColorAdjust(
HDC hdc)
{
COLORADJUSTMENT ca;
if (GreGetColorAdjustment(hdc, &ca)) {
ca.caRedGamma =
ca.caGreenGamma =
ca.caBlueGamma = FIXED_GAMMA;
GreSetColorAdjustment(hdc, &ca);
}
}
/***************************************************************************\
* ConvertToDDB
*
* Converts a DIBSection to a DDB. We do this to speed up drawings so that
* bitmap-colors don't have to go through a palette-translation match. This
* will also stretch/expand the image if the syle is set.
*
* If the new image requires a halftone-palette, the we will create one and
* set it as the new wallpaper-palette.
*
* History:
* 26-Oct-1995 ChrisWil Ported.
* 30-Oct-1995 ChrisWil Added halftoning. Rewote the stretch/expand stuff.
\***************************************************************************/
HBITMAP ConvertToDDB(
HDC hdc,
HBITMAP hbmOld,
HPALETTE hpal)
{
BITMAP bm;
HBITMAP hbmNew;
/*
* This object must be a REALDIB type bitmap.
*/
GreExtGetObjectW(hbmOld, sizeof(bm), &bm);
/*
* Create the new wallpaper-surface.
*/
if (hbmNew = GreCreateCompatibleBitmap(hdc, bm.bmWidth, bm.bmHeight)) {
HPALETTE hpalDst;
HPALETTE hpalSrc;
HBITMAP hbmDst;
HBITMAP hbmSrc;
UINT bpp;
BOOL fHalftone = FALSE;
/*
* Select in the surfaces.
*/
hbmDst = GreSelectBitmap(ghdcMem2, hbmNew);
hbmSrc = GreSelectBitmap(ghdcMem, hbmOld);
/*
* Determine image bits/pixel.
*/
bpp = (bm.bmPlanes * bm.bmBitsPixel);
/*
* Use the palette if given. If the image is of a greater
* resolution than the device, then we're going to go through
* a halftone-palette to get better colors.
*/
if (hpal) {
hpalDst = _SelectPalette(ghdcMem2, hpal, FALSE);
hpalSrc = _SelectPalette(ghdcMem, hpal, FALSE);
xxxRealizePalette(ghdcMem2);
/*
* Set the halftoning for the destination. This is done
* for images of greater resolution than the device.
*/
if (bpp > gpsi->BitCount) {
fHalftone = TRUE;
DoHTColorAdjust(ghdcMem2);
}
}
/*
* Set the stretchbltmode. This is more necessary when doing
* halftoning. Since otherwise, the colors won't translate
* correctly.
*/
SetBestStretchMode(ghdcMem2, bpp, fHalftone);
/*
* Set the new surface bits. Use StretchBlt() so the SBMode
* will be used in color-translation.
*/
GreStretchBlt(ghdcMem2,
0,
0,
bm.bmWidth,
bm.bmHeight,
ghdcMem,
0,
0,
bm.bmWidth,
bm.bmHeight,
SRCCOPY,
0);
/*
* Restore palettes.
*/
if (hpal) {
_SelectPalette(ghdcMem2, hpalDst, FALSE);
_SelectPalette(ghdcMem, hpalSrc, FALSE);
}
/*
* Restore the surfaces.
*/
GreSelectBitmap(ghdcMem2, hbmDst);
GreSelectBitmap(ghdcMem, hbmSrc);
GreDeleteObject(hbmOld);
GreSetBitmapOwner(hbmNew, OBJECT_OWNER_PUBLIC);
} else {
hbmNew = hbmOld;
}
return hbmNew;
}
/***************************************************************************\
* CreatePaletteFromBitmap
*
* Take in a REAL dib handle and create a palette from it. This will not
* work for bitmaps created by any other means than CreateDIBSection or
* CreateDIBitmap(CBM_CREATEDIB). This is due to the fact that these are
* the only two formats who have palettes stored with their object.
*
* History:
* 29-Sep-1995 ChrisWil Created.
\***************************************************************************/
HPALETTE CreatePaletteFromBitmap(
HBITMAP hbm)
{
HPALETTE hpal;
LPLOGPALETTE ppal;
HBITMAP hbmT;
DWORD size;
int i;
/*
* Make room for temp logical palette of max size.
*/
size = sizeof(LOGPALETTE) + (MAXPAL * sizeof(PALETTEENTRY));
ppal = (LPLOGPALETTE)UserAllocPool(size, TAG_SYSTEM);
if (!ppal)
return NULL;
/*
* Retrieve the palette from the DIB(Section). The method of calling
* GreGetDIBColorTable() can only be done on sections or REAL-Dibs.
*/
hbmT = GreSelectBitmap(ghdcMem, hbm);
ppal->palVersion = 0x300;
ppal->palNumEntries = (WORD)GreGetDIBColorTable(ghdcMem,
0,
MAXPAL,
(LPRGBQUAD)ppal->palPalEntry);
GreSelectBitmap(ghdcMem, hbmT);
/*
* Create a halftone-palette if their are no entries. Otherwise,
* swap the RGB values to be palentry-compatible and create us a
* palette.
*/
if (ppal->palNumEntries == 0) {
hpal = GreCreateHalftonePalette(gpDispInfo->hdcScreen);
} else {
BYTE tmpR;
/*
* Swap red/blue because a RGBQUAD and PALETTEENTRY dont get along.
*/
for (i=0; i < (int)ppal->palNumEntries; i++) {
tmpR = ppal->palPalEntry[i].peRed;
ppal->palPalEntry[i].peRed = ppal->palPalEntry[i].peBlue;
ppal->palPalEntry[i].peBlue = tmpR;
ppal->palPalEntry[i].peFlags = 0;
}
/*
* If the Bitmap only has VGA colors in it we dont want to
* use a palette. It just causes unessesary palette flashes.
*/
hpal = TestVGAColors(ppal) ? NULL : GreCreatePalette(ppal);
}
UserFreePool(ppal);
/*
* Make this palette public.
*/
if (hpal)
GreSetPaletteOwner(hpal, OBJECT_OWNER_PUBLIC);
return hpal;
}
/***************************************************************************\
* TileWallpaper
*
* History:
* 29-Jul-1991 MikeKe From win31
\***************************************************************************/
BOOL
TileWallpaper(HDC hdc, LPCRECT lprc, BOOL fOffset)
{
int xO;
int yO;
int x;
int y;
BITMAP bm;
HBITMAP hbmT = NULL;
POINT ptOffset;
if (fOffset) {
ptOffset.x = gsrcWallpaper.x;
ptOffset.y = gsrcWallpaper.y;
} else {
ptOffset.x = 0;
ptOffset.y = 0;
}
/*
* We need to get the dimensions of the bitmap here rather than rely on
* the dimensions in srcWallpaper because this function may
* be called as part of ExpandBitmap, before srcWallpaper is
* set.
*/
if (GreExtGetObjectW(ghbmWallpaper, sizeof(BITMAP), (PBITMAP)&bm)) {
xO = lprc->left - (lprc->left % bm.bmWidth) + (ptOffset.x % bm.bmWidth);
if (xO > lprc->left) {
xO -= bm.bmWidth;
}
yO = lprc->top - (lprc->top % bm.bmHeight) + (ptOffset.y % bm.bmHeight);
if (yO > lprc->top) {
yO -= bm.bmHeight;
}
/*
* Tile the bitmap to the surface.
*/
if (hbmT = GreSelectBitmap(ghdcMem, ghbmWallpaper)) {
for (y = yO; y < lprc->bottom; y += bm.bmHeight) {
for (x = xO; x < lprc->right; x += bm.bmWidth) {
GreBitBlt(hdc,
x,
y,
bm.bmWidth,
bm.bmHeight,
ghdcMem,
0,
0,
SRCCOPY,
0);
}
}
GreSelectBitmap(ghdcMem, hbmT);
}
}
return (hbmT != NULL);
}
/***************************************************************************\
* GetWallpaperCenterRect
*
* Returns the rect of centered wallpaper on a particular monitor.
*
* History:
* 26-Sep-1996 adams Created.
\***************************************************************************/
BOOL
GetWallpaperCenterRect(LPRECT lprc, LPPOINT lppt, LPCRECT lprcMonitor)
{
RECT rc;
if (gsrcWallpaper.x != 0 || gsrcWallpaper.y != 0) {
rc.left = lprcMonitor->left + gsrcWallpaper.x;
rc.top = lprcMonitor->top + gsrcWallpaper.y;
} else {
rc.left = (lprcMonitor->left + lprcMonitor->right - gsrcWallpaper.cx) / 2;
rc.top = (lprcMonitor->top + lprcMonitor->bottom - gsrcWallpaper.cy) / 2;
}
rc.right = rc.left + gsrcWallpaper.cx;
rc.bottom = rc.top + gsrcWallpaper.cy;
lppt->x = max(0, lprcMonitor->left - rc.left);
lppt->y = max(0, lprcMonitor->top - rc.top);
return IntersectRect(lprc, &rc, lprcMonitor);
}
/***************************************************************************\
* CenterOrStretchWallpaper
*
*
* History:
* 29-Jul-1991 MikeKe From win31
\***************************************************************************/
BOOL
CenterOrStretchWallpaper(HDC hdc, LPCRECT lprcMonitor)
{
BOOL fStretchToEachMonitor = FALSE;
RECT rc;
HBITMAP hbmT;
BOOL f = FALSE;
HRGN hrgn;
POINT pt;
BITMAP bm;
int oldStretchMode;
/*
* This used to call TileWallpaper, but this really slowed up the system
* for small dimension bitmaps. We really only need to blt it once for
* centered bitmaps.
*/
if (hbmT = GreSelectBitmap(ghdcMem, ghbmWallpaper)) {
if (fStretchToEachMonitor && (gwWPStyle & DTF_STRETCH)) {
if (GreExtGetObjectW(ghbmWallpaper, sizeof(BITMAP), (PBITMAP)&bm)) {
oldStretchMode = GreSetStretchBltMode(hdc, COLORONCOLOR);
f = GreStretchBlt(hdc,
lprcMonitor->left,
lprcMonitor->top,
lprcMonitor->right - lprcMonitor->left,
lprcMonitor->bottom - lprcMonitor->top,
ghdcMem,
0,
0,
bm.bmWidth,
bm.bmHeight,
SRCCOPY,
0);
GreSetStretchBltMode(hdc, oldStretchMode);
}
} else {
if (GetWallpaperCenterRect(&rc, &pt, lprcMonitor)) {
f = GreBitBlt(hdc,
rc.left,
rc.top,
rc.right - rc.left,
rc.bottom - rc.top,
ghdcMem,
pt.x,
pt.y,
SRCCOPY,
0);
/*
* Fill the bacground (excluding the bitmap) with the desktop
* brush. Save the DC with the cliprect.
*/
if (f && NULL != (hrgn = CreateEmptyRgn())) {
if (GreGetRandomRgn(hdc, hrgn, 1) != -1) {
GreExcludeClipRect(hdc, rc.left, rc.top, rc.right, rc.bottom);
FillRect(hdc, lprcMonitor, SYSHBR(DESKTOP));
GreExtSelectClipRgn(hdc, hrgn, RGN_COPY);
}
GreDeleteObject(hrgn);
}
}
}
GreSelectBitmap(ghdcMem, hbmT);
}
/*
* As a last-ditch effort, if something failed, just clear the desktop.
*/
if (!f) {
FillRect(hdc, lprcMonitor, SYSHBR(DESKTOP));
}
return f;
}
/***************************************************************************\
* xxxDrawWallpaper
*
* Performs the drawing of the wallpaper. This can be either tiled or
* centered. This routine provides the common things like palette-handling.
* If the (fPaint) is false, then we only to palette realization and no
* drawing.
*
* History:
* 01-Oct-1995 ChrisWil Ported.
\***************************************************************************/
BOOL xxxDrawWallpaper(
PWND pwnd,
HDC hdc,
PMONITOR pMonitorPaint,
LPCRECT lprc)
{
BOOL f;
HPALETTE hpalT;
int i;
CheckLock(pwnd);
CheckLock(pMonitorPaint);
UserAssert(ghbmWallpaper != NULL);
UserAssert(lprc);
/*
* Select in the palette if one exists. As a wallpaper, we should only
* be able to do background-realizations.
*/
if (ghpalWallpaper && pMonitorPaint->dwMONFlags & MONF_PALETTEDISPLAY) {
hpalT = _SelectPalette(hdc, ghpalWallpaper, FALSE);
i = xxxRealizePalette(hdc);
} else {
hpalT = NULL;
}
if (gwWPStyle & DTF_TILE) {
f = TileWallpaper(hdc, lprc, pwnd != NULL);
} else {
f = CenterOrStretchWallpaper(hdc, &pMonitorPaint->rcMonitor);
}
if (hpalT) {
_SelectPalette(hdc, hpalT, FALSE);
}
return f;
}
/***************************************************************************\
* xxxExpandBitmap
*
* Expand this bitmap to fit the screen. This is used for tiled images
* only.
*
* History:
* 29-Sep-1995 ChrisWil Ported from Chicago.
\***************************************************************************/
HBITMAP xxxExpandBitmap(
HBITMAP hbm)
{
int nx;
int ny;
BITMAP bm;
HBITMAP hbmNew;
HBITMAP hbmD;
LPRECT lprc;
RECT rc;
PMONITOR pMonitor;
TL tlpMonitor;
/*
* Get the dimensions of the screen and bitmap we'll be dealing with.
* We'll adjust the xScreen/yScreen to reflect the new surface size.
* The default adjustment is to stretch the image to fit the screen.
*/
GreExtGetObjectW(hbm, sizeof(bm), (PBITMAP)&bm);
pMonitor = GetPrimaryMonitor();
lprc = &pMonitor->rcMonitor;
nx = (lprc->right / TILE_XMINSIZE) / bm.bmWidth;
ny = (lprc->bottom / TILE_YMINSIZE) / bm.bmHeight;
if (nx == 0)
nx++;
if (ny == 0)
ny++;
if ((nx + ny) <= 2)
return hbm;
/*
* Create the surface for the new-bitmap.
*/
rc.left = rc.top = 0;
rc.right = nx * bm.bmWidth;
rc.bottom = ny * bm.bmHeight;
hbmD = GreSelectBitmap(ghdcMem, hbm);
hbmNew = GreCreateCompatibleBitmap(ghdcMem, rc.right, rc.bottom);
GreSelectBitmap(ghdcMem, hbmD);
if (hbmNew == NULL)
return hbm;
if (hbmD = GreSelectBitmap(ghdcMem2, hbmNew)) {
/*
* Expand the bitmap to the new surface.
*/
ThreadLockAlways(pMonitor, &tlpMonitor);
xxxDrawWallpaper(NULL, ghdcMem2, pMonitor, &rc);
ThreadUnlock(&tlpMonitor);
GreSelectBitmap(ghdcMem2, hbmD);
}
GreDeleteObject(hbm);
GreSetBitmapOwner(hbmNew, OBJECT_OWNER_PUBLIC);
return hbmNew;
}
/***************************************************************************\
* xxxLoadDesktopWallpaper
*
* Load the dib (section) from the client-side. We make this callback to
* utilize code in USER32 for loading/creating a dib or section. Since,
* the wallpaper-code can be called from any-process, we can't use DIBSECTIONS
* for a wallpaper. Luckily we can use Real-DIBs for this. That way we
* can extract out a palette from the bitmap. We couldn't do this if the
* bitmap was created "compatible".
*
* History:
* 29-Sep-1995 ChrisWil Created.
\***************************************************************************/
BOOL xxxLoadDesktopWallpaper(
LPWSTR lpszFile)
{
UINT LR_flags;
int dxDesired;
int dyDesired;
UNICODE_STRING strName;
/*
* If the bitmap is somewhat large (big bpp), then we'll deal
* with it as a real-dib. We'll also do this for 8bpp since it
* can utilize a palette. Chicago uses DIBSECTIONS since it can
* count on the one-process handling the drawing. Since, NT can
* have different processes doing the drawing, we can't use sections.
*/
LR_flags = LR_LOADFROMFILE;
if (gpDispInfo->fAnyPalette || gpsi->BitCount >= 8) {
LR_flags |= LR_CREATEREALDIB;
}
/*
* If we are going to be stretching the bitmap, go ahead and pre-stretch
* the bitmap to the size of the primary monitor. This makes blitting
* to the primary monitor quicker (because it doesn't have to stretch),
* while other monitors will be a little slower.
*/
if (gwWPStyle & DTF_STRETCH) {
PMONITOR pMonitor = GetPrimaryMonitor();
dxDesired = pMonitor->rcMonitor.right - pMonitor->rcMonitor.left;
dyDesired = pMonitor->rcMonitor.bottom - pMonitor->rcMonitor.top;
} else {
dxDesired = dyDesired = 0;
}
/*
* Make a callback to the client to perform the loading.
* Saves us some code.
*/
RtlInitUnicodeString(&strName, lpszFile);
ghbmWallpaper = xxxClientLoadImage(
&strName,
0,
IMAGE_BITMAP,
dxDesired,
dyDesired,
LR_flags,
TRUE);
if (ghbmWallpaper == NULL)
return FALSE;
/*
* If it's a palette-display, then we will derive the global
* wallpaper palette from the bitmap.
*/
if (gpDispInfo->fAnyPalette) {
ghpalWallpaper = CreatePaletteFromBitmap(ghbmWallpaper);
}
/*
* Always try to convert the bitmap to a DDB. On single monitor
* systems this will improve performance. On multiple-monitor
* systems, GDI will refuse to create the DDB and just leave it
* as a DIB at the color format of the primary monitor.
*/
ghbmWallpaper = ConvertToDDB(gpDispInfo->hdcScreen, ghbmWallpaper, ghpalWallpaper);
/*
* Mark the bitmap as public, so any process can party with it.
*/
GreSetBitmapOwner(ghbmWallpaper, OBJECT_OWNER_PUBLIC);
/*
* Expand bitmap if we are going to tile it. This creates a larger
* bitmap that contains an even multiple of the source bitmap. This
* larger bitmap can then be tiled more quickly than the smaller bitmap.
*/
if (gwWPStyle & DTF_TILE) {
ghbmWallpaper = xxxExpandBitmap(ghbmWallpaper);
}
return TRUE;
}
/***************************************************************************\
* xxxSetDeskWallpaper
*
* Sets the desktop-wallpaper. This deletes the old handles in the process.
*
* History:
* 29-Jul-1991 MikeKe From win31.
* 01-Oct-1995 ChrisWil Rewrote for LoadImage().
\***************************************************************************/
BOOL xxxSetDeskWallpaper(PUNICODE_STRING pProfileUserName,
LPWSTR lpszFile)
{
BITMAP bm;
UINT WallpaperStyle2;
PWND pwndShell;
TL tl;
PTHREADINFO ptiCurrent = PtiCurrent();
PDESKTOP pdesk;
BOOL fRet = FALSE;
HBITMAP hbmOld;
PROFINTINFO apsi[] = {
{PMAP_DESKTOP, (LPWSTR)STR_TILEWALL , 0, &gwWPStyle },
{PMAP_DESKTOP, (LPWSTR)STR_DTSTYLE , 0, &WallpaperStyle2 },
{PMAP_DESKTOP, (LPWSTR)STR_DTORIGINX, 0, &gsrcWallpaper.x },
{PMAP_DESKTOP, (LPWSTR)STR_DTORIGINY, 0, &gsrcWallpaper.y },
{0, NULL, 0, NULL }
};
pdesk = ptiCurrent->rpdesk;
hbmOld = ghbmWallpaper;
if ((lpszFile == SETWALLPAPER_METRICS) && !(gwWPStyle & DTF_STRETCH)) {
gsrcWallpaper.x = 0;
gsrcWallpaper.y = 0;
if (ghbmWallpaper)
goto CreateNewWallpaper;
goto Metric_Change;
}
CreateNewWallpaper:
/*
* Delete the old wallpaper and palette if the exist.
*/
if (ghpalWallpaper) {
GreDeleteObject(ghpalWallpaper);
ghpalWallpaper = NULL;
}
if (ghbmWallpaper) {
GreDeleteObject(ghbmWallpaper);
ghbmWallpaper = NULL;
}
/*
* Kill any SPBs no matter what. This works if we're switching from/to
* palettized wallpaper. Fixes a lot of problems because palette doesn't
* change, shell paints funny on desktop, etc.
*/
BEGINATOMICCHECK();
FreeAllSpbs();
ENDATOMICCHECK();
/*
* If this is a metric-change (and stretched), then we need to
* reload it. However, since we are called from the winlogon process
* during a desktop-switch, we would be mapped to the wrong Luid
* when we attempt to grab the name from GetDeskWallpaperName. This
* would use the Luid from the DEFAULT user rather than the current
* logged on user. In order to avoid this, we cache the wallpaer
* name so that on METRIC-CHANGES we use the current-user's wallpaper.
*
* NOTE: we assume that prior to any METRIC change, we have already
* setup the ghbmWallpaper and lpszCached. This is usually done
* either on logon or during user desktop-changes through conrol-Panel.
*/
if (lpszFile == SETWALLPAPER_METRICS) {
UserAssert(gpszWall != NULL);
goto LoadWallpaper;
}
/*
* Free the cached handle.
*/
if (gpszWall) {
UserFreePool(gpszWall);
gpszWall = NULL;
}
/*
* Load the wallpaper-name. If this returns FALSE, then
* the user specified (None). We will return true to force
* the repainting of the desktop.
*/
gpszWall = GetDeskWallpaperName(pProfileUserName,lpszFile);
if (!gpszWall) {
fRet = TRUE;
goto SDW_Exit;
}
/*
* Retrieve the default settings from the registry.
*
* If tile is indicated, then normalize style to not include
* FIT/STRETCH which are center-only styles. Likewise, if
* we are centered, then normalize out the TILE bit.
*/
FastGetProfileIntsW(pProfileUserName, apsi, 0);
gwWPStyle &= DTF_TILE;
if (!(gwWPStyle & DTF_TILE)) {
gwWPStyle = WallpaperStyle2 & DTF_STRETCH;
}
/*
* Load the wallpaper. This makes a callback to the client to
* perform the bitmap-creation.
*/
LoadWallpaper:
if (xxxLoadDesktopWallpaper(gpszWall) == FALSE) {
gwWPStyle = 0;
goto SDW_Exit;
}
/*
* If we have a palette, then we need to do the correct realization and
* notification.
*/
if (ghpalWallpaper != NULL) {
PWND pwndSend;
/*
* Get the shell window. This could be NULL on system
* initialization. We will use this to do palette realization.
*/
pwndShell = _GetShellWindow(pdesk);
if (pwndShell) {
pwndSend = pwndShell;
} else {
pwndSend = (pdesk ? pdesk->pDeskInfo->spwnd : NULL);
}
/*
* Update the desktop with the new bitmap. This cleans
* out the system-palette so colors can be realized.
*/
GreRealizeDefaultPalette(gpDispInfo->hdcScreen, TRUE);
/*
* Don't broadcast if system initialization is occuring. Otherwise
* this gives the shell first crack at realizing its colors
* correctly.
*/
if (pwndSend) {
HWND hwnd = HW(pwndSend);
ThreadLockAlways(pwndSend, &tl);
xxxSendNotifyMessage(pwndSend, WM_PALETTECHANGED, (WPARAM)hwnd, 0);
ThreadUnlock(&tl);
}
}
Metric_Change:
if (fRet = GreExtGetObjectW(ghbmWallpaper, sizeof(bm), (PBITMAP)&bm)) {
gsrcWallpaper.cx = bm.bmWidth;
gsrcWallpaper.cy = bm.bmHeight;
}
SDW_Exit:
/*
* Notify the shell-window that the wallpaper changed. We need to refresh
* our local pwndShell here because we might have called-back above.
*/
pwndShell = _GetShellWindow(pdesk);
if ((pwndShell != NULL) &&
((hbmOld && !ghbmWallpaper) || (!hbmOld && ghbmWallpaper))) {
ThreadLockAlways(pwndShell, &tl);
xxxSendNotifyMessage(pwndShell,
WM_SHELLNOTIFY,
SHELLNOTIFY_WALLPAPERCHANGED,
(LPARAM)ghbmWallpaper);
ThreadUnlock(&tl);
}
return fRet;
}
/***************************************************************************\
* DesktopBuildPaint
*
* Draw the build information onto the desktop
*
* History:
* 2/4/99 joejo - Bug 280256
\***************************************************************************/
void DesktopBuildPaint(
HDC hdc,
PMONITOR pMonitor)
{
int imode;
COLORREF oldColor;
RECT rcText = {0,0,0,0};
RECT rcBuildInfo = {0,0,0,0};
HFONT oldFont = GreGetHFONT(hdc);
SIZE sizeText;
SIZE sizeProductName;
SIZE sizeProductBuild;
SIZE sizeSystemRoot;
BOOL fDrawSolidBackground = FALSE;
int cBorder = 5;
int cMargin = fDrawSolidBackground ? 5 : 0;
/*
* Set up DC
*/
imode = GreSetBkMode(hdc, TRANSPARENT);
if (fDrawSolidBackground) {
/*
* Since we are going to draw our own background, we can always set
* the pen color to black.
*/
oldColor = GreSetTextColor( hdc, RGB(0,0,0) );
} else {
/*
* Since we are not going to draw our own background, we have to work
* with whatever is already there. This is an ugly hack to try and
* cover the case where our white text won't show up on a white
* background. Of course, this doesn't catch the bitmap case. Or
* the almost white case.
*/
if (GreGetBrushColor(SYSHBR(BACKGROUND)) != 0x00ffffff) {
oldColor = GreSetTextColor( hdc, RGB(255,255,255) );
} else {
oldColor = GreSetTextColor( hdc, RGB(0,0,0) );
}
}
/*
* Get the width in pixels of the longest string we are going to print out.
*/
if (gpsi && gpsi->hCaptionFont) {
GreSelectFont(hdc, gpsi->hCaptionFont);
}
GreGetTextExtentW(
hdc,
wszProductName,
wcslen(wszProductName),
&sizeProductName,
GGTE_WIN3_EXTENT);
if (ghMenuFont != NULL ) {
GreSelectFont(hdc, ghMenuFont);
}
GreGetTextExtentW(
hdc,
wszProductBuild,
wcslen(wszProductBuild),
&sizeProductBuild,
GGTE_WIN3_EXTENT);
if (gDrawVersionAlways) {
GreGetTextExtentW(
hdc,
USER_SHARED_DATA->NtSystemRoot,
wcslen(USER_SHARED_DATA->NtSystemRoot),
&sizeSystemRoot,
GGTE_WIN3_EXTENT);
} else {
sizeSystemRoot.cx = 0;
sizeSystemRoot.cy = 0;
}
sizeText.cx = sizeProductName.cx >= sizeProductBuild.cx ? sizeProductName.cx : sizeProductBuild.cx;
sizeText.cy = sizeProductName.cy + sizeProductBuild.cy;
if (gDrawVersionAlways) {
sizeText.cx = (sizeText.cx >= sizeSystemRoot.cx) ? sizeText.cx : sizeSystemRoot.cx;
sizeText.cy += sizeSystemRoot.cy;
}
/*
* Calculate the position for all of the build info on the desktop.
* We will draw either 2 or 3 lines of text.
*/
rcBuildInfo.left = pMonitor->rcWork.right - cBorder - cMargin - sizeText.cx - cMargin;
rcBuildInfo.top = pMonitor->rcWork.bottom - cBorder - cMargin - sizeText.cy - cMargin;
rcBuildInfo.right = pMonitor->rcWork.right - cBorder;
rcBuildInfo.bottom = pMonitor->rcWork.bottom - cBorder;
/*
* Draw the background if we want it.
*
*/
if (fDrawSolidBackground) {
NtGdiRoundRect(hdc, rcBuildInfo.left, rcBuildInfo.top, rcBuildInfo.right, rcBuildInfo.bottom, 10, 10);
}
/*
* Print Windows 2000 name
*/
if (gpsi && gpsi->hCaptionFont) {
GreSelectFont(hdc, gpsi->hCaptionFont);
}
rcText.left = rcBuildInfo.left + cMargin;
rcText.top = rcBuildInfo.top + cMargin;
rcText.right = rcText.left + sizeText.cx;
rcText.bottom = rcText.top + sizeProductName.cy;
GreSetTextAlign(hdc, TA_RIGHT | TA_BOTTOM);
GreExtTextOutW(
hdc,
rcText.right,
rcText.bottom,
0,
&rcText,
wszProductName,
wcslen(wszProductName),
(LPINT)NULL
);
/*
* Print Build Number
*/
if (ghMenuFont != NULL ) {
GreSelectFont(hdc, ghMenuFont);
}
rcText.top = rcText.bottom + 1;
rcText.bottom = rcText.top + sizeProductBuild.cy;
GreExtTextOutW(
hdc,
rcText.right,
rcText.bottom,
0,
&rcText,
wszProductBuild,
wcslen(wszProductBuild),
(LPINT)NULL
);
/*
* If we are in CHK mode, draw the System Dir Path
*/
if (gDrawVersionAlways) {
rcText.top = rcText.bottom + 1;
rcText.bottom = rcText.top + sizeSystemRoot.cy;
GreExtTextOutW(
hdc,
rcText.right,
rcText.bottom,
0,
&rcText,
USER_SHARED_DATA->NtSystemRoot,
wcslen(USER_SHARED_DATA->NtSystemRoot),
(LPINT)NULL
);
}
if (oldFont) {
GreSelectFont(hdc, oldFont);
}
GreSetBkMode(hdc, imode);
GreSetTextColor(hdc, oldColor);
}
/***************************************************************************\
* xxxDesktopPaintCallback
*
* Draw the wallpaper or fill with the background brush. In debug,
* also draw the build number on the top of each monitor.
*
* History:
* 20-Sep-1996 adams Created.
\***************************************************************************/
BOOL
xxxDesktopPaintCallback(
PMONITOR pMonitor,
HDC hdc,
LPRECT lprcMonitorClip,
LPARAM dwData)
{
BOOL f;
PWND pwnd;
CheckLock(pMonitor);
pwnd = (PWND)dwData;
if (SYSMET(CLEANBOOT)) {
FillRect(hdc, lprcMonitorClip, ghbrBlack );
f = TRUE;
} else {
/*
* if this is the disconnected desktop, skip the bitmap paint
*/
if (gbDesktopLocked) {
f = FALSE;
} else {
/*
* Paint the desktop with a color or the wallpaper.
*/
if (ghbmWallpaper) {
f = xxxDrawWallpaper(
pwnd,
hdc,
pMonitor,
lprcMonitorClip);
} else {
FillRect(hdc, lprcMonitorClip, SYSHBR(DESKTOP));
f = TRUE;
}
}
}
if (SYSMET(CLEANBOOT)
|| gDrawVersionAlways
|| gdwCanPaintDesktop) {
static BOOL fInit = TRUE;
SIZE size;
int imode;
COLORREF oldColor;
HFONT oldFont = NULL;
/*
* Grab the stuff from the registry
*/
if (fInit) {
if (SYSMET(CLEANBOOT)) {
ServerLoadString( hModuleWin, STR_SAFEMODE, SafeModeStr, ARRAY_SIZE(SafeModeStr) );
SafeModeStrLen = wcslen(SafeModeStr);
}
GetVersionInfo(SYSMET(CLEANBOOT) == 0);
fInit = FALSE;
}
if (SYSMET(CLEANBOOT)) {
if (gpsi != NULL && gpsi->hCaptionFont != NULL) {
oldFont = GreSelectFont(hdc, gpsi->hCaptionFont);
}
GreGetTextExtentW(hdc, wszSafeMode, wcslen(wszSafeMode), &size, GGTE_WIN3_EXTENT);
imode = GreSetBkMode(hdc, TRANSPARENT);
oldColor = GreSetTextColor( hdc, RGB(255,255,255) );
GreExtTextOutW(
hdc,
(pMonitor->rcWork.left + pMonitor->rcWork.right - size.cx) / 2,
pMonitor->rcWork.top,
0,
(LPRECT)NULL,
wszSafeMode,
wcslen(wszSafeMode),
(LPINT)NULL
);
GreGetTextExtentW(hdc, SafeModeStr, SafeModeStrLen, &size, GGTE_WIN3_EXTENT);
GreExtTextOutW(
hdc,
pMonitor->rcWork.left,
pMonitor->rcWork.top,
0,
(LPRECT)NULL,
SafeModeStr,
SafeModeStrLen,
(LPINT)NULL
);
GreExtTextOutW(
hdc,
pMonitor->rcWork.right - size.cx,
pMonitor->rcWork.top,
0,
(LPRECT)NULL,
SafeModeStr,
SafeModeStrLen,
(LPINT)NULL
);
GreExtTextOutW(
hdc,
pMonitor->rcWork.right - size.cx,
pMonitor->rcWork.bottom - gpsi->tmSysFont.tmHeight,
0,
(LPRECT)NULL,
SafeModeStr,
SafeModeStrLen,
(LPINT)NULL
);
GreExtTextOutW(
hdc,
pMonitor->rcWork.left,
pMonitor->rcWork.bottom - gpsi->tmSysFont.tmHeight,
0,
(LPRECT)NULL,
SafeModeStr,
SafeModeStrLen,
(LPINT)NULL
);
GreSetBkMode(hdc, imode);
GreSetTextColor(hdc, oldColor);
if (oldFont) {
GreSelectFont(hdc, oldFont);
}
} else {
if (!gbRemoteSession || !gdwTSExcludeDesktopVersion) {
DesktopBuildPaint(hdc, pMonitor);
}
}
}
return f;
}
/***************************************************************************\
* xxxInvalidateDesktopOnPaletteChange
*
* Invalidates the shell window and uncovered areas of the desktop
* when the palette changes.
*
* History:
* 28-Apr-1997 adams Created.
\***************************************************************************/
VOID
xxxInvalidateDesktopOnPaletteChange(
PWND pwnd)
{
PDESKTOP pdesk;
PWND pwndShell;
TL tlpwndShell;
RECT rc;
BOOL fRedrawDesktop;
CheckLock(pwnd);
/*
* Invalidate the shell window.
*/
pdesk = PtiCurrent()->rpdesk;
pwndShell = _GetShellWindow(pdesk);
if (!pwndShell) {
fRedrawDesktop = TRUE;
rc = gpsi->rcScreen;
} else {
ThreadLockAlways(pwndShell, &tlpwndShell);
xxxRedrawWindow(
pwndShell,
NULL,
NULL,
RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN);
/*
* The shell window may not cover all of the desktop.
* Invalidate the part of the desktop wallpaper it
* doesn't sit over.
*/
fRedrawDesktop = SubtractRect(&rc, &pwnd->rcWindow, &pwndShell->rcWindow);
ThreadUnlock(&tlpwndShell);
}
/*
* Invalidate the desktop window.
*/
if (fRedrawDesktop) {
xxxRedrawWindow(
pwnd,
&rc,
NULL,
RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN);
}
}
/***************************************************************************\
* xxxInternalPaintDesktop
*
* If fPaint is TRUE, enumerate the monitors to paint the desktop.
* Otherwise, it selects the bitmap palette into the DC to select
* its colors into the hardware palette.
*
* History:
* 29-Jul-1991 MikeKe From win31
\***************************************************************************/
BOOL xxxInternalPaintDesktop(
PWND pwnd,
HDC hdc,
BOOL fPaint)
{
BOOL fRet = FALSE;
CheckLock(pwnd);
if (fPaint) {
RECT rcOrg, rcT;
POINT pt;
/*
* For compatiblity purposes the DC origin of desktop windows
* is set to the primary monitor, i.e. (0,0). Since we may get
* either desktop or non-desktop DCs here, temporarily reset
* the hdc origin to (0,0).
*/
GreGetDCOrgEx(hdc, &pt, &rcOrg);
CopyRect(&rcT, &rcOrg);
OffsetRect(&rcT, -rcT.left, -rcT.top);
GreSetDCOrg(hdc, rcT.left, rcT.top, (PRECTL)&rcT);
fRet = xxxEnumDisplayMonitors(
hdc,
NULL,
(MONITORENUMPROC) xxxDesktopPaintCallback,
(LPARAM)pwnd,
TRUE);
/*
* Reset the DC origin back.
*/
GreSetDCOrg(hdc, rcOrg.left, rcOrg.top, (PRECTL)&rcOrg);
} else if (ghpalWallpaper &&
GetPrimaryMonitor()->dwMONFlags & MONF_PALETTEDISPLAY) {
/*
* Select in the palette if one exists.
*/
HPALETTE hpalT;
int i;
hpalT = _SelectPalette(hdc, ghpalWallpaper, FALSE);
i = xxxRealizePalette(hdc);
_SelectPalette(hdc, hpalT, FALSE);
if (i > 0) {
xxxInvalidateDesktopOnPaletteChange(pwnd);
}
fRet = TRUE;
}
return fRet;
}