From: Zhiyi Zhang Subject: [PATCH v3 1/2] ddraw/tests: Test cursor clipping. Message-Id: <33b15a27-8602-7cef-0962-46da7befa9c9@codeweavers.com> Date: Thu, 9 Apr 2020 15:31:42 +0800 Signed-off-by: Zhiyi Zhang --- v3: Add tests for DirectDraw version 1, 2 and 4. Supersede 183019 and 183021. dlls/ddraw/tests/ddraw1.c | 166 ++++++++++++++++++++++++++++++++++ dlls/ddraw/tests/ddraw2.c | 166 ++++++++++++++++++++++++++++++++++ dlls/ddraw/tests/ddraw4.c | 166 ++++++++++++++++++++++++++++++++++ dlls/ddraw/tests/ddraw7.c | 166 ++++++++++++++++++++++++++++++++++ dlls/ddraw/tests/ddrawmodes.c | 13 +-- 5 files changed, 665 insertions(+), 12 deletions(-) diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index 96e5555d9fc..2554a109487 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -88,6 +88,32 @@ static BOOL compare_color(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff) && compare_uint((c1 >> 24) & 0xff, (c2 >> 24) & 0xff, max_diff); } +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(IDirectDraw *ddraw, DDDEVICEIDENTIFIER *identifier) { IDirectDraw4 *ddraw4; @@ -13207,6 +13233,145 @@ static void test_d32_support(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(DDSURFACEDESC *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; + DDSURFACEDESC surface_desc; + RECT rect, clip_rect; + IDirectDraw *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 = IDirectDraw_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 = IDirectDraw_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 = IDirectDraw_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 = set_display_mode(ddraw, param.new_width, param.new_height); + 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 = IDirectDraw_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 = IDirectDraw_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 = set_display_mode(ddraw, param.new_width, param.new_height); + 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 = IDirectDraw_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 = IDirectDraw_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: + IDirectDraw_Release(ddraw); + DestroyWindow(window); +} + START_TEST(ddraw1) { DDDEVICEIDENTIFIER identifier; @@ -13319,4 +13484,5 @@ START_TEST(ddraw1) test_clipper_refcount(); test_caps(); test_d32_support(); + test_cursor_clipping(); } diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c index 389f33408fe..236230ef775 100644 --- a/dlls/ddraw/tests/ddraw2.c +++ b/dlls/ddraw/tests/ddraw2.c @@ -89,6 +89,32 @@ static BOOL compare_color(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff) && compare_uint((c1 >> 24) & 0xff, (c2 >> 24) & 0xff, max_diff); } +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(IDirectDraw2 *ddraw, DDDEVICEIDENTIFIER *identifier) { IDirectDraw4 *ddraw4; @@ -14048,6 +14074,145 @@ static void test_d32_support(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(DDSURFACEDESC *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; + DDSURFACEDESC surface_desc; + RECT rect, clip_rect; + IDirectDraw2 *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 = IDirectDraw2_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 = IDirectDraw2_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 = IDirectDraw2_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 = set_display_mode(ddraw, param.new_width, param.new_height); + 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 = IDirectDraw2_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 = IDirectDraw2_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 = set_display_mode(ddraw, param.new_width, param.new_height); + 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 = IDirectDraw2_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 = IDirectDraw2_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: + IDirectDraw2_Release(ddraw); + DestroyWindow(window); +} + START_TEST(ddraw2) { DDDEVICEIDENTIFIER identifier; @@ -14167,4 +14332,5 @@ START_TEST(ddraw2) test_clipper_refcount(); test_caps(); test_d32_support(); + test_cursor_clipping(); } diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c index 7c53c7e2e97..4d1871e2100 100644 --- a/dlls/ddraw/tests/ddraw4.c +++ b/dlls/ddraw/tests/ddraw4.c @@ -95,6 +95,32 @@ static BOOL compare_color(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff) && compare_uint((c1 >> 24) & 0xff, (c2 >> 24) & 0xff, max_diff); } +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(IDirectDraw4 *ddraw, DDDEVICEIDENTIFIER *identifier) { HRESULT hr; @@ -17073,6 +17099,145 @@ static void test_surface_format_conversion_alpha(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; + IDirectDraw4 *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 = IDirectDraw4_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 = IDirectDraw4_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 = IDirectDraw4_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 = set_display_mode(ddraw, param.new_width, param.new_height); + 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 = IDirectDraw4_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 = IDirectDraw4_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 = set_display_mode(ddraw, param.new_width, param.new_height); + 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 = IDirectDraw4_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 = IDirectDraw4_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: + IDirectDraw4_Release(ddraw); + DestroyWindow(window); +} + START_TEST(ddraw4) { DDDEVICEIDENTIFIER identifier; @@ -17208,4 +17373,5 @@ START_TEST(ddraw4) test_caps(); test_d32_support(); test_surface_format_conversion_alpha(); + test_cursor_clipping(); } diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 9e50c1a7bc3..10c3204683e 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,145 @@ 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 = set_display_mode(ddraw, param.new_width, param.new_height); + 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 = set_display_mode(ddraw, param.new_width, param.new_height); + 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 +17617,5 @@ START_TEST(ddraw7) test_d32_support(); test_surface_format_conversion_alpha(); test_compressed_surface_stretch(); + test_cursor_clipping(); } diff --git a/dlls/ddraw/tests/ddrawmodes.c b/dlls/ddraw/tests/ddrawmodes.c index f5b0666cfbe..638ff374012 100644 --- a/dlls/ddraw/tests/ddrawmodes.c +++ b/dlls/ddraw/tests/ddrawmodes.c @@ -558,7 +558,7 @@ static void setdisplaymode(int i) ok(DD_OK==rc || DDERR_UNSUPPORTED==rc,"SetDisplayMode returned: %x\n",rc); if (rc == DD_OK) { - RECT r, scrn, test, virt; + RECT scrn, test, virt; SetRect(&virt, 0, 0, GetSystemMetrics(SM_CXVIRTUALSCREEN), GetSystemMetrics(SM_CYVIRTUALSCREEN)); OffsetRect(&virt, GetSystemMetrics(SM_XVIRTUALSCREEN), GetSystemMetrics(SM_YVIRTUALSCREEN)); @@ -598,17 +598,6 @@ static void setdisplaymode(int i) ok(DD_OK==rc, "SetDisplayMode returned: %x\n",rc); } } - ok(GetClipCursor(&r), "GetClipCursor() failed\n"); - /* ddraw sets clip rect here to the screen size, even for - multiple monitors */ - ok(EqualRect(&r, &scrn), "Invalid clip rect: (%d %d) x (%d %d)\n", - r.left, r.top, r.right, r.bottom); - - ok(ClipCursor(NULL), "ClipCursor() failed\n"); - ok(GetClipCursor(&r), "GetClipCursor() failed\n"); - ok(EqualRect(&r, &virt), "Invalid clip rect: (%d %d) x (%d %d)\n", - r.left, r.top, r.right, r.bottom); - rc = IDirectDraw_RestoreDisplayMode(lpDD); ok(DD_OK==rc,"RestoreDisplayMode returned: %x\n",rc); } -- 2.20.1