#define MAX_BACKGROUNDS 100
-#define PLACEMENT_CENTER 0
-#define PLACEMENT_STRETCH 1
-#define PLACEMENT_TILE 2
+typedef enum
+{
+ PLACEMENT_CENTER = 0,
+ PLACEMENT_STRETCH,
+ PLACEMENT_TILE,
+ PLACEMENT_FIT,
+ PLACEMENT_FILL
+} PLACEMENT;
+
+/* The tile placement is stored in different registry
+ * key, but due to a condition in win32k it needs to be
+ * zero when stored in the same key as others.
+ */
+typedef enum
+{
+ PLACEMENT_VALUE_CENTER = 0,
+ PLACEMENT_VALUE_STRETCH = 2,
+ PLACEMENT_VALUE_TILE = 0,
+ PLACEMENT_VALUE_FIT = 6,
+ PLACEMENT_VALUE_FILL = 10
+} PLACEMENT_VALUE;
/* The values in these macros are dependent on the
* layout of the monitor image and they must be adjusted
{
TCHAR szString[256];
HKEY regKey;
- TCHAR szBuffer[2];
+ TCHAR szBuffer[3];
DWORD bufferSize = sizeof(szBuffer);
BITMAP bitmap;
LoadString(hApplet, IDS_TILE, szString, sizeof(szString) / sizeof(TCHAR));
SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_INSERTSTRING, PLACEMENT_TILE, (LPARAM)szString);
+ LoadString(hApplet, IDS_FIT, szString, sizeof(szString) / sizeof(TCHAR));
+ SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_INSERTSTRING, PLACEMENT_FIT, (LPARAM)szString);
+
+ LoadString(hApplet, IDS_FILL, szString, sizeof(szString) / sizeof(TCHAR));
+ SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_INSERTSTRING, PLACEMENT_FILL, (LPARAM)szString);
+
SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_SETCURSEL, PLACEMENT_CENTER, 0);
pData->placementSelection = PLACEMENT_CENTER;
if (RegQueryValueEx(regKey, TEXT("WallpaperStyle"), 0, NULL, (LPBYTE)szBuffer, &bufferSize) == ERROR_SUCCESS)
{
- if (_ttoi(szBuffer) == 0)
+ if (_ttoi(szBuffer) == PLACEMENT_VALUE_CENTER)
{
SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_SETCURSEL, PLACEMENT_CENTER, 0);
pData->placementSelection = PLACEMENT_CENTER;
}
- if (_ttoi(szBuffer) == 2)
+ if (_ttoi(szBuffer) == PLACEMENT_VALUE_STRETCH)
{
SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_SETCURSEL, PLACEMENT_STRETCH, 0);
pData->placementSelection = PLACEMENT_STRETCH;
}
+
+ if (_ttoi(szBuffer) == PLACEMENT_VALUE_FIT)
+ {
+ SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_SETCURSEL, PLACEMENT_FIT, 0);
+ pData->placementSelection = PLACEMENT_FIT;
+ }
+
+ if (_ttoi(szBuffer) == PLACEMENT_VALUE_FILL)
+ {
+ SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_SETCURSEL, PLACEMENT_FILL, 0);
+ pData->placementSelection = PLACEMENT_FILL;
+ }
}
if (RegQueryValueEx(regKey, TEXT("TileWallpaper"), 0, NULL, (LPBYTE)szBuffer, &bufferSize) == ERROR_SUCCESS)
int scaledHeight;
int posX, desX;
int posY, desY;
+ int fitFillScaleNum, fitFillScaleDen;
+ int fitFillWidth, fitFillHeight;
HBRUSH hBrush;
int x;
int y;
}
break;
+
+ case PLACEMENT_FIT:
+ if ((MONITOR_WIDTH * scaledHeight) <= (MONITOR_HEIGHT * scaledWidth))
+ {
+ fitFillScaleNum = MONITOR_WIDTH;
+ fitFillScaleDen = scaledWidth;
+ }
+ else
+ {
+ fitFillScaleNum = MONITOR_HEIGHT;
+ fitFillScaleDen = scaledHeight;
+ }
+
+ fitFillWidth = MulDiv(scaledWidth, fitFillScaleNum, fitFillScaleDen);
+ fitFillHeight = MulDiv(scaledHeight, fitFillScaleNum, fitFillScaleDen);
+
+ posX = (MONITOR_WIDTH - fitFillWidth) / 2;
+ posY = (MONITOR_HEIGHT - fitFillHeight) / 2;
+
+ StretchDIBits(hDC,
+ MONITOR_LEFT + posX,
+ MONITOR_TOP + posY,
+ fitFillWidth,
+ fitFillHeight,
+ 0,
+ 0,
+ pData->pWallpaperBitmap->width,
+ pData->pWallpaperBitmap->height,
+ pData->pWallpaperBitmap->bits,
+ pData->pWallpaperBitmap->info,
+ DIB_RGB_COLORS,
+ SRCCOPY);
+ break;
+
+ case PLACEMENT_FILL:
+ if ((MONITOR_WIDTH * scaledHeight) > (MONITOR_HEIGHT * scaledWidth))
+ {
+ fitFillScaleNum = MONITOR_WIDTH;
+ fitFillScaleDen = scaledWidth;
+ }
+ else
+ {
+ fitFillScaleNum = MONITOR_HEIGHT;
+ fitFillScaleDen = scaledHeight;
+ }
+
+ fitFillWidth = MulDiv(scaledWidth, fitFillScaleNum, fitFillScaleDen);
+ fitFillHeight = MulDiv(scaledHeight, fitFillScaleNum, fitFillScaleDen);
+
+ desX = (((fitFillWidth - MONITOR_WIDTH) * pData->pWallpaperBitmap->width) / (2 * fitFillWidth));
+ desY = (((fitFillHeight - MONITOR_HEIGHT) * pData->pWallpaperBitmap->height) / (2 * fitFillHeight));
+
+ StretchDIBits(hDC,
+ MONITOR_LEFT,
+ MONITOR_TOP,
+ MONITOR_WIDTH,
+ MONITOR_HEIGHT,
+ desX,
+ desY,
+ (MONITOR_WIDTH * pData->pWallpaperBitmap->width) / fitFillWidth,
+ (MONITOR_HEIGHT * pData->pWallpaperBitmap->height) / fitFillHeight,
+ pData->pWallpaperBitmap->bits,
+ pData->pWallpaperBitmap->info,
+ DIB_RGB_COLORS,
+ SRCCOPY);
+ break;
}
}
RegSetValueEx(regKey, TEXT("WallpaperStyle"), 0, REG_SZ, (LPBYTE)TEXT("2"), sizeof(TCHAR) * 2);
}
+ if (pData->placementSelection == PLACEMENT_FIT)
+ {
+ RegSetValueEx(regKey, TEXT("TileWallpaper"), 0, REG_SZ, (LPBYTE)TEXT("0"), sizeof(TCHAR) * 2);
+ RegSetValueEx(regKey, TEXT("WallpaperStyle"), 0, REG_SZ, (LPBYTE)TEXT("6"), sizeof(TCHAR) * 2);
+ }
+
+ if (pData->placementSelection == PLACEMENT_FILL)
+ {
+ RegSetValueEx(regKey, TEXT("TileWallpaper"), 0, REG_SZ, (LPBYTE)TEXT("0"), sizeof(TCHAR) * 2);
+ RegSetValueEx(regKey, TEXT("WallpaperStyle"), 0, REG_SZ, (LPBYTE)TEXT("10"), sizeof(TCHAR) * 3);
+ }
+
if (pData->backgroundItems[pData->backgroundSelection].bWallpaper != FALSE)
{
GdipLoadImageFromFile(pData->backgroundItems[pData->backgroundSelection].szFilename, &image);
{
SIZE sz;
int x, y;
+ int scaledWidth, scaledHeight;
+ int wallpaperX, wallpaperY, wallpaperWidth, wallpaperHeight;
HDC hWallpaperDC;
sz.cx = WndDesktop->rcWindow.right - WndDesktop->rcWindow.left;
sz.cy = WndDesktop->rcWindow.bottom - WndDesktop->rcWindow.top;
+ if (gspv.WallpaperMode == wmFit ||
+ gspv.WallpaperMode == wmFill)
+ {
+ int scaleNum, scaleDen;
+
+ // Precision improvement over ((sz.cx / gspv.cxWallpaper) > (sz.cy / gspv.cyWallpaper))
+ if ((sz.cx * gspv.cyWallpaper) > (sz.cy * gspv.cxWallpaper))
+ {
+ if (gspv.WallpaperMode == wmFit)
+ {
+ scaleNum = sz.cy;
+ scaleDen = gspv.cyWallpaper;
+ }
+ else
+ {
+ scaleNum = sz.cx;
+ scaleDen = gspv.cxWallpaper;
+ }
+ }
+ else
+ {
+ if (gspv.WallpaperMode == wmFit)
+ {
+ scaleNum = sz.cx;
+ scaleDen = gspv.cxWallpaper;
+ }
+ else
+ {
+ scaleNum = sz.cy;
+ scaleDen = gspv.cyWallpaper;
+ }
+ }
+
+ scaledWidth = EngMulDiv(gspv.cxWallpaper, scaleNum, scaleDen);
+ scaledHeight = EngMulDiv(gspv.cyWallpaper, scaleNum, scaleDen);
+
+ if (gspv.WallpaperMode == wmFill)
+ {
+ wallpaperX = (((scaledWidth - sz.cx) * gspv.cxWallpaper) / (2 * scaledWidth));
+ wallpaperY = (((scaledHeight - sz.cy) * gspv.cyWallpaper) / (2 * scaledHeight));
+
+ wallpaperWidth = (sz.cx * gspv.cxWallpaper) / scaledWidth;
+ wallpaperHeight = (sz.cy * gspv.cyWallpaper) / scaledHeight;
+ }
+ }
+
if (gspv.WallpaperMode == wmStretch ||
- gspv.WallpaperMode == wmTile)
+ gspv.WallpaperMode == wmTile ||
+ gspv.WallpaperMode == wmFill)
{
x = 0;
y = 0;
}
+ else if (gspv.WallpaperMode == wmFit)
+ {
+ x = (sz.cx - scaledWidth) / 2;
+ y = (sz.cy - scaledHeight) / 2;
+ }
else
{
/* Find the upper left corner, can be negative if the bitmap is bigger than the screen */
}
}
}
+ else if (gspv.WallpaperMode == wmFit)
+ {
+ if (Rect.right && Rect.bottom)
+ {
+ NtGdiStretchBlt(hDC,
+ x,
+ y,
+ scaledWidth,
+ scaledHeight,
+ hWallpaperDC,
+ 0,
+ 0,
+ gspv.cxWallpaper,
+ gspv.cyWallpaper,
+ SRCCOPY,
+ 0);
+ }
+ }
+ else if (gspv.WallpaperMode == wmFill)
+ {
+ if (Rect.right && Rect.bottom)
+ {
+ NtGdiStretchBlt(hDC,
+ x,
+ y,
+ sz.cx,
+ sz.cy,
+ hWallpaperDC,
+ wallpaperX,
+ wallpaperY,
+ wallpaperWidth,
+ wallpaperHeight,
+ SRCCOPY,
+ 0);
+ }
+ }
else
{
NtGdiBitBlt(hDC,
/* Capture UNICODE_STRING */
bResult = SpiMemCopy(&ustr, pvParam, sizeof(ustr), fl & SPIF_PROTECT);
- if (!bResult) return 0;
+ if (!bResult)
+ {
+ return 0;
+ }
if (ustr.Length > MAX_PATH * sizeof(WCHAR))
+ {
return 0;
+ }
/* Copy the string buffer name */
bResult = SpiMemCopy(gspv.awcWallpaper, ustr.Buffer, ustr.Length, fl & SPIF_PROTECT);
- if (!bResult) return 0;
+ if (!bResult)
+ {
+ return 0;
+ }
/* Update the UNICODE_STRING */
gspv.ustrWallpaper.Buffer = gspv.awcWallpaper;
}
/* Try to get the size of the wallpaper */
- if(!(psurfBmp = SURFACE_ShareLockSurface(hbmp)))
+ if (!(psurfBmp = SURFACE_ShareLockSurface(hbmp)))
{
GreDeleteObject(hbmp);
return 0;
TRACE("SpiSetWallpaper: ulTile=%lu, ulStyle=%lu\n", ulTile, ulStyle);
/* Check the values we found in the registry */
- if(ulTile && !ulStyle)
+ if (ulTile && !ulStyle)
{
gspv.WallpaperMode = wmTile;
}
- else if(!ulTile && ulStyle == 2)
+ else if (!ulTile && ulStyle)
{
- gspv.WallpaperMode = wmStretch;
+ if (ulStyle == 2)
+ {
+ gspv.WallpaperMode = wmStretch;
+ }
+ else if (ulStyle == 6)
+ {
+ gspv.WallpaperMode = wmFit;
+ }
+ else if (ulStyle == 10)
+ {
+ gspv.WallpaperMode = wmFill;
+ }
}
}
else