[WIN32K][DESK.CPL]: Add fit and fill background placement options (#28)

- WIN32K and DESK.CPL: Add fit and fill background placement options.
- DESK.CPL: Define wallpaper placement constants; update translations.
- WIN32K: Fix coding style.
CORE-13360
This commit is contained in:
Waritnan Sookbuntherng 2017-10-14 02:44:02 +07:00 committed by Hermès BÉLUSCA - MAÏTO
parent 30bfd8afad
commit 1128447196
31 changed files with 297 additions and 16 deletions

View file

@ -15,9 +15,27 @@
#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
@ -440,7 +458,7 @@ InitBackgroundDialog(HWND hwndDlg, PDATA pData)
{
TCHAR szString[256];
HKEY regKey;
TCHAR szBuffer[2];
TCHAR szBuffer[3];
DWORD bufferSize = sizeof(szBuffer);
BITMAP bitmap;
@ -455,6 +473,12 @@ InitBackgroundDialog(HWND hwndDlg, PDATA pData)
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;
@ -475,17 +499,29 @@ InitBackgroundDialog(HWND hwndDlg, PDATA pData)
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)
@ -758,6 +794,8 @@ DrawBackgroundPreview(LPDRAWITEMSTRUCT draw, PDATA pData)
int scaledHeight;
int posX, desX;
int posY, desY;
int fitFillScaleNum, fitFillScaleDen;
int fitFillWidth, fitFillHeight;
HBRUSH hBrush;
int x;
int y;
@ -875,6 +913,72 @@ DrawBackgroundPreview(LPDRAWITEMSTRUCT draw, PDATA pData)
}
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;
}
}
@ -937,6 +1041,18 @@ SetWallpaper(PDATA pData)
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);

View file

@ -207,6 +207,8 @@ BEGIN
IDS_CENTER "В средата"
IDS_STRETCH "Разтегнато"
IDS_TILE "Настелено"
IDS_FIT "Fit"
IDS_FILL "Fill"
END
STRINGTABLE

View file

@ -213,6 +213,8 @@ BEGIN
IDS_CENTER "Na střed"
IDS_STRETCH "Roztáhnout"
IDS_TILE "Dlaždice"
IDS_FIT "Fit"
IDS_FILL "Fill"
END
STRINGTABLE

View file

@ -207,6 +207,8 @@ BEGIN
IDS_CENTER "Zentriert"
IDS_STRETCH "Gestreckt"
IDS_TILE "Nebeneinander"
IDS_FIT "Fit"
IDS_FILL "Fill"
END
STRINGTABLE

View file

@ -207,6 +207,8 @@ BEGIN
IDS_CENTER "Κέντρο"
IDS_STRETCH "Παραμόρφωση"
IDS_TILE "Σε παράθεση"
IDS_FIT "Fit"
IDS_FILL "Fill"
END
STRINGTABLE

View file

@ -207,6 +207,8 @@ BEGIN
IDS_CENTER "Center"
IDS_STRETCH "Stretch"
IDS_TILE "Tile"
IDS_FIT "Fit"
IDS_FILL "Fill"
END
STRINGTABLE

View file

@ -207,6 +207,8 @@ BEGIN
IDS_CENTER "Center"
IDS_STRETCH "Stretch"
IDS_TILE "Tile"
IDS_FIT "Fit"
IDS_FILL "Fill"
END
STRINGTABLE

View file

@ -209,6 +209,8 @@ BEGIN
IDS_CENTER "Centrada"
IDS_STRETCH "Expandida"
IDS_TILE "En mosaico"
IDS_FIT "Fit"
IDS_FILL "Fill"
END
STRINGTABLE

View file

@ -206,9 +206,11 @@ BEGIN
IDS_CPLNAME "Affichage"
IDS_CPLDESCRIPTION "Personalise l'affichage du bureau et de l'écran de veille."
IDS_NONE "(Aucun)"
IDS_CENTER "Centre"
IDS_CENTER "Centrer"
IDS_STRETCH "Étirer"
IDS_TILE "Mosaïque"
IDS_FIT "Ajuster"
IDS_FILL "Remplir"
END
STRINGTABLE

View file

@ -207,6 +207,8 @@ BEGIN
IDS_CENTER "מרכז"
IDS_STRETCH "מתח"
IDS_TILE "פרוש"
IDS_FIT "Fit"
IDS_FILL "Fill"
END
STRINGTABLE

View file

@ -209,6 +209,8 @@ BEGIN
IDS_CENTER "Középen"
IDS_STRETCH "Széthúzva"
IDS_TILE "Mozaikszerűen"
IDS_FIT "Fit"
IDS_FILL "Fill"
END
STRINGTABLE

View file

@ -207,6 +207,8 @@ BEGIN
IDS_CENTER "Tengah"
IDS_STRETCH "Tarik"
IDS_TILE "Tile"
IDS_FIT "Fit"
IDS_FILL "Fill"
END
STRINGTABLE

View file

@ -207,6 +207,8 @@ BEGIN
IDS_CENTER "Al centro"
IDS_STRETCH "Estesa"
IDS_TILE "Affiancata"
IDS_FIT "Fit"
IDS_FILL "Fill"
END
STRINGTABLE

View file

@ -207,6 +207,8 @@ BEGIN
IDS_CENTER "中央に表示"
IDS_STRETCH "拡大して表示"
IDS_TILE "並べて表示"
IDS_FIT "Fit"
IDS_FILL "Fill"
END
STRINGTABLE

View file

@ -207,6 +207,8 @@ BEGIN
IDS_CENTER "Center"
IDS_STRETCH "Stretch"
IDS_TILE "Tile"
IDS_FIT "Fit"
IDS_FILL "Fill"
END
STRINGTABLE

View file

@ -207,6 +207,8 @@ BEGIN
IDS_CENTER "Midtstill"
IDS_STRETCH "Side ved side"
IDS_TILE "Stukket"
IDS_FIT "Fit"
IDS_FILL "Fill"
END
STRINGTABLE

View file

@ -216,6 +216,8 @@ BEGIN
IDS_CENTER "Do środka"
IDS_STRETCH "Rozciągnięcie"
IDS_TILE "Sąsiadująco"
IDS_FIT "Fit"
IDS_FILL "Fill"
END
STRINGTABLE

View file

@ -207,6 +207,8 @@ BEGIN
IDS_CENTER "Centralizar"
IDS_STRETCH "Estender"
IDS_TILE "Lado a lado"
IDS_FIT "Fit"
IDS_FILL "Fill"
END
STRINGTABLE

View file

@ -212,6 +212,8 @@ BEGIN
IDS_CENTER "Centrat"
IDS_STRETCH "Extins"
IDS_TILE "Tapițat"
IDS_FIT "Fit"
IDS_FILL "Fill"
END
STRINGTABLE

View file

@ -207,6 +207,8 @@ BEGIN
IDS_CENTER "по центру"
IDS_STRETCH "растянуть"
IDS_TILE "замостить"
IDS_FIT "вписать"
IDS_FILL "заполнить"
END
STRINGTABLE

View file

@ -209,6 +209,8 @@ BEGIN
IDS_CENTER "V strede"
IDS_STRETCH "Roztiahnuť"
IDS_TILE "Dlaždice"
IDS_FIT "Fit"
IDS_FILL "Fill"
END
STRINGTABLE

View file

@ -211,6 +211,8 @@ BEGIN
IDS_CENTER "Qender"
IDS_STRETCH "Streq"
IDS_TILE "Tile"
IDS_FIT "Fit"
IDS_FILL "Fill"
END
STRINGTABLE

View file

@ -209,6 +209,8 @@ BEGIN
IDS_CENTER "Centrera"
IDS_STRETCH "Sträck ut"
IDS_TILE "Stapla"
IDS_FIT "Fit"
IDS_FILL "Fill"
END
STRINGTABLE

View file

@ -209,6 +209,8 @@ BEGIN
IDS_CENTER "Ortala"
IDS_STRETCH "Uzat"
IDS_TILE "Döşe"
IDS_FIT "Fit"
IDS_FILL "Fill"
END
STRINGTABLE

View file

@ -215,6 +215,8 @@ BEGIN
IDS_CENTER "По центру"
IDS_STRETCH "Розтягнути"
IDS_TILE "Плиткою"
IDS_FIT "Fit"
IDS_FILL "Fill"
END
STRINGTABLE

View file

@ -214,6 +214,8 @@ BEGIN
IDS_CENTER "居中"
IDS_STRETCH "拉伸"
IDS_TILE "平铺"
IDS_FIT "Fit"
IDS_FILL "Fill"
END
STRINGTABLE

View file

@ -209,6 +209,8 @@ BEGIN
IDS_CENTER "居中"
IDS_STRETCH "拉伸"
IDS_TILE "平鋪"
IDS_FIT "Fit"
IDS_FILL "Fill"
END
STRINGTABLE

View file

@ -48,6 +48,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

View file

@ -1216,17 +1216,71 @@ IntPaintDesktop(HDC hDC)
{
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 */
@ -1292,6 +1346,42 @@ IntPaintDesktop(HDC hDC)
}
}
}
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,

View file

@ -625,13 +625,21 @@ SpiSetWallpaper(PVOID pvParam, FLONG fl)
/* Capture UNICODE_STRING */
bResult = SpiMemCopy(&ustr, pvParam, sizeof(ustr), fl & SPIF_PROTECT);
if (!bResult) return 0;
if (ustr.Length > MAX_PATH * sizeof(WCHAR))
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;
@ -669,7 +677,7 @@ SpiSetWallpaper(PVOID pvParam, FLONG fl)
}
/* Try to get the size of the wallpaper */
if(!(psurfBmp = SURFACE_ShareLockSurface(hbmp)))
if (!(psurfBmp = SURFACE_ShareLockSurface(hbmp)))
{
GreDeleteObject(hbmp);
return 0;
@ -690,13 +698,24 @@ SpiSetWallpaper(PVOID pvParam, FLONG fl)
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

View file

@ -40,7 +40,9 @@ typedef enum
{
wmCenter = 0,
wmTile,
wmStretch
wmStretch,
wmFit,
wmFill
} WALLPAPER_MODE;
typedef struct _SPIVALUES