Index: dll/cpl/desk/background.c =================================================================== --- dll/cpl/desk/background.c (revision 74896) +++ dll/cpl/desk/background.c (working copy) @@ -18,6 +18,8 @@ #define PLACEMENT_CENTER 0 #define PLACEMENT_STRETCH 1 #define PLACEMENT_TILE 2 +#define PLACEMENT_FIT 3 +#define PLACEMENT_FILL 4 /* The values in these macros are dependent on the * layout of the monitor image and they must be adjusted @@ -440,7 +442,7 @@ { TCHAR szString[256]; HKEY regKey; - TCHAR szBuffer[2]; + TCHAR szBuffer[3]; DWORD bufferSize = sizeof(szBuffer); BITMAP bitmap; @@ -455,6 +457,12 @@ 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; @@ -486,6 +494,18 @@ SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_SETCURSEL, PLACEMENT_STRETCH, 0); pData->placementSelection = PLACEMENT_STRETCH; } + + if (_ttoi(szBuffer) == 6) + { + SendDlgItemMessage(hwndDlg, IDC_PLACEMENT_COMBO, CB_SETCURSEL, PLACEMENT_FIT, 0); + pData->placementSelection = PLACEMENT_FIT; + } + + if (_ttoi(szBuffer) == 10) + { + 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) @@ -758,6 +778,9 @@ int scaledHeight; int posX, desX; int posY, desY; + float fitFillScale; + float fitFillScaleX, fitFillScaleY; + float fitFillWidth, fitFillHeight; HBRUSH hBrush; int x; int y; @@ -875,6 +898,58 @@ } break; + + case PLACEMENT_FIT: + fitFillScaleX = (float)MONITOR_WIDTH / scaledWidth; + fitFillScaleY = (float)MONITOR_HEIGHT / scaledHeight; + fitFillScale = min(fitFillScaleX, fitFillScaleY); + + fitFillWidth = fitFillScale * scaledWidth; + fitFillHeight = fitFillScale * scaledHeight; + + 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: + fitFillScaleX = (float)MONITOR_WIDTH / scaledWidth; + fitFillScaleY = (float)MONITOR_HEIGHT / scaledHeight; + fitFillScale = max(fitFillScaleX, fitFillScaleY); + + fitFillWidth = fitFillScale * scaledWidth; + fitFillHeight = fitFillScale * scaledHeight; + + 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; } } @@ -937,6 +1012,18 @@ 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 == TRUE) { GdipLoadImageFromFile(pData->backgroundItems[pData->backgroundSelection].szFilename, &image); Index: dll/cpl/desk/lang/en-US.rc =================================================================== --- dll/cpl/desk/lang/en-US.rc (revision 74896) +++ dll/cpl/desk/lang/en-US.rc (working copy) @@ -196,6 +196,8 @@ IDS_CENTER "Center" IDS_STRETCH "Stretch" IDS_TILE "Tile" + IDS_FIT "Fit" + IDS_FILL "Fill" END STRINGTABLE Index: dll/cpl/desk/resource.h =================================================================== --- dll/cpl/desk/resource.h (revision 74896) +++ dll/cpl/desk/resource.h (working copy) @@ -47,6 +47,8 @@ #define IDS_CENTER 2003 #define IDS_STRETCH 2004 #define IDS_TILE 2005 +#define IDS_FIT 2006 +#define IDS_FILL 2007 #define IDC_SETTINGS_DEVICE 201 #define IDC_SETTINGS_BPP 202 Index: win32ss/user/ntuser/desktop.c =================================================================== --- win32ss/user/ntuser/desktop.c (revision 74896) +++ win32ss/user/ntuser/desktop.c (working copy) @@ -1215,17 +1215,71 @@ { 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, scaleDem; + + // if ((sz.cx / gspv.cxWallpaper) > (sz.cy / gspv.cyWallpaper)) + if ((sz.cx * gspv.cyWallpaper) > (sz.cy * gspv.cxWallpaper)) + { + if (gspv.WallpaperMode == wmFit) + { + scaleNum = sz.cy; + scaleDem = gspv.cyWallpaper; + } + else + { + scaleNum = sz.cx; + scaleDem = gspv.cxWallpaper; + } + } + else + { + if (gspv.WallpaperMode == wmFit) + { + scaleNum = sz.cx; + scaleDem = gspv.cxWallpaper; + } + else + { + scaleNum = sz.cy; + scaleDem = gspv.cyWallpaper; + } + } + + scaledWidth = MulDiv(gspv.cxWallpaper, scaleNum, scaleDem); + scaledHeight = MulDiv(gspv.cyWallpaper, scaleNum, scaleDem); + + 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 */ @@ -1291,6 +1345,38 @@ } } } + 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, Index: win32ss/user/ntuser/sysparams.c =================================================================== --- win32ss/user/ntuser/sysparams.c (revision 74896) +++ win32ss/user/ntuser/sysparams.c (working copy) @@ -694,9 +694,14 @@ { 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 @@ -914,7 +919,7 @@ /* Fixup user's structure size */ metrics->cbSize = sizeof(NONCLIENTMETRICSW); - + if (!SpiSet(&gspv.ncm, metrics, sizeof(NONCLIENTMETRICSW), fl)) return 0; Index: win32ss/user/ntuser/sysparams.h =================================================================== --- win32ss/user/ntuser/sysparams.h (revision 74896) +++ win32ss/user/ntuser/sysparams.h (working copy) @@ -40,7 +40,9 @@ { wmCenter = 0, wmTile, - wmStretch + wmStretch, + wmFit, + wmFill } WALLPAPER_MODE; typedef struct _SPIVALUES