https://git.reactos.org/?p=reactos.git;a=commitdiff;h=1128447196a424731226f8911f90e94f2fe1c266

commit 1128447196a424731226f8911f90e94f2fe1c266
Author: Waritnan Sookbuntherng <[email protected]>
AuthorDate: Sat Oct 14 02:44:02 2017 +0700

    [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
---
 dll/cpl/desk/background.c       | 128 ++++++++++++++++++++++++++++++++++++++--
 dll/cpl/desk/lang/bg-BG.rc      |   2 +
 dll/cpl/desk/lang/cs-CZ.rc      |   2 +
 dll/cpl/desk/lang/de-DE.rc      |   2 +
 dll/cpl/desk/lang/el-GR.rc      |   2 +
 dll/cpl/desk/lang/en-GB.rc      |   2 +
 dll/cpl/desk/lang/en-US.rc      |   2 +
 dll/cpl/desk/lang/es-ES.rc      |   2 +
 dll/cpl/desk/lang/fr-FR.rc      |   4 +-
 dll/cpl/desk/lang/he-IL.rc      |   2 +
 dll/cpl/desk/lang/hu-HU.rc      |   2 +
 dll/cpl/desk/lang/id-ID.rc      |   2 +
 dll/cpl/desk/lang/it-IT.rc      |   2 +
 dll/cpl/desk/lang/ja-JP.rc      |   2 +
 dll/cpl/desk/lang/nl-NL.rc      |   2 +
 dll/cpl/desk/lang/no-NO.rc      |   2 +
 dll/cpl/desk/lang/pl-PL.rc      |   2 +
 dll/cpl/desk/lang/pt-BR.rc      |   2 +
 dll/cpl/desk/lang/ro-RO.rc      |   2 +
 dll/cpl/desk/lang/ru-RU.rc      |   2 +
 dll/cpl/desk/lang/sk-SK.rc      |   2 +
 dll/cpl/desk/lang/sq-AL.rc      |   2 +
 dll/cpl/desk/lang/sv-SE.rc      |   2 +
 dll/cpl/desk/lang/tr-TR.rc      |   2 +
 dll/cpl/desk/lang/uk-UA.rc      |   2 +
 dll/cpl/desk/lang/zh-CN.rc      |   2 +
 dll/cpl/desk/lang/zh-TW.rc      |   2 +
 dll/cpl/desk/resource.h         |   2 +
 win32ss/user/ntuser/desktop.c   |  92 ++++++++++++++++++++++++++++-
 win32ss/user/ntuser/sysparams.c |  31 ++++++++--
 win32ss/user/ntuser/sysparams.h |   4 +-
 31 files changed, 296 insertions(+), 15 deletions(-)

diff --git a/dll/cpl/desk/background.c b/dll/cpl/desk/background.c
index 6d0a018b59..9853ef9dfa 100644
--- a/dll/cpl/desk/background.c
+++ b/dll/cpl/desk/background.c
@@ -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);
diff --git a/dll/cpl/desk/lang/bg-BG.rc b/dll/cpl/desk/lang/bg-BG.rc
index de85e08305..780247ecd9 100644
--- a/dll/cpl/desk/lang/bg-BG.rc
+++ b/dll/cpl/desk/lang/bg-BG.rc
@@ -207,6 +207,8 @@ BEGIN
     IDS_CENTER "В средата"
     IDS_STRETCH "Разтегнато"
     IDS_TILE "Настелено"
+    IDS_FIT "Fit"
+    IDS_FILL "Fill"
 END
 
 STRINGTABLE
diff --git a/dll/cpl/desk/lang/cs-CZ.rc b/dll/cpl/desk/lang/cs-CZ.rc
index dd7692e48b..95c5bd907c 100644
--- a/dll/cpl/desk/lang/cs-CZ.rc
+++ b/dll/cpl/desk/lang/cs-CZ.rc
@@ -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
diff --git a/dll/cpl/desk/lang/de-DE.rc b/dll/cpl/desk/lang/de-DE.rc
index c3c1111b04..c49ebeb932 100644
--- a/dll/cpl/desk/lang/de-DE.rc
+++ b/dll/cpl/desk/lang/de-DE.rc
@@ -207,6 +207,8 @@ BEGIN
     IDS_CENTER "Zentriert"
     IDS_STRETCH "Gestreckt"
     IDS_TILE "Nebeneinander"
+    IDS_FIT "Fit"
+    IDS_FILL "Fill"
 END
 
 STRINGTABLE
diff --git a/dll/cpl/desk/lang/el-GR.rc b/dll/cpl/desk/lang/el-GR.rc
index 9b18cd6ff0..304a15f168 100644
--- a/dll/cpl/desk/lang/el-GR.rc
+++ b/dll/cpl/desk/lang/el-GR.rc
@@ -207,6 +207,8 @@ BEGIN
     IDS_CENTER "Κέντρο"
     IDS_STRETCH "Παραμόρφωση"
     IDS_TILE "Σε παράθεση"
+    IDS_FIT "Fit"
+    IDS_FILL "Fill"
 END
 
 STRINGTABLE
diff --git a/dll/cpl/desk/lang/en-GB.rc b/dll/cpl/desk/lang/en-GB.rc
index 4e4982b042..75a53f3e5b 100644
--- a/dll/cpl/desk/lang/en-GB.rc
+++ b/dll/cpl/desk/lang/en-GB.rc
@@ -207,6 +207,8 @@ BEGIN
     IDS_CENTER "Center"
     IDS_STRETCH "Stretch"
     IDS_TILE "Tile"
+    IDS_FIT "Fit"
+    IDS_FILL "Fill"
 END
 
 STRINGTABLE
diff --git a/dll/cpl/desk/lang/en-US.rc b/dll/cpl/desk/lang/en-US.rc
index 8d15bbbeb3..c29493c1bd 100644
--- a/dll/cpl/desk/lang/en-US.rc
+++ b/dll/cpl/desk/lang/en-US.rc
@@ -207,6 +207,8 @@ BEGIN
     IDS_CENTER "Center"
     IDS_STRETCH "Stretch"
     IDS_TILE "Tile"
+    IDS_FIT "Fit"
+    IDS_FILL "Fill"
 END
 
 STRINGTABLE
diff --git a/dll/cpl/desk/lang/es-ES.rc b/dll/cpl/desk/lang/es-ES.rc
index 819c6f8145..815192ea1f 100644
--- a/dll/cpl/desk/lang/es-ES.rc
+++ b/dll/cpl/desk/lang/es-ES.rc
@@ -209,6 +209,8 @@ BEGIN
     IDS_CENTER "Centrada"
     IDS_STRETCH "Expandida"
     IDS_TILE "En mosaico"
+    IDS_FIT "Fit"
+    IDS_FILL "Fill"
 END
 
 STRINGTABLE
diff --git a/dll/cpl/desk/lang/fr-FR.rc b/dll/cpl/desk/lang/fr-FR.rc
index 5ff190a1b2..820eb254d6 100644
--- a/dll/cpl/desk/lang/fr-FR.rc
+++ b/dll/cpl/desk/lang/fr-FR.rc
@@ -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
diff --git a/dll/cpl/desk/lang/he-IL.rc b/dll/cpl/desk/lang/he-IL.rc
index ee57ec16f7..cd5b9adbbe 100644
--- a/dll/cpl/desk/lang/he-IL.rc
+++ b/dll/cpl/desk/lang/he-IL.rc
@@ -207,6 +207,8 @@ BEGIN
     IDS_CENTER "מרכז"
     IDS_STRETCH "מתח"
     IDS_TILE "פרוש"
+    IDS_FIT "Fit"
+    IDS_FILL "Fill"
 END
 
 STRINGTABLE
diff --git a/dll/cpl/desk/lang/hu-HU.rc b/dll/cpl/desk/lang/hu-HU.rc
index 7876225014..fd99370fc4 100644
--- a/dll/cpl/desk/lang/hu-HU.rc
+++ b/dll/cpl/desk/lang/hu-HU.rc
@@ -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
diff --git a/dll/cpl/desk/lang/id-ID.rc b/dll/cpl/desk/lang/id-ID.rc
index 378267f552..fbae9c9b88 100644
--- a/dll/cpl/desk/lang/id-ID.rc
+++ b/dll/cpl/desk/lang/id-ID.rc
@@ -207,6 +207,8 @@ BEGIN
     IDS_CENTER "Tengah"
     IDS_STRETCH "Tarik"
     IDS_TILE "Tile"
+    IDS_FIT "Fit"
+    IDS_FILL "Fill"
 END
 
 STRINGTABLE
diff --git a/dll/cpl/desk/lang/it-IT.rc b/dll/cpl/desk/lang/it-IT.rc
index d121485a72..0d44f3da77 100644
--- a/dll/cpl/desk/lang/it-IT.rc
+++ b/dll/cpl/desk/lang/it-IT.rc
@@ -207,6 +207,8 @@ BEGIN
     IDS_CENTER "Al centro"
     IDS_STRETCH "Estesa"
     IDS_TILE "Affiancata"
+    IDS_FIT "Fit"
+    IDS_FILL "Fill"
 END
 
 STRINGTABLE
diff --git a/dll/cpl/desk/lang/ja-JP.rc b/dll/cpl/desk/lang/ja-JP.rc
index e326ea6394..20ff2aa926 100644
--- a/dll/cpl/desk/lang/ja-JP.rc
+++ b/dll/cpl/desk/lang/ja-JP.rc
@@ -207,6 +207,8 @@ BEGIN
     IDS_CENTER "中央に表示"
     IDS_STRETCH "拡大して表示"
     IDS_TILE "並べて表示"
+    IDS_FIT "Fit"
+    IDS_FILL "Fill"
 END
 
 STRINGTABLE
diff --git a/dll/cpl/desk/lang/nl-NL.rc b/dll/cpl/desk/lang/nl-NL.rc
index 5c7213de24..2cd1033e31 100644
--- a/dll/cpl/desk/lang/nl-NL.rc
+++ b/dll/cpl/desk/lang/nl-NL.rc
@@ -207,6 +207,8 @@ BEGIN
     IDS_CENTER "Center"
     IDS_STRETCH "Stretch"
     IDS_TILE "Tile"
+    IDS_FIT "Fit"
+    IDS_FILL "Fill"
 END
 
 STRINGTABLE
diff --git a/dll/cpl/desk/lang/no-NO.rc b/dll/cpl/desk/lang/no-NO.rc
index 5acd860787..210f49f7ae 100644
--- a/dll/cpl/desk/lang/no-NO.rc
+++ b/dll/cpl/desk/lang/no-NO.rc
@@ -207,6 +207,8 @@ BEGIN
     IDS_CENTER "Midtstill"
     IDS_STRETCH "Side ved side"
     IDS_TILE "Stukket"
+    IDS_FIT "Fit"
+    IDS_FILL "Fill"
 END
 
 STRINGTABLE
diff --git a/dll/cpl/desk/lang/pl-PL.rc b/dll/cpl/desk/lang/pl-PL.rc
index 037aee9f4a..f6f59bd371 100644
--- a/dll/cpl/desk/lang/pl-PL.rc
+++ b/dll/cpl/desk/lang/pl-PL.rc
@@ -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
diff --git a/dll/cpl/desk/lang/pt-BR.rc b/dll/cpl/desk/lang/pt-BR.rc
index c448cae75b..fffaca84bf 100644
--- a/dll/cpl/desk/lang/pt-BR.rc
+++ b/dll/cpl/desk/lang/pt-BR.rc
@@ -207,6 +207,8 @@ BEGIN
     IDS_CENTER "Centralizar"
     IDS_STRETCH "Estender"
     IDS_TILE "Lado a lado"
+    IDS_FIT "Fit"
+    IDS_FILL "Fill"
 END
 
 STRINGTABLE
diff --git a/dll/cpl/desk/lang/ro-RO.rc b/dll/cpl/desk/lang/ro-RO.rc
index 10e6007030..0dfbb37cb5 100644
--- a/dll/cpl/desk/lang/ro-RO.rc
+++ b/dll/cpl/desk/lang/ro-RO.rc
@@ -212,6 +212,8 @@ BEGIN
     IDS_CENTER "Centrat"
     IDS_STRETCH "Extins"
     IDS_TILE "Tapițat"
+    IDS_FIT "Fit"
+    IDS_FILL "Fill"
 END
 
 STRINGTABLE
diff --git a/dll/cpl/desk/lang/ru-RU.rc b/dll/cpl/desk/lang/ru-RU.rc
index d24182c2b9..90acdc6d66 100644
--- a/dll/cpl/desk/lang/ru-RU.rc
+++ b/dll/cpl/desk/lang/ru-RU.rc
@@ -207,6 +207,8 @@ BEGIN
     IDS_CENTER "по центру"
     IDS_STRETCH "растянуть"
     IDS_TILE "замостить"
+    IDS_FIT "вписать"
+    IDS_FILL "заполнить"
 END
 
 STRINGTABLE
diff --git a/dll/cpl/desk/lang/sk-SK.rc b/dll/cpl/desk/lang/sk-SK.rc
index 7f3b69328b..5c6311dad8 100644
--- a/dll/cpl/desk/lang/sk-SK.rc
+++ b/dll/cpl/desk/lang/sk-SK.rc
@@ -209,6 +209,8 @@ BEGIN
     IDS_CENTER "V strede"
     IDS_STRETCH "Roztiahnuť"
     IDS_TILE "Dlaždice"
+    IDS_FIT "Fit"
+    IDS_FILL "Fill"
 END
 
 STRINGTABLE
diff --git a/dll/cpl/desk/lang/sq-AL.rc b/dll/cpl/desk/lang/sq-AL.rc
index 1da51baa72..0a9fc973ab 100644
--- a/dll/cpl/desk/lang/sq-AL.rc
+++ b/dll/cpl/desk/lang/sq-AL.rc
@@ -211,6 +211,8 @@ BEGIN
     IDS_CENTER "Qender"
     IDS_STRETCH "Streq"
     IDS_TILE "Tile"
+    IDS_FIT "Fit"
+    IDS_FILL "Fill"
 END
 
 STRINGTABLE
diff --git a/dll/cpl/desk/lang/sv-SE.rc b/dll/cpl/desk/lang/sv-SE.rc
index dd7bb1bd5f..f286b2a921 100644
--- a/dll/cpl/desk/lang/sv-SE.rc
+++ b/dll/cpl/desk/lang/sv-SE.rc
@@ -209,6 +209,8 @@ BEGIN
     IDS_CENTER "Centrera"
     IDS_STRETCH "Sträck ut"
     IDS_TILE "Stapla"
+    IDS_FIT "Fit"
+    IDS_FILL "Fill"
 END
 
 STRINGTABLE
diff --git a/dll/cpl/desk/lang/tr-TR.rc b/dll/cpl/desk/lang/tr-TR.rc
index f33614293f..ee71aab40c 100644
--- a/dll/cpl/desk/lang/tr-TR.rc
+++ b/dll/cpl/desk/lang/tr-TR.rc
@@ -209,6 +209,8 @@ BEGIN
     IDS_CENTER "Ortala"
     IDS_STRETCH "Uzat"
     IDS_TILE "Döşe"
+    IDS_FIT "Fit"
+    IDS_FILL "Fill"
 END
 
 STRINGTABLE
diff --git a/dll/cpl/desk/lang/uk-UA.rc b/dll/cpl/desk/lang/uk-UA.rc
index b9aa734aa5..f768d29008 100644
--- a/dll/cpl/desk/lang/uk-UA.rc
+++ b/dll/cpl/desk/lang/uk-UA.rc
@@ -215,6 +215,8 @@ BEGIN
     IDS_CENTER "По центру"
     IDS_STRETCH "Розтягнути"
     IDS_TILE "Плиткою"
+    IDS_FIT "Fit"
+    IDS_FILL "Fill"
 END
 
 STRINGTABLE
diff --git a/dll/cpl/desk/lang/zh-CN.rc b/dll/cpl/desk/lang/zh-CN.rc
index b5973ee72f..ae16448009 100644
--- a/dll/cpl/desk/lang/zh-CN.rc
+++ b/dll/cpl/desk/lang/zh-CN.rc
@@ -214,6 +214,8 @@ BEGIN
     IDS_CENTER "居中"
     IDS_STRETCH "拉伸"
     IDS_TILE "平铺"
+    IDS_FIT "Fit"
+    IDS_FILL "Fill"
 END
 
 STRINGTABLE
diff --git a/dll/cpl/desk/lang/zh-TW.rc b/dll/cpl/desk/lang/zh-TW.rc
index 825e55411c..91f4ed2d7f 100644
--- a/dll/cpl/desk/lang/zh-TW.rc
+++ b/dll/cpl/desk/lang/zh-TW.rc
@@ -209,6 +209,8 @@ BEGIN
     IDS_CENTER "居中"
     IDS_STRETCH "拉伸"
     IDS_TILE "平鋪"
+    IDS_FIT "Fit"
+    IDS_FILL "Fill"
 END
 
 STRINGTABLE
diff --git a/dll/cpl/desk/resource.h b/dll/cpl/desk/resource.h
index 0bb35e0527..6884290e16 100644
--- a/dll/cpl/desk/resource.h
+++ b/dll/cpl/desk/resource.h
@@ -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
diff --git a/win32ss/user/ntuser/desktop.c b/win32ss/user/ntuser/desktop.c
index 7129f58d60..9f2e3b4d81 100644
--- a/win32ss/user/ntuser/desktop.c
+++ b/win32ss/user/ntuser/desktop.c
@@ -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,
diff --git a/win32ss/user/ntuser/sysparams.c b/win32ss/user/ntuser/sysparams.c
index ab0412606a..2265219586 100644
--- a/win32ss/user/ntuser/sysparams.c
+++ b/win32ss/user/ntuser/sysparams.c
@@ -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 (!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
diff --git a/win32ss/user/ntuser/sysparams.h b/win32ss/user/ntuser/sysparams.h
index 28e9d94536..0b564f8609 100644
--- a/win32ss/user/ntuser/sysparams.h
+++ b/win32ss/user/ntuser/sysparams.h
@@ -40,7 +40,9 @@ typedef enum
 {
     wmCenter = 0,
     wmTile,
-    wmStretch
+    wmStretch,
+    wmFit,
+    wmFill
 } WALLPAPER_MODE;
 
 typedef struct _SPIVALUES

Reply via email to