[PATCH v4 0/3] MR10723: ddraw: Ignore hwnd clipper in exclusive fullscreen mode.
-- v4: ddraw: Ignore hwnd clipper in exclusive fullscreen mode. ddraw/tests: Add tests for clipper in exclusive fullscreen mode. ddraw/tests: Don't leak window and ddraw in test_d3d_state_reset() on ddraw2. https://gitlab.winehq.org/wine/wine/-/merge_requests/10723
From: Paul Gofman <pgofman@codeweavers.com> --- dlls/ddraw/tests/ddraw2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c index 114b297d239..ca030897abd 100644 --- a/dlls/ddraw/tests/ddraw2.c +++ b/dlls/ddraw/tests/ddraw2.c @@ -17053,13 +17053,13 @@ static void test_d3d_state_reset(void) window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, 0, 0, 0, 0); - window = create_window(); ddraw = create_ddraw(); ok(!!ddraw, "Failed to create a ddraw object.\n"); if (!(device = create_device(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN))) { skip("Failed to create 3D device.\n"); + IDirectDraw2_Release(ddraw); DestroyWindow(window); return; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10723
From: Paul Gofman <pgofman@codeweavers.com> --- dlls/ddraw/tests/ddraw1.c | 184 ++++++++++++++++++++++++++++++++++++++ dlls/ddraw/tests/ddraw2.c | 184 ++++++++++++++++++++++++++++++++++++++ dlls/ddraw/tests/ddraw4.c | 184 ++++++++++++++++++++++++++++++++++++++ dlls/ddraw/tests/ddraw7.c | 184 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 736 insertions(+) diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index 2e2f7e62483..594baee6ff9 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -114,6 +114,14 @@ static void flush_events(void) } } +static void pump_messages(void) +{ + MSG msg; + + while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) + DispatchMessageA(&msg); +} + static HWND create_foreground_window(void) { for (UINT retries = 5; retries; retries--) @@ -16382,6 +16390,181 @@ out: DestroyWindow(window); } +static void check_surface_clipper(IDirectDrawSurface *surface, IDirectDrawClipper *clipper_hwnd, + IDirectDrawClipper *clipper_region, RECT *window_rect, DWORD style) +{ + unsigned int c; + DDBLTFX fx; + HRESULT hr; + + memset(&fx, 0, sizeof(fx)); + fx.dwSize = sizeof(fx); + fx.dwFillColor = 0xff00ff00; + + fill_surface(surface, 0xffff0000); + + /* Clipper with region works. */ + hr = IDirectDrawSurface_SetClipper(surface, clipper_region); + ok(hr == DD_OK, "got %#lx.\n", hr); + c = get_surface_color(surface, 101, 101); + ok(c == 0x00ff0000, "got %#x.\n", c); + hr = IDirectDrawSurface_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx); + ok(hr == DD_OK, "got %#lx.\n", hr); + c = get_surface_color(surface, 0, 0); + ok(c == 0x00ff0000, "got %#x.\n", c); + c = get_surface_color(surface, 101, 101); + ok(c == 0x0000ff00, "got %#x.\n", c); + + /* Clipper with window has no effect. */ + hr = IDirectDrawSurface_SetClipper(surface, clipper_hwnd); + ok(hr == DD_OK, "got %#lx.\n", hr); + fill_surface(surface, 0xff0000ff); + c = get_surface_color(surface, window_rect->left + 1, window_rect->top + 1); + ok(c == 0x000000ff, "got %#x.\n", c); + + hr = IDirectDrawSurface_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx); + ok(hr == DD_OK, "got %#lx.\n", hr); + + c = get_surface_color(surface, window_rect->left + 1, window_rect->top + 1); + todo_wine_if(!(style & WS_VISIBLE)) ok(c == 0x0000ff00, "got %#x.\n", c); + c = get_surface_color(surface, 0, 0); + todo_wine_if((style & (WS_CHILD | WS_VISIBLE)) != (WS_CHILD | WS_VISIBLE)) ok(c == 0x0000ff00, "got %#x.\n", c); + + hr = IDirectDrawSurface_SetClipper(surface, NULL); + ok(hr == DD_OK, "got %#lx.\n", hr); + fill_surface(surface, 0); +} + +static void test_clipper_in_exclusive_fullscreen(void) +{ + static const struct + { + DWORD style; + BOOL parent; + } + tests[] = + { + { WS_POPUP }, + { WS_POPUP, TRUE }, + { WS_CHILD, TRUE }, + { WS_OVERLAPPED }, + { WS_CHILD | WS_VISIBLE, TRUE }, + { WS_POPUP | WS_VISIBLE }, + }; + IDirectDrawSurface *primary, *offscreen; + IDirectDrawClipper *clipper, *clipper2; + DDSURFACEDESC surface_desc; + HWND window, clip_window; + IDirectDraw *ddraw; + RGNDATA *rgn_data; + DWORD ret, style; + RECT window_rect; + ULONG refcount; + unsigned int i; + HRESULT hr; + HRGN rgn; + + if (!(ddraw = create_ddraw())) + { + skip("Failed to create ddraw, skipping test.\n"); + return; + } + hr = IDirectDraw_CreateClipper(ddraw, 0, &clipper, NULL); + ok(hr == DD_OK, "got %#lx.\n", hr); + + hr = IDirectDraw_CreateClipper(ddraw, 0, &clipper2, NULL); + ok(hr == DD_OK, "got %#lx.\n", hr); + + window = CreateWindowA("static", "ddraw_fullscreen", WS_POPUP | WS_VISIBLE, 0, 0, 640, 480, NULL, NULL, NULL, NULL); + pump_messages(); + hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); + ok(hr == DD_OK, "got %#lx.\n", hr); + pump_messages(); + + rgn = CreateRectRgn(100, 100, 200, 200); + ok(!!rgn, "Failed to create region.\n"); + ret = GetRegionData(rgn, 0, NULL); + rgn_data = malloc(ret); + ret = GetRegionData(rgn, ret, rgn_data); + ok(!!ret, "Failed to get region data.\n"); + DeleteObject(rgn); + hr = IDirectDrawClipper_SetClipList(clipper2, rgn_data, 0); + ok(hr == DD_OK, "got %#lx.\n", hr); + free(rgn_data); + + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS; + surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &primary, NULL); + ok(hr == DD_OK, "got %#lx.\n", hr); + + surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; + surface_desc.dwWidth = 640; + surface_desc.dwHeight = 480; + hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &offscreen, NULL); + ok(hr == DD_OK, "got %#lx.\n", hr); + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + winetest_push_context("test %u", i); + style = tests[i].style; + clip_window = CreateWindowA("static", "ddraw_clip", style, 100, 100, 100, 100, + tests[i].parent ? window : NULL, NULL, NULL, NULL); + ok(!!clip_window, "got error %ld.\n", GetLastError()); + pump_messages(); + + GetWindowRect(clip_window, &window_rect); + hr = IDirectDrawClipper_SetHWnd(clipper, 0, clip_window); + ok(hr == DD_OK, "got %#lx.\n", hr); + + hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret); + ok(hr == DD_OK, "got %#lx.\n", hr); + rgn_data = malloc(ret); + hr = IDirectDrawClipper_GetClipList(clipper, NULL, rgn_data, &ret); + ok(hr == DD_OK, "got %#lx.\n", hr); + ok(rgn_data->rdh.dwSize == sizeof(rgn_data->rdh), "Got unexpected structure size %#lx.\n", rgn_data->rdh.dwSize); + ok(rgn_data->rdh.iType == RDH_RECTANGLES, "Got unexpected type %#lx.\n", rgn_data->rdh.iType); + if (style & WS_VISIBLE) + { + ok(rgn_data->rdh.nCount >= 1, "got %lu.\n", rgn_data->rdh.nCount); + if (!(style & WS_CHILD)) + ok(EqualRect(&rgn_data->rdh.rcBound, &window_rect), "got %s, expected %s.\n", + wine_dbgstr_rect(&rgn_data->rdh.rcBound), wine_dbgstr_rect(&window_rect)); + } + else + { + ok(!rgn_data->rdh.nCount, "got %lu.\n", rgn_data->rdh.nCount); + } + free(rgn_data); + + winetest_push_context("primary"); + check_surface_clipper(primary, clipper, clipper2, &window_rect, style); + winetest_pop_context(); + + winetest_push_context("offscreen"); + check_surface_clipper(offscreen, clipper, clipper2, &window_rect, style); + winetest_pop_context(); + + hr = IDirectDrawClipper_SetHWnd(clipper, 0, NULL); + ok(hr == DD_OK, "got %#lx.\n", hr); + DestroyWindow(clip_window); + pump_messages(); + winetest_pop_context(); + } + + IDirectDrawClipper_Release(clipper); + refcount = IDirectDrawSurface_Release(offscreen); + ok(!refcount, "Got unexpected refcount %lu.\n", refcount); + refcount = IDirectDrawSurface_Release(primary); + ok(!refcount, "Got unexpected refcount %lu.\n", refcount); + + IDirectDraw_Release(ddraw); + DestroyWindow(window); + pump_messages(); +} + START_TEST(ddraw1) { DDDEVICEIDENTIFIER identifier; @@ -16508,4 +16691,5 @@ START_TEST(ddraw1) test_sysmem_x_channel(); test_yuv_blit(); test_blit_to_self(); + test_clipper_in_exclusive_fullscreen(); } diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c index ca030897abd..ebbc20aacac 100644 --- a/dlls/ddraw/tests/ddraw2.c +++ b/dlls/ddraw/tests/ddraw2.c @@ -115,6 +115,14 @@ static void flush_events(void) } } +static void pump_messages(void) +{ + MSG msg; + + while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) + DispatchMessageA(&msg); +} + static HWND create_foreground_window(void) { for (UINT retries = 5; retries; retries--) @@ -17453,6 +17461,181 @@ out: DestroyWindow(window); } +static void check_surface_clipper(IDirectDrawSurface *surface, IDirectDrawClipper *clipper_hwnd, + IDirectDrawClipper *clipper_region, RECT *window_rect, DWORD style) +{ + unsigned int c; + DDBLTFX fx; + HRESULT hr; + + memset(&fx, 0, sizeof(fx)); + fx.dwSize = sizeof(fx); + fx.dwFillColor = 0xff00ff00; + + fill_surface(surface, 0xffff0000); + + /* Clipper with region works. */ + hr = IDirectDrawSurface_SetClipper(surface, clipper_region); + ok(hr == DD_OK, "got %#lx.\n", hr); + c = get_surface_color(surface, 101, 101); + ok(c == 0x00ff0000, "got %#x.\n", c); + hr = IDirectDrawSurface_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx); + ok(hr == DD_OK, "got %#lx.\n", hr); + c = get_surface_color(surface, 0, 0); + ok(c == 0x00ff0000, "got %#x.\n", c); + c = get_surface_color(surface, 101, 101); + ok(c == 0x0000ff00, "got %#x.\n", c); + + /* Clipper with window has no effect. */ + hr = IDirectDrawSurface_SetClipper(surface, clipper_hwnd); + ok(hr == DD_OK, "got %#lx.\n", hr); + fill_surface(surface, 0xff0000ff); + c = get_surface_color(surface, window_rect->left + 1, window_rect->top + 1); + ok(c == 0x000000ff, "got %#x.\n", c); + + hr = IDirectDrawSurface_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx); + ok(hr == DD_OK, "got %#lx.\n", hr); + + c = get_surface_color(surface, window_rect->left + 1, window_rect->top + 1); + todo_wine_if(!(style & WS_VISIBLE)) ok(c == 0x0000ff00, "got %#x.\n", c); + c = get_surface_color(surface, 0, 0); + todo_wine_if((style & (WS_CHILD | WS_VISIBLE)) != (WS_CHILD | WS_VISIBLE)) ok(c == 0x0000ff00, "got %#x.\n", c); + + hr = IDirectDrawSurface_SetClipper(surface, NULL); + ok(hr == DD_OK, "got %#lx.\n", hr); + fill_surface(surface, 0); +} + +static void test_clipper_in_exclusive_fullscreen(void) +{ + static const struct + { + DWORD style; + BOOL parent; + } + tests[] = + { + { WS_POPUP }, + { WS_POPUP, TRUE }, + { WS_CHILD, TRUE }, + { WS_OVERLAPPED }, + { WS_CHILD | WS_VISIBLE, TRUE }, + { WS_POPUP | WS_VISIBLE }, + }; + IDirectDrawSurface *primary, *offscreen; + IDirectDrawClipper *clipper, *clipper2; + DDSURFACEDESC surface_desc; + HWND window, clip_window; + IDirectDraw2 *ddraw; + RGNDATA *rgn_data; + DWORD ret, style; + RECT window_rect; + ULONG refcount; + unsigned int i; + HRESULT hr; + HRGN rgn; + + if (!(ddraw = create_ddraw())) + { + skip("Failed to create ddraw, skipping test.\n"); + return; + } + hr = IDirectDraw2_CreateClipper(ddraw, 0, &clipper, NULL); + ok(hr == DD_OK, "got %#lx.\n", hr); + + hr = IDirectDraw2_CreateClipper(ddraw, 0, &clipper2, NULL); + ok(hr == DD_OK, "got %#lx.\n", hr); + + window = CreateWindowA("static", "ddraw_fullscreen", WS_POPUP | WS_VISIBLE, 0, 0, 640, 480, NULL, NULL, NULL, NULL); + pump_messages(); + hr = IDirectDraw2_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); + ok(hr == DD_OK, "got %#lx.\n", hr); + pump_messages(); + + rgn = CreateRectRgn(100, 100, 200, 200); + ok(!!rgn, "Failed to create region.\n"); + ret = GetRegionData(rgn, 0, NULL); + rgn_data = malloc(ret); + ret = GetRegionData(rgn, ret, rgn_data); + ok(!!ret, "Failed to get region data.\n"); + DeleteObject(rgn); + hr = IDirectDrawClipper_SetClipList(clipper2, rgn_data, 0); + ok(hr == DD_OK, "got %#lx.\n", hr); + free(rgn_data); + + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS; + surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &primary, NULL); + ok(hr == DD_OK, "got %#lx.\n", hr); + + surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; + surface_desc.dwWidth = 640; + surface_desc.dwHeight = 480; + hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &offscreen, NULL); + ok(hr == DD_OK, "got %#lx.\n", hr); + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + winetest_push_context("test %u", i); + style = tests[i].style; + clip_window = CreateWindowA("static", "ddraw_clip", style, 100, 100, 100, 100, + tests[i].parent ? window : NULL, NULL, NULL, NULL); + ok(!!clip_window, "got error %ld.\n", GetLastError()); + pump_messages(); + + GetWindowRect(clip_window, &window_rect); + hr = IDirectDrawClipper_SetHWnd(clipper, 0, clip_window); + ok(hr == DD_OK, "got %#lx.\n", hr); + + hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret); + ok(hr == DD_OK, "got %#lx.\n", hr); + rgn_data = malloc(ret); + hr = IDirectDrawClipper_GetClipList(clipper, NULL, rgn_data, &ret); + ok(hr == DD_OK, "got %#lx.\n", hr); + ok(rgn_data->rdh.dwSize == sizeof(rgn_data->rdh), "Got unexpected structure size %#lx.\n", rgn_data->rdh.dwSize); + ok(rgn_data->rdh.iType == RDH_RECTANGLES, "Got unexpected type %#lx.\n", rgn_data->rdh.iType); + if (style & WS_VISIBLE) + { + ok(rgn_data->rdh.nCount >= 1, "got %lu.\n", rgn_data->rdh.nCount); + if (!(style & WS_CHILD)) + ok(EqualRect(&rgn_data->rdh.rcBound, &window_rect), "got %s, expected %s.\n", + wine_dbgstr_rect(&rgn_data->rdh.rcBound), wine_dbgstr_rect(&window_rect)); + } + else + { + ok(!rgn_data->rdh.nCount, "got %lu.\n", rgn_data->rdh.nCount); + } + free(rgn_data); + + winetest_push_context("primary"); + check_surface_clipper(primary, clipper, clipper2, &window_rect, style); + winetest_pop_context(); + + winetest_push_context("offscreen"); + check_surface_clipper(offscreen, clipper, clipper2, &window_rect, style); + winetest_pop_context(); + + hr = IDirectDrawClipper_SetHWnd(clipper, 0, NULL); + ok(hr == DD_OK, "got %#lx.\n", hr); + DestroyWindow(clip_window); + pump_messages(); + winetest_pop_context(); + } + + IDirectDrawClipper_Release(clipper); + refcount = IDirectDrawSurface_Release(offscreen); + ok(!refcount, "Got unexpected refcount %lu.\n", refcount); + refcount = IDirectDrawSurface_Release(primary); + ok(!refcount, "Got unexpected refcount %lu.\n", refcount); + + IDirectDraw2_Release(ddraw); + DestroyWindow(window); + pump_messages(); +} + START_TEST(ddraw2) { DDDEVICEIDENTIFIER identifier; @@ -17585,4 +17768,5 @@ START_TEST(ddraw2) test_sysmem_x_channel(); test_yuv_blit(); test_blit_to_self(); + test_clipper_in_exclusive_fullscreen(); } diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c index 285b36f54c6..e2fa4738cbc 100644 --- a/dlls/ddraw/tests/ddraw4.c +++ b/dlls/ddraw/tests/ddraw4.c @@ -121,6 +121,14 @@ static void flush_events(void) } } +static void pump_messages(void) +{ + MSG msg; + + while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) + DispatchMessageA(&msg); +} + static HWND create_foreground_window(void) { for (UINT retries = 5; retries; retries--) @@ -20552,6 +20560,181 @@ out: DestroyWindow(window); } +static void check_surface_clipper(IDirectDrawSurface4 *surface, IDirectDrawClipper *clipper_hwnd, + IDirectDrawClipper *clipper_region, RECT *window_rect, DWORD style) +{ + unsigned int c; + DDBLTFX fx; + HRESULT hr; + + memset(&fx, 0, sizeof(fx)); + fx.dwSize = sizeof(fx); + fx.dwFillColor = 0xff00ff00; + + fill_surface(surface, 0xffff0000); + + /* Clipper with region works. */ + hr = IDirectDrawSurface4_SetClipper(surface, clipper_region); + ok(hr == DD_OK, "got %#lx.\n", hr); + c = get_surface_color(surface, 101, 101); + ok(c == 0x00ff0000, "got %#x.\n", c); + hr = IDirectDrawSurface4_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx); + ok(hr == DD_OK, "got %#lx.\n", hr); + c = get_surface_color(surface, 0, 0); + ok(c == 0x00ff0000, "got %#x.\n", c); + c = get_surface_color(surface, 101, 101); + ok(c == 0x0000ff00, "got %#x.\n", c); + + /* Clipper with window has no effect. */ + hr = IDirectDrawSurface4_SetClipper(surface, clipper_hwnd); + ok(hr == DD_OK, "got %#lx.\n", hr); + fill_surface(surface, 0xff0000ff); + c = get_surface_color(surface, window_rect->left + 1, window_rect->top + 1); + ok(c == 0x000000ff, "got %#x.\n", c); + + hr = IDirectDrawSurface4_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx); + ok(hr == DD_OK, "got %#lx.\n", hr); + + c = get_surface_color(surface, window_rect->left + 1, window_rect->top + 1); + todo_wine_if(!(style & WS_VISIBLE)) ok(c == 0x0000ff00, "got %#x.\n", c); + c = get_surface_color(surface, 0, 0); + todo_wine_if((style & (WS_CHILD | WS_VISIBLE)) != (WS_CHILD | WS_VISIBLE)) ok(c == 0x0000ff00, "got %#x.\n", c); + + hr = IDirectDrawSurface4_SetClipper(surface, NULL); + ok(hr == DD_OK, "got %#lx.\n", hr); + fill_surface(surface, 0); +} + +static void test_clipper_in_exclusive_fullscreen(void) +{ + static const struct + { + DWORD style; + BOOL parent; + } + tests[] = + { + { WS_POPUP }, + { WS_POPUP, TRUE }, + { WS_CHILD, TRUE }, + { WS_OVERLAPPED }, + { WS_CHILD | WS_VISIBLE, TRUE }, + { WS_POPUP | WS_VISIBLE }, + }; + IDirectDrawSurface4 *primary, *offscreen; + IDirectDrawClipper *clipper, *clipper2; + DDSURFACEDESC2 surface_desc; + HWND window, clip_window; + IDirectDraw4 *ddraw; + RGNDATA *rgn_data; + DWORD ret, style; + RECT window_rect; + ULONG refcount; + unsigned int i; + HRESULT hr; + HRGN rgn; + + if (!(ddraw = create_ddraw())) + { + skip("Failed to create ddraw, skipping test.\n"); + return; + } + hr = IDirectDraw4_CreateClipper(ddraw, 0, &clipper, NULL); + ok(hr == DD_OK, "got %#lx.\n", hr); + + hr = IDirectDraw4_CreateClipper(ddraw, 0, &clipper2, NULL); + ok(hr == DD_OK, "got %#lx.\n", hr); + + window = CreateWindowA("static", "ddraw_fullscreen", WS_POPUP | WS_VISIBLE, 0, 0, 640, 480, NULL, NULL, NULL, NULL); + pump_messages(); + hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); + ok(hr == DD_OK, "got %#lx.\n", hr); + pump_messages(); + + rgn = CreateRectRgn(100, 100, 200, 200); + ok(!!rgn, "Failed to create region.\n"); + ret = GetRegionData(rgn, 0, NULL); + rgn_data = malloc(ret); + ret = GetRegionData(rgn, ret, rgn_data); + ok(!!ret, "Failed to get region data.\n"); + DeleteObject(rgn); + hr = IDirectDrawClipper_SetClipList(clipper2, rgn_data, 0); + ok(hr == DD_OK, "got %#lx.\n", hr); + free(rgn_data); + + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS; + surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &primary, NULL); + ok(hr == DD_OK, "got %#lx.\n", hr); + + surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; + surface_desc.dwWidth = 640; + surface_desc.dwHeight = 480; + hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &offscreen, NULL); + ok(hr == DD_OK, "got %#lx.\n", hr); + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + winetest_push_context("test %u", i); + style = tests[i].style; + clip_window = CreateWindowA("static", "ddraw_clip", style, 100, 100, 100, 100, + tests[i].parent ? window : NULL, NULL, NULL, NULL); + ok(!!clip_window, "got error %ld.\n", GetLastError()); + pump_messages(); + + GetWindowRect(clip_window, &window_rect); + hr = IDirectDrawClipper_SetHWnd(clipper, 0, clip_window); + ok(hr == DD_OK, "got %#lx.\n", hr); + + hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret); + ok(hr == DD_OK, "got %#lx.\n", hr); + rgn_data = malloc(ret); + hr = IDirectDrawClipper_GetClipList(clipper, NULL, rgn_data, &ret); + ok(hr == DD_OK, "got %#lx.\n", hr); + ok(rgn_data->rdh.dwSize == sizeof(rgn_data->rdh), "Got unexpected structure size %#lx.\n", rgn_data->rdh.dwSize); + ok(rgn_data->rdh.iType == RDH_RECTANGLES, "Got unexpected type %#lx.\n", rgn_data->rdh.iType); + if (style & WS_VISIBLE) + { + ok(rgn_data->rdh.nCount >= 1, "got %lu.\n", rgn_data->rdh.nCount); + if (!(style & WS_CHILD)) + ok(EqualRect(&rgn_data->rdh.rcBound, &window_rect), "got %s, expected %s.\n", + wine_dbgstr_rect(&rgn_data->rdh.rcBound), wine_dbgstr_rect(&window_rect)); + } + else + { + ok(!rgn_data->rdh.nCount, "got %lu.\n", rgn_data->rdh.nCount); + } + free(rgn_data); + + winetest_push_context("primary"); + check_surface_clipper(primary, clipper, clipper2, &window_rect, style); + winetest_pop_context(); + + winetest_push_context("offscreen"); + check_surface_clipper(offscreen, clipper, clipper2, &window_rect, style); + winetest_pop_context(); + + hr = IDirectDrawClipper_SetHWnd(clipper, 0, NULL); + ok(hr == DD_OK, "got %#lx.\n", hr); + DestroyWindow(clip_window); + pump_messages(); + winetest_pop_context(); + } + + IDirectDrawClipper_Release(clipper); + refcount = IDirectDrawSurface4_Release(offscreen); + ok(!refcount, "Got unexpected refcount %lu.\n", refcount); + refcount = IDirectDrawSurface4_Release(primary); + ok(!refcount, "Got unexpected refcount %lu.\n", refcount); + + IDirectDraw4_Release(ddraw); + DestroyWindow(window); + pump_messages(); +} + START_TEST(ddraw4) { DDDEVICEIDENTIFIER identifier; @@ -20701,4 +20884,5 @@ START_TEST(ddraw4) test_sysmem_x_channel(); test_yuv_blit(); test_blit_to_self(); + test_clipper_in_exclusive_fullscreen(); } diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index e8487283ead..eb35cfa6792 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -162,6 +162,14 @@ static void flush_events(void) } } +static void pump_messages(void) +{ + MSG msg; + + while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) + DispatchMessageA(&msg); +} + static HWND create_foreground_window(void) { for (UINT retries = 5; retries; retries--) @@ -20950,6 +20958,181 @@ out: DestroyWindow(window); } +static void check_surface_clipper(IDirectDrawSurface7 *surface, IDirectDrawClipper *clipper_hwnd, + IDirectDrawClipper *clipper_region, RECT *window_rect, DWORD style) +{ + unsigned int c; + DDBLTFX fx; + HRESULT hr; + + memset(&fx, 0, sizeof(fx)); + fx.dwSize = sizeof(fx); + fx.dwFillColor = 0xff00ff00; + + fill_surface(surface, 0xffff0000); + + /* Clipper with region works. */ + hr = IDirectDrawSurface7_SetClipper(surface, clipper_region); + ok(hr == DD_OK, "got %#lx.\n", hr); + c = get_surface_color(surface, 101, 101); + ok(c == 0x00ff0000, "got %#x.\n", c); + hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx); + ok(hr == DD_OK, "got %#lx.\n", hr); + c = get_surface_color(surface, 0, 0); + ok(c == 0x00ff0000, "got %#x.\n", c); + c = get_surface_color(surface, 101, 101); + ok(c == 0x0000ff00, "got %#x.\n", c); + + /* Clipper with window has no effect. */ + hr = IDirectDrawSurface7_SetClipper(surface, clipper_hwnd); + ok(hr == DD_OK, "got %#lx.\n", hr); + fill_surface(surface, 0xff0000ff); + c = get_surface_color(surface, window_rect->left + 1, window_rect->top + 1); + ok(c == 0x000000ff, "got %#x.\n", c); + + hr = IDirectDrawSurface7_Blt(surface, NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &fx); + ok(hr == DD_OK, "got %#lx.\n", hr); + + c = get_surface_color(surface, window_rect->left + 1, window_rect->top + 1); + todo_wine_if(!(style & WS_VISIBLE)) ok(c == 0x0000ff00, "got %#x.\n", c); + c = get_surface_color(surface, 0, 0); + todo_wine_if((style & (WS_CHILD | WS_VISIBLE)) != (WS_CHILD | WS_VISIBLE)) ok(c == 0x0000ff00, "got %#x.\n", c); + + hr = IDirectDrawSurface7_SetClipper(surface, NULL); + ok(hr == DD_OK, "got %#lx.\n", hr); + clear_surface(surface, 0); +} + +static void test_clipper_in_exclusive_fullscreen(void) +{ + static const struct + { + DWORD style; + BOOL parent; + } + tests[] = + { + { WS_POPUP }, + { WS_POPUP, TRUE }, + { WS_CHILD, TRUE }, + { WS_OVERLAPPED }, + { WS_CHILD | WS_VISIBLE, TRUE }, + { WS_POPUP | WS_VISIBLE }, + }; + IDirectDrawSurface7 *primary, *offscreen; + IDirectDrawClipper *clipper, *clipper2; + DDSURFACEDESC2 surface_desc; + HWND window, clip_window; + IDirectDraw7 *ddraw; + RGNDATA *rgn_data; + DWORD ret, style; + RECT window_rect; + ULONG refcount; + unsigned int i; + HRESULT hr; + HRGN rgn; + + if (!(ddraw = create_ddraw())) + { + skip("Failed to create ddraw, skipping test.\n"); + return; + } + hr = IDirectDraw7_CreateClipper(ddraw, 0, &clipper, NULL); + ok(hr == DD_OK, "got %#lx.\n", hr); + + hr = IDirectDraw7_CreateClipper(ddraw, 0, &clipper2, NULL); + ok(hr == DD_OK, "got %#lx.\n", hr); + + window = CreateWindowA("static", "ddraw_fullscreen", WS_POPUP | WS_VISIBLE, 0, 0, 640, 480, NULL, NULL, NULL, NULL); + pump_messages(); + hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); + ok(hr == DD_OK, "got %#lx.\n", hr); + pump_messages(); + + rgn = CreateRectRgn(100, 100, 200, 200); + ok(!!rgn, "Failed to create region.\n"); + ret = GetRegionData(rgn, 0, NULL); + rgn_data = malloc(ret); + ret = GetRegionData(rgn, ret, rgn_data); + ok(!!ret, "Failed to get region data.\n"); + DeleteObject(rgn); + hr = IDirectDrawClipper_SetClipList(clipper2, rgn_data, 0); + ok(hr == DD_OK, "got %#lx.\n", hr); + free(rgn_data); + + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS; + surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &primary, NULL); + ok(hr == DD_OK, "got %#lx.\n", hr); + + surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; + surface_desc.dwWidth = 640; + surface_desc.dwHeight = 480; + hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &offscreen, NULL); + ok(hr == DD_OK, "got %#lx.\n", hr); + + for (i = 0; i < ARRAY_SIZE(tests); ++i) + { + winetest_push_context("test %u", i); + style = tests[i].style; + clip_window = CreateWindowA("static", "ddraw_clip", style, 100, 100, 100, 100, + tests[i].parent ? window : NULL, NULL, NULL, NULL); + ok(!!clip_window, "got error %ld.\n", GetLastError()); + pump_messages(); + + GetWindowRect(clip_window, &window_rect); + hr = IDirectDrawClipper_SetHWnd(clipper, 0, clip_window); + ok(hr == DD_OK, "got %#lx.\n", hr); + + hr = IDirectDrawClipper_GetClipList(clipper, NULL, NULL, &ret); + ok(hr == DD_OK, "got %#lx.\n", hr); + rgn_data = malloc(ret); + hr = IDirectDrawClipper_GetClipList(clipper, NULL, rgn_data, &ret); + ok(hr == DD_OK, "got %#lx.\n", hr); + ok(rgn_data->rdh.dwSize == sizeof(rgn_data->rdh), "Got unexpected structure size %#lx.\n", rgn_data->rdh.dwSize); + ok(rgn_data->rdh.iType == RDH_RECTANGLES, "Got unexpected type %#lx.\n", rgn_data->rdh.iType); + if (style & WS_VISIBLE) + { + ok(rgn_data->rdh.nCount >= 1, "got %lu.\n", rgn_data->rdh.nCount); + if (!(style & WS_CHILD)) + ok(EqualRect(&rgn_data->rdh.rcBound, &window_rect), "got %s, expected %s.\n", + wine_dbgstr_rect(&rgn_data->rdh.rcBound), wine_dbgstr_rect(&window_rect)); + } + else + { + ok(!rgn_data->rdh.nCount, "got %lu.\n", rgn_data->rdh.nCount); + } + free(rgn_data); + + winetest_push_context("primary"); + check_surface_clipper(primary, clipper, clipper2, &window_rect, style); + winetest_pop_context(); + + winetest_push_context("offscreen"); + check_surface_clipper(offscreen, clipper, clipper2, &window_rect, style); + winetest_pop_context(); + + hr = IDirectDrawClipper_SetHWnd(clipper, 0, NULL); + ok(hr == DD_OK, "got %#lx.\n", hr); + DestroyWindow(clip_window); + pump_messages(); + winetest_pop_context(); + } + + IDirectDrawClipper_Release(clipper); + refcount = IDirectDrawSurface7_Release(offscreen); + ok(!refcount, "Got unexpected refcount %lu.\n", refcount); + refcount = IDirectDrawSurface7_Release(primary); + ok(!refcount, "Got unexpected refcount %lu.\n", refcount); + + IDirectDraw7_Release(ddraw); + DestroyWindow(window); + pump_messages(); +} + START_TEST(ddraw7) { DDDEVICEIDENTIFIER2 identifier; @@ -21133,4 +21316,5 @@ START_TEST(ddraw7) test_sysmem_x_channel(); test_yuv_blit(); test_blit_to_self(); + test_clipper_in_exclusive_fullscreen(); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10723
From: Paul Gofman <pgofman@codeweavers.com> --- dlls/ddraw/surface.c | 18 +++++++++--------- dlls/ddraw/tests/ddraw1.c | 9 +++++++-- dlls/ddraw/tests/ddraw2.c | 9 +++++++-- dlls/ddraw/tests/ddraw4.c | 9 +++++++-- dlls/ddraw/tests/ddraw7.c | 9 +++++++-- 5 files changed, 37 insertions(+), 17 deletions(-) diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index e6ed79afccf..139bf45921d 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -1647,7 +1647,14 @@ static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, cons SetRectEmpty(&src_rect); } - if (!dst_surface->clipper) + if (dst_surface->clipper && !ddraw_clipper_is_valid(dst_surface->clipper)) + { + FIXME("Attempting to blit with an invalid clipper.\n"); + return DDERR_INVALIDPARAMS; + } + + if (!dst_surface->clipper || (dst_surface->ddraw->cooperative_level & DDSCL_EXCLUSIVE + && dst_surface->clipper->window)) { if (src_surface && src_surface->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) hr = ddraw_surface_update_frontbuffer(src_surface, &src_rect, TRUE, 0); @@ -1659,12 +1666,6 @@ static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, cons return hr; } - if (!ddraw_clipper_is_valid(dst_surface->clipper)) - { - FIXME("Attempting to blit with an invalid clipper.\n"); - return DDERR_INVALIDPARAMS; - } - scale_x = (float)(src_rect.right - src_rect.left) / (float)(dst_rect.right - dst_rect.left); scale_y = (float)(src_rect.bottom - src_rect.top) / (float)(dst_rect.bottom - dst_rect.top); @@ -4644,9 +4645,8 @@ static HRESULT WINAPI ddraw_surface7_SetClipper(IDirectDrawSurface7 *iface, if ((This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) && This->ddraw->wined3d_swapchain) { clipWindow = NULL; - if(clipper) { + if (clipper && !(This->ddraw->cooperative_level & DDSCL_EXCLUSIVE)) IDirectDrawClipper_GetHWnd(iclipper, &clipWindow); - } if (clipWindow) { diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index 594baee6ff9..b632354f88b 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -16426,9 +16426,9 @@ static void check_surface_clipper(IDirectDrawSurface *surface, IDirectDrawClippe ok(hr == DD_OK, "got %#lx.\n", hr); c = get_surface_color(surface, window_rect->left + 1, window_rect->top + 1); - todo_wine_if(!(style & WS_VISIBLE)) ok(c == 0x0000ff00, "got %#x.\n", c); + ok(c == 0x0000ff00, "got %#x.\n", c); c = get_surface_color(surface, 0, 0); - todo_wine_if((style & (WS_CHILD | WS_VISIBLE)) != (WS_CHILD | WS_VISIBLE)) ok(c == 0x0000ff00, "got %#x.\n", c); + ok(c == 0x0000ff00, "got %#x.\n", c); hr = IDirectDrawSurface_SetClipper(surface, NULL); ok(hr == DD_OK, "got %#lx.\n", hr); @@ -16477,6 +16477,8 @@ static void test_clipper_in_exclusive_fullscreen(void) window = CreateWindowA("static", "ddraw_fullscreen", WS_POPUP | WS_VISIBLE, 0, 0, 640, 480, NULL, NULL, NULL, NULL); pump_messages(); + hr = IDirectDraw_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL); + ok(hr == DD_OK, "got %#lx.\n", hr); hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); ok(hr == DD_OK, "got %#lx.\n", hr); pump_messages(); @@ -16554,7 +16556,10 @@ static void test_clipper_in_exclusive_fullscreen(void) winetest_pop_context(); } + hr = IDirectDraw_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL); + ok(hr == DD_OK, "got %#lx.\n", hr); IDirectDrawClipper_Release(clipper); + IDirectDrawClipper_Release(clipper2); refcount = IDirectDrawSurface_Release(offscreen); ok(!refcount, "Got unexpected refcount %lu.\n", refcount); refcount = IDirectDrawSurface_Release(primary); diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c index ebbc20aacac..def4b26626f 100644 --- a/dlls/ddraw/tests/ddraw2.c +++ b/dlls/ddraw/tests/ddraw2.c @@ -17497,9 +17497,9 @@ static void check_surface_clipper(IDirectDrawSurface *surface, IDirectDrawClippe ok(hr == DD_OK, "got %#lx.\n", hr); c = get_surface_color(surface, window_rect->left + 1, window_rect->top + 1); - todo_wine_if(!(style & WS_VISIBLE)) ok(c == 0x0000ff00, "got %#x.\n", c); + ok(c == 0x0000ff00, "got %#x.\n", c); c = get_surface_color(surface, 0, 0); - todo_wine_if((style & (WS_CHILD | WS_VISIBLE)) != (WS_CHILD | WS_VISIBLE)) ok(c == 0x0000ff00, "got %#x.\n", c); + ok(c == 0x0000ff00, "got %#x.\n", c); hr = IDirectDrawSurface_SetClipper(surface, NULL); ok(hr == DD_OK, "got %#lx.\n", hr); @@ -17548,6 +17548,8 @@ static void test_clipper_in_exclusive_fullscreen(void) window = CreateWindowA("static", "ddraw_fullscreen", WS_POPUP | WS_VISIBLE, 0, 0, 640, 480, NULL, NULL, NULL, NULL); pump_messages(); + hr = IDirectDraw2_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL); + ok(hr == DD_OK, "got %#lx.\n", hr); hr = IDirectDraw2_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); ok(hr == DD_OK, "got %#lx.\n", hr); pump_messages(); @@ -17625,7 +17627,10 @@ static void test_clipper_in_exclusive_fullscreen(void) winetest_pop_context(); } + hr = IDirectDraw2_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL); + ok(hr == DD_OK, "got %#lx.\n", hr); IDirectDrawClipper_Release(clipper); + IDirectDrawClipper_Release(clipper2); refcount = IDirectDrawSurface_Release(offscreen); ok(!refcount, "Got unexpected refcount %lu.\n", refcount); refcount = IDirectDrawSurface_Release(primary); diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c index e2fa4738cbc..8710c8926a5 100644 --- a/dlls/ddraw/tests/ddraw4.c +++ b/dlls/ddraw/tests/ddraw4.c @@ -20596,9 +20596,9 @@ static void check_surface_clipper(IDirectDrawSurface4 *surface, IDirectDrawClipp ok(hr == DD_OK, "got %#lx.\n", hr); c = get_surface_color(surface, window_rect->left + 1, window_rect->top + 1); - todo_wine_if(!(style & WS_VISIBLE)) ok(c == 0x0000ff00, "got %#x.\n", c); + ok(c == 0x0000ff00, "got %#x.\n", c); c = get_surface_color(surface, 0, 0); - todo_wine_if((style & (WS_CHILD | WS_VISIBLE)) != (WS_CHILD | WS_VISIBLE)) ok(c == 0x0000ff00, "got %#x.\n", c); + ok(c == 0x0000ff00, "got %#x.\n", c); hr = IDirectDrawSurface4_SetClipper(surface, NULL); ok(hr == DD_OK, "got %#lx.\n", hr); @@ -20647,6 +20647,8 @@ static void test_clipper_in_exclusive_fullscreen(void) window = CreateWindowA("static", "ddraw_fullscreen", WS_POPUP | WS_VISIBLE, 0, 0, 640, 480, NULL, NULL, NULL, NULL); pump_messages(); + hr = IDirectDraw4_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL); + ok(hr == DD_OK, "got %#lx.\n", hr); hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); ok(hr == DD_OK, "got %#lx.\n", hr); pump_messages(); @@ -20724,7 +20726,10 @@ static void test_clipper_in_exclusive_fullscreen(void) winetest_pop_context(); } + hr = IDirectDraw4_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL); + ok(hr == DD_OK, "got %#lx.\n", hr); IDirectDrawClipper_Release(clipper); + IDirectDrawClipper_Release(clipper2); refcount = IDirectDrawSurface4_Release(offscreen); ok(!refcount, "Got unexpected refcount %lu.\n", refcount); refcount = IDirectDrawSurface4_Release(primary); diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index eb35cfa6792..9a68421af4e 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -20994,9 +20994,9 @@ static void check_surface_clipper(IDirectDrawSurface7 *surface, IDirectDrawClipp ok(hr == DD_OK, "got %#lx.\n", hr); c = get_surface_color(surface, window_rect->left + 1, window_rect->top + 1); - todo_wine_if(!(style & WS_VISIBLE)) ok(c == 0x0000ff00, "got %#x.\n", c); + ok(c == 0x0000ff00, "got %#x.\n", c); c = get_surface_color(surface, 0, 0); - todo_wine_if((style & (WS_CHILD | WS_VISIBLE)) != (WS_CHILD | WS_VISIBLE)) ok(c == 0x0000ff00, "got %#x.\n", c); + ok(c == 0x0000ff00, "got %#x.\n", c); hr = IDirectDrawSurface7_SetClipper(surface, NULL); ok(hr == DD_OK, "got %#lx.\n", hr); @@ -21045,6 +21045,8 @@ static void test_clipper_in_exclusive_fullscreen(void) window = CreateWindowA("static", "ddraw_fullscreen", WS_POPUP | WS_VISIBLE, 0, 0, 640, 480, NULL, NULL, NULL, NULL); pump_messages(); + hr = IDirectDraw7_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL); + ok(hr == DD_OK, "got %#lx.\n", hr); hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); ok(hr == DD_OK, "got %#lx.\n", hr); pump_messages(); @@ -21122,7 +21124,10 @@ static void test_clipper_in_exclusive_fullscreen(void) winetest_pop_context(); } + hr = IDirectDraw7_SetCooperativeLevel(ddraw, NULL, DDSCL_NORMAL); + ok(hr == DD_OK, "got %#lx.\n", hr); IDirectDrawClipper_Release(clipper); + IDirectDrawClipper_Release(clipper2); refcount = IDirectDrawSurface7_Release(offscreen); ok(!refcount, "Got unexpected refcount %lu.\n", refcount); refcount = IDirectDrawSurface7_Release(primary); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10723
v5: * add a patch which fixes CI test failure which happens in ddraw2 when the new test is after test_d3d_state_reset(). -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10723#note_137518
I tested this with fswindow from the dx7 SDK and Rollercoaster Tycoon 2 (of bug 53751 fame), and both work ok with this MR applied. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10723#note_137571
Ugh, gitlab ate a comment I spent way too long writing... Sorry for the delay. Among other things, this is a touchy area and I wanted to make sure I understood the problem completely. The tests don't pass on Helen (Geforce 2 MX, not that I expect it to matter). It appears that Windows 98 does respect the clipper in this scenario, including visually. The game in question is from 2019, and probably doesn't even work on any Windows version with that behaviour. I think the prudent thing to do is take this change anyway. I still want the tests to pass on Helen, though, so I've sent !10842, which removes the tests that don't pass, adds a couple comments, and makes a change to SetClipper() which I feel is a bit more idiomatic. Please let me know if you have concerns with it. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10723#note_139165
This merge request was closed by Paul Gofman. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10723
participants (4)
-
Elizabeth Figura (@zfigura) -
Paul Gofman -
Paul Gofman (@gofman) -
Stefan Dösinger (@stefan)