Signed-off-by: Zhiyi Zhang zzhang@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 */