Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/user32/tests/monitor.c | 110 +++++++++++++++++++++++++++++++++++-
1 file changed, 107 insertions(+), 3 deletions(-)
diff --git a/dlls/user32/tests/monitor.c b/dlls/user32/tests/monitor.c
index bd348576726..e745fb9c7b3 100644
--- a/dlls/user32/tests/monitor.c
+++ b/dlls/user32/tests/monitor.c
@@ -2180,13 +2180,17 @@ static void _check_display_dc(INT line, HDC hdc, const DEVMODEA *dm, BOOL allow_
static void test_display_dc(void)
{
+ static const INT bpps[] = {1, 4, 8, 16, 24, 32};
+ HBITMAP hbitmap, old_hbitmap;
+ INT count, old_count, i, bpp;
DWORD device_idx, mode_idx;
DEVMODEA dm, dm2, dm3;
- INT count, old_count;
DISPLAY_DEVICEA dd;
+ HDC hdc, mem_dc;
+ DIBSECTION dib;
+ BITMAP bitmap;
BOOL ret;
LONG res;
- HDC hdc;
/* Test DCs covering the entire virtual screen */
hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
@@ -2199,6 +2203,51 @@ static void test_display_dc(void)
check_display_dc(hdc, &dm, FALSE);
+ /* Test that CreateCompatibleBitmap() for display DCs creates DDBs */
+ hbitmap = CreateCompatibleBitmap(hdc, dm.dmPelsWidth, dm.dmPelsHeight);
+ ok(!!hbitmap, "CreateCompatibleBitmap failed, error %d.\n", GetLastError());
+ count = GetObjectW(hbitmap, sizeof(dib), &dib);
+ ok(count == sizeof(BITMAP), "GetObject failed, count %d.\n", count);
+ count = GetObjectW(hbitmap, sizeof(bitmap), &bitmap);
+ ok(count == sizeof(BITMAP), "GetObject failed, count %d.\n", count);
+ ok(bitmap.bmBitsPixel == dm.dmBitsPerPel, "Expected %d, got %d.\n", dm.dmBitsPerPel,
+ bitmap.bmBitsPixel);
+ DeleteObject(hbitmap);
+
+ /* Test selecting a DDB of a different depth into a display compatible DC */
+ for (i = 0; i < ARRAY_SIZE(bpps); ++i)
+ {
+ winetest_push_context("bpp %d", bpps[i]);
+
+ mem_dc = CreateCompatibleDC(hdc);
+ hbitmap = CreateBitmap(dm.dmPelsWidth, dm.dmPelsHeight, 1, bpps[i], NULL);
+ ok(!!hbitmap, "CreateBitmap failed, error %d.\n", GetLastError());
+ old_hbitmap = SelectObject(mem_dc, hbitmap);
+ if (bpps[i] != 1 && bpps[i] != 32)
+ ok(!old_hbitmap, "Selecting bitmap succeeded.\n");
+ else
+ ok(!!old_hbitmap, "Failed to select bitmap.\n");
+
+ SelectObject(mem_dc, old_hbitmap);
+ DeleteObject(hbitmap);
+ DeleteDC(mem_dc);
+
+ winetest_pop_context();
+ }
+
+ /* Test selecting a DDB of the same color depth into a display compatible DC */
+ mem_dc = CreateCompatibleDC(hdc);
+ bpp = GetDeviceCaps(mem_dc, BITSPIXEL);
+ ok(bpp == dm.dmBitsPerPel, "Expected bpp %d, got %d.\n", dm.dmBitsPerPel, bpp);
+ hbitmap = CreateCompatibleBitmap(hdc, dm.dmPelsWidth, dm.dmPelsHeight);
+ count = GetObjectW(hbitmap, sizeof(bitmap), &bitmap);
+ ok(count == sizeof(BITMAP), "GetObject failed, count %d.\n", count);
+ ok(bitmap.bmBitsPixel == dm.dmBitsPerPel, "Expected %d, got %d.\n", dm.dmBitsPerPel, bitmap.bmBitsPixel);
+ old_hbitmap = SelectObject(mem_dc, hbitmap);
+ ok(!!old_hbitmap, "Failed to select bitmap.\n");
+ SelectObject(mem_dc, old_hbitmap);
+ DeleteDC(mem_dc);
+
/* Tests after mode changes to a different resolution */
memset(&dm2, 0, sizeof(dm2));
dm2.dmSize = sizeof(dm2);
@@ -2226,7 +2275,7 @@ static void test_display_dc(void)
dm2.dmSize = sizeof(dm2);
for (mode_idx = 0; EnumDisplaySettingsA(NULL, mode_idx, &dm2); ++mode_idx)
{
- if (dm2.dmBitsPerPel != dm.dmBitsPerPel)
+ if (dm2.dmBitsPerPel != dm.dmBitsPerPel && dm2.dmBitsPerPel != 1)
break;
}
if (dm2.dmBitsPerPel && dm2.dmBitsPerPel != dm.dmBitsPerPel)
@@ -2239,6 +2288,59 @@ static void test_display_dc(void)
{
check_display_dc(hdc, &dm2, FALSE);
+ /* Test selecting a compatible bitmap of a different color depth previously created for
+ * a display DC into a new compatible DC */
+ count = GetObjectW(hbitmap, sizeof(bitmap), &bitmap);
+ ok(count == sizeof(BITMAP), "GetObject failed, count %d.\n", count);
+ ok(bitmap.bmBitsPixel == dm.dmBitsPerPel, "Expected %d, got %d.\n", dm.dmBitsPerPel,
+ bitmap.bmBitsPixel);
+
+ /* Note that hbitmap is of a different color depth and it can be successfully selected
+ * into the new compatible DC */
+ mem_dc = CreateCompatibleDC(hdc);
+ bpp = GetDeviceCaps(mem_dc, BITSPIXEL);
+ ok(bpp == dm2.dmBitsPerPel, "Expected bpp %d, got %d.\n", dm2.dmBitsPerPel, bpp);
+ old_hbitmap = SelectObject(mem_dc, hbitmap);
+ todo_wine
+ ok(!!old_hbitmap, "Failed to select bitmap.\n");
+ bpp = GetDeviceCaps(mem_dc, BITSPIXEL);
+ ok(bpp == dm2.dmBitsPerPel, "Expected bpp %d, got %d.\n", dm2.dmBitsPerPel, bpp);
+ SelectObject(mem_dc, old_hbitmap);
+ DeleteDC(mem_dc);
+ DeleteObject(hbitmap);
+
+ /* Test selecting a DDB of a different color depth into a display compatible DC */
+ for (i = 0; i < ARRAY_SIZE(bpps); ++i)
+ {
+ winetest_push_context("bpp %d", bpps[i]);
+
+ mem_dc = CreateCompatibleDC(hdc);
+ hbitmap = CreateBitmap(dm2.dmPelsWidth, dm2.dmPelsHeight, 1, bpps[i], NULL);
+ ok(!!hbitmap, "CreateBitmap failed, error %d.\n", GetLastError());
+ old_hbitmap = SelectObject(mem_dc, hbitmap);
+ /* On Win7 dual-QXL test bot and XP, only 1-bit DDBs and DDBs with the same color
+ * depth can be selected to the compatible DC. On newer versions of Windows, only
+ * 1-bit and 32-bit DDBs can be selected into the compatible DC even if
+ * GetDeviceCaps(BITSPIXEL) reports a different color depth, for example, 16-bit.
+ * It's most likely due to the fact that lower color depth are emulated on newer
+ * versions of Windows as the real color depth is still 32-bit */
+ if (bpps[i] != 1 && bpps[i] != 32)
+ todo_wine_if(bpps[i] == dm2.dmBitsPerPel)
+ ok(!old_hbitmap || broken(!!old_hbitmap) /* Win7 dual-QXL test bot and XP */,
+ "Selecting bitmap succeeded.\n");
+ else
+ todo_wine_if(bpps[i] == 32)
+ ok(!!old_hbitmap || broken(!old_hbitmap) /* Win7 dual-QXL test bot and XP */,
+ "Failed to select bitmap.\n");
+
+ SelectObject(mem_dc, old_hbitmap);
+ DeleteObject(hbitmap);
+ DeleteDC(mem_dc);
+
+ winetest_pop_context();
+ }
+ hbitmap = NULL;
+
res = ChangeDisplaySettingsExA(NULL, NULL, NULL, 0, NULL);
ok(res == DISP_CHANGE_SUCCESSFUL, "ChangeDisplaySettingsExA returned unexpected %d.\n", res);
}
@@ -2248,6 +2350,8 @@ static void test_display_dc(void)
win_skip("Failed to find a different color depth other than %u.\n", dm.dmBitsPerPel);
}
+ if (hbitmap)
+ DeleteObject(hbitmap);
DeleteDC(hdc);
/* Test DCs covering a specific monitor */
--
2.32.0