From: Zhiyi Zhang Subject: [PATCH v2 3/5] ddraw/tests: Test cursor clipping. Message-Id: <0c1815e2-ab57-e6be-1883-786657f22773@codeweavers.com> Date: Wed, 8 Apr 2020 18:01:08 +0800 Signed-off-by: Zhiyi Zhang --- dlls/ddraw/tests/ddraw7.c | 168 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 9e50c1a7bc3..a90fe51a508 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -108,6 +108,32 @@ static ULONG get_refcount(IUnknown *iface) return IUnknown_Release(iface); } +static void get_virtual_rect(RECT *rect) +{ + rect->left = GetSystemMetrics(SM_XVIRTUALSCREEN); + rect->top = GetSystemMetrics(SM_YVIRTUALSCREEN); + rect->right = rect->left + GetSystemMetrics(SM_CXVIRTUALSCREEN); + rect->bottom = rect->top + GetSystemMetrics(SM_CYVIRTUALSCREEN); +} + +/* Try to make sure pending X events have been processed before continuing */ +static void flush_events(void) +{ + int diff = 200; + DWORD time; + MSG msg; + + time = GetTickCount() + diff; + while (diff > 0) + { + if (MsgWaitForMultipleObjects(0, NULL, FALSE, 100, QS_ALLINPUT) == WAIT_TIMEOUT) + break; + while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) + DispatchMessageA(&msg); + diff = time - GetTickCount(); + } +} + static BOOL ddraw_get_identifier(IDirectDraw7 *ddraw, DDDEVICEIDENTIFIER2 *identifier) { HRESULT hr; @@ -17302,6 +17328,147 @@ static void test_compressed_surface_stretch(void) DestroyWindow(window); } +struct find_different_mode_param +{ + unsigned int old_width; + unsigned int old_height; + unsigned int new_width; + unsigned int new_height; +}; + +static HRESULT CALLBACK find_different_mode_callback(DDSURFACEDESC2 *surface_desc, void *context) +{ + struct find_different_mode_param *param = context; + + if (U1(U4(*surface_desc).ddpfPixelFormat).dwRGBBitCount != registry_mode.dmBitsPerPel) + return DDENUMRET_OK; + + if (surface_desc->dwWidth != param->old_width && surface_desc->dwHeight != param->old_height) + { + param->new_width = surface_desc->dwWidth; + param->new_height = surface_desc->dwHeight; + return DDENUMRET_CANCEL; + } + + return DDENUMRET_OK; +} + +static void test_cursor_clipping(void) +{ + struct find_different_mode_param param; + DDSURFACEDESC2 surface_desc; + RECT rect, clip_rect; + IDirectDraw7 *ddraw; + HWND window; + HRESULT hr; + + window = create_window(); + ok(!!window, "Failed to create a window.\n"); + ddraw = create_ddraw(); + ok(!!ddraw, "Failed to create a ddraw object.\n"); + + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + hr = IDirectDraw7_GetDisplayMode(ddraw, &surface_desc); + ok(hr == DD_OK, "GetDisplayMode failed, hr %#x.\n", hr); + + memset(¶m, 0, sizeof(param)); + param.old_width = surface_desc.dwWidth; + param.old_height = surface_desc.dwHeight; + hr = IDirectDraw7_EnumDisplayModes(ddraw, 0, NULL, ¶m, find_different_mode_callback); + ok(hr == DD_OK, "EnumDisplayModes failed, hr %#x.\n", hr); + if (!(param.new_width && param.new_height)) + { + skip("Failed to find a different mode than %ux%u.\n", param.old_width, param.old_height); + goto done; + } + + ok(ClipCursor(NULL), "ClipCursor failed, error %#x.\n", GetLastError()); + get_virtual_rect(&rect); + ok(GetClipCursor(&clip_rect), "GetClipCursor failed, error %#x.\n", GetLastError()); + ok(EqualRect(&clip_rect, &rect), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect), + wine_dbgstr_rect(&clip_rect)); + + /* Set cooperative level to normal */ + hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL); + ok(hr == DD_OK, "SetCooperativeLevel failed, hr %#x.\n", hr); + flush_events(); + get_virtual_rect(&rect); + ok(GetClipCursor(&clip_rect), "GetClipCursor failed, error %#x.\n", GetLastError()); + ok(EqualRect(&clip_rect, &rect), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect), + wine_dbgstr_rect(&clip_rect)); + + hr = IDirectDraw7_SetDisplayMode(ddraw, param.new_width, param.new_height, + registry_mode.dmBitsPerPel, 0, 0); + ok(hr == DD_OK || hr == DDERR_UNSUPPORTED, "SetDisplayMode failed, hr %#x.\n", hr); + if (FAILED(hr)) + { + win_skip("SetDisplayMode failed, hr %#x.\n", hr); + goto done; + } + flush_events(); + get_virtual_rect(&rect); + ok(GetClipCursor(&clip_rect), "GetClipCursor failed, error %#x.\n", GetLastError()); + todo_wine_if(!EqualRect(&clip_rect, &rect)) + ok(EqualRect(&clip_rect, &rect), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect), + wine_dbgstr_rect(&clip_rect)); + + hr = IDirectDraw7_RestoreDisplayMode(ddraw); + ok(hr == DD_OK, "RestoreDisplayMode failed, hr %#x.\n", hr); + flush_events(); + get_virtual_rect(&rect); + ok(GetClipCursor(&clip_rect), "GetClipCursor failed, error %#x.\n", GetLastError()); + todo_wine_if(GetSystemMetrics(SM_CMONITORS) > 1) + ok(EqualRect(&clip_rect, &rect), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect), + wine_dbgstr_rect(&clip_rect)); + + /* Switch to full screen cooperative level */ + hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); + ok(hr == DD_OK, "SetCooperativeLevel failed, hr %#x.\n", hr); + flush_events(); + SetRect(&rect, 0, 0, param.old_width, param.old_height); + ok(GetClipCursor(&clip_rect), "GetClipCursor failed, error %#x.\n", GetLastError()); + ok(EqualRect(&clip_rect, &rect), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect), + wine_dbgstr_rect(&clip_rect)); + + hr = IDirectDraw7_SetDisplayMode(ddraw, param.new_width, param.new_height, + registry_mode.dmBitsPerPel, 0, 0); + ok(hr == DD_OK || hr == DDERR_UNSUPPORTED, "SetDisplayMode failed, hr %#x.\n", hr); + if (FAILED(hr)) + { + win_skip("SetDisplayMode failed, hr %#x.\n", hr); + goto done; + } + flush_events(); + SetRect(&rect, 0, 0, param.new_width, param.new_height); + ok(GetClipCursor(&clip_rect), "GetClipCursor failed, error %#x.\n", GetLastError()); + ok(EqualRect(&clip_rect, &rect), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect), + wine_dbgstr_rect(&clip_rect)); + + /* Restore display mode */ + hr = IDirectDraw7_RestoreDisplayMode(ddraw); + ok(hr == DD_OK, "RestoreDisplayMode failed, hr %#x.\n", hr); + flush_events(); + SetRect(&rect, 0, 0, param.old_width, param.old_height); + ok(GetClipCursor(&clip_rect), "GetClipCursor failed, error %#x.\n", GetLastError()); + ok(EqualRect(&clip_rect, &rect), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect), + wine_dbgstr_rect(&clip_rect)); + + /* Switch to normal cooperative level */ + hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL); + ok(hr == DD_OK, "SetCooperativeLevel failed, hr %#x.\n", hr); + flush_events(); + get_virtual_rect(&rect); + ok(GetClipCursor(&clip_rect), "GetClipCursor failed, error %#x.\n", GetLastError()); + todo_wine_if(GetSystemMetrics(SM_CMONITORS) > 1) + ok(EqualRect(&clip_rect, &rect), "Expect clip rect %s, got %s.\n", wine_dbgstr_rect(&rect), + wine_dbgstr_rect(&clip_rect)); + +done: + IDirectDraw7_Release(ddraw); + DestroyWindow(window); +} + START_TEST(ddraw7) { DDDEVICEIDENTIFIER2 identifier; @@ -17452,4 +17619,5 @@ START_TEST(ddraw7) test_d32_support(); test_surface_format_conversion_alpha(); test_compressed_surface_stretch(); + test_cursor_clipping(); } -- 2.20.1