From: Zhiyi Zhang Subject: [PATCH v3 2/2] wined3d: Do not clip the cursor after changing display modes. Message-Id: Date: Thu, 9 Apr 2020 15:33:05 +0800 DirectDraw should clip the cursor to the primary monitor only when the cooperative level is DDSCL_EXCLUSIVE. For Direct3D 8, 9 and DXGI, changing display modes shouldn't clip the cursor as tests showed. Signed-off-by: Zhiyi Zhang --- dlls/d3d8/tests/device.c | 2 -- dlls/d3d9/tests/device.c | 2 -- dlls/ddraw/ddraw.c | 31 +++++++++++++++++++++++++++---- dlls/ddraw/tests/ddraw1.c | 3 --- dlls/ddraw/tests/ddraw2.c | 3 --- dlls/ddraw/tests/ddraw4.c | 3 --- dlls/ddraw/tests/ddraw7.c | 3 --- dlls/dxgi/tests/dxgi.c | 2 -- dlls/wined3d/directx.c | 5 ----- dlls/wined3d/swapchain.c | 1 - 10 files changed, 27 insertions(+), 28 deletions(-) diff --git a/dlls/d3d8/tests/device.c b/dlls/d3d8/tests/device.c index ead5f47bf14..b9d838e5cd4 100644 --- a/dlls/d3d8/tests/device.c +++ b/dlls/d3d8/tests/device.c @@ -10152,7 +10152,6 @@ static void test_cursor_clipping(void) get_virtual_rect(&virtual_rect); ok(GetClipCursor(&clip_rect), "Adapter %u: GetClipCursor failed, error %#x.\n", adapter_idx, GetLastError()); - todo_wine_if(!EqualRect(&clip_rect, &virtual_rect)) ok(EqualRect(&clip_rect, &virtual_rect), "Adapter %u: Expect clip rect %s, got %s.\n", adapter_idx, wine_dbgstr_rect(&virtual_rect), wine_dbgstr_rect(&clip_rect)); @@ -10161,7 +10160,6 @@ static void test_cursor_clipping(void) get_virtual_rect(&virtual_rect); ok(GetClipCursor(&clip_rect), "Adapter %u: GetClipCursor failed, error %#x.\n", adapter_idx, GetLastError()); - todo_wine_if(!EqualRect(&clip_rect, &virtual_rect)) ok(EqualRect(&clip_rect, &virtual_rect), "Adapter %u: Expect clip rect %s, got %s.\n", adapter_idx, wine_dbgstr_rect(&virtual_rect), wine_dbgstr_rect(&clip_rect)); } diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c index b84a35714cd..c65f0cd04da 100644 --- a/dlls/d3d9/tests/device.c +++ b/dlls/d3d9/tests/device.c @@ -13893,7 +13893,6 @@ static void test_cursor_clipping(void) get_virtual_rect(&virtual_rect); ok(GetClipCursor(&clip_rect), "Adapter %u: GetClipCursor failed, error %#x.\n", adapter_idx, GetLastError()); - todo_wine_if(!EqualRect(&clip_rect, &virtual_rect)) ok(EqualRect(&clip_rect, &virtual_rect), "Adapter %u: Expect clip rect %s, got %s.\n", adapter_idx, wine_dbgstr_rect(&virtual_rect), wine_dbgstr_rect(&clip_rect)); @@ -13902,7 +13901,6 @@ static void test_cursor_clipping(void) get_virtual_rect(&virtual_rect); ok(GetClipCursor(&clip_rect), "Adapter %u: GetClipCursor failed, error %#x.\n", adapter_idx, GetLastError()); - todo_wine_if(!EqualRect(&clip_rect, &virtual_rect)) ok(EqualRect(&clip_rect, &virtual_rect), "Adapter %u: Expect clip rect %s, got %s.\n", adapter_idx, wine_dbgstr_rect(&virtual_rect), wine_dbgstr_rect(&clip_rect)); } diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index db7fc2c9486..95e9fba9011 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -665,6 +665,8 @@ static HRESULT ddraw_create_swapchain(struct ddraw *ddraw, HWND window, BOOL win static HRESULT WINAPI ddraw7_RestoreDisplayMode(IDirectDraw7 *iface) { struct ddraw *ddraw = impl_from_IDirectDraw7(iface); + struct wined3d_display_mode mode; + RECT clip_rect; HRESULT hr; TRACE("iface %p.\n", iface); @@ -684,7 +686,15 @@ static HRESULT WINAPI ddraw7_RestoreDisplayMode(IDirectDraw7 *iface) } if (SUCCEEDED(hr = wined3d_output_set_display_mode(ddraw->wined3d_output, NULL))) + { ddraw->flags &= ~DDRAW_RESTORE_MODE; + if (ddraw->cooperative_level & DDSCL_EXCLUSIVE && + SUCCEEDED(hr = wined3d_output_get_display_mode(ddraw->wined3d_output, &mode, NULL))) + { + SetRect(&clip_rect, 0, 0, mode.width, mode.height); + ClipCursor(&clip_rect); + } + } InterlockedCompareExchange(&ddraw->device_state, DDRAW_DEVICE_STATE_NOT_RESTORED, DDRAW_DEVICE_STATE_OK); @@ -768,6 +778,7 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window, struct wined3d_rendertarget_view *rtv = NULL, *dsv = NULL; struct wined3d_stateblock *stateblock; BOOL restore_state = FALSE; + RECT clip_rect; HRESULT hr; TRACE("ddraw %p, window %p, flags %#x, restore_mode_on_normal %x.\n", ddraw, window, cooplevel, @@ -942,12 +953,11 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window, wined3d_stateblock_decref(stateblock); } - if (!(cooplevel & DDSCL_EXCLUSIVE) && (ddraw->cooperative_level & DDSCL_EXCLUSIVE) - && restore_mode_on_normal) + if (!(cooplevel & DDSCL_EXCLUSIVE) && (ddraw->cooperative_level & DDSCL_EXCLUSIVE)) { - hr = ddraw7_RestoreDisplayMode(&ddraw->IDirectDraw7_iface); - if (FAILED(hr)) + if (restore_mode_on_normal && FAILED(ddraw7_RestoreDisplayMode(&ddraw->IDirectDraw7_iface))) ERR("RestoreDisplayMode failed\n"); + ClipCursor(NULL); } if ((ddraw->cooperative_level & DDSCL_EXCLUSIVE) @@ -965,6 +975,12 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window, } } + if (cooplevel & DDSCL_EXCLUSIVE) + { + SetRect(&clip_rect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); + ClipCursor(&clip_rect); + } + /* Unhandled flags */ if (cooplevel & DDSCL_ALLOWREBOOT) WARN("Unhandled flag DDSCL_ALLOWREBOOT, harmless\n"); @@ -1059,6 +1075,7 @@ static HRESULT WINAPI ddraw7_SetDisplayMode(IDirectDraw7 *iface, DWORD width, DW struct ddraw *ddraw = impl_from_IDirectDraw7(iface); struct wined3d_display_mode mode; enum wined3d_format_id format; + RECT clip_rect; HRESULT hr; TRACE("iface %p, width %u, height %u, bpp %u, refresh_rate %u, flags %#x.\n", @@ -1117,6 +1134,12 @@ static HRESULT WINAPI ddraw7_SetDisplayMode(IDirectDraw7 *iface, DWORD width, DW ddrawformat_from_wined3dformat(&ddraw->primary->surface_desc.u4.ddpfPixelFormat, mode.format_id); } ddraw->flags |= DDRAW_RESTORE_MODE; + + if (ddraw->cooperative_level & DDSCL_EXCLUSIVE) + { + SetRect(&clip_rect, 0, 0, width, height); + ClipCursor(&clip_rect); + } } InterlockedCompareExchange(&ddraw->device_state, DDRAW_DEVICE_STATE_NOT_RESTORED, DDRAW_DEVICE_STATE_OK); diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index 2554a109487..62cc87b697a 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -13313,7 +13313,6 @@ static void test_cursor_clipping(void) 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)); @@ -13322,7 +13321,6 @@ static void test_cursor_clipping(void) 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)); @@ -13363,7 +13361,6 @@ static void test_cursor_clipping(void) 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)); diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c index 236230ef775..efa9195c09c 100644 --- a/dlls/ddraw/tests/ddraw2.c +++ b/dlls/ddraw/tests/ddraw2.c @@ -14154,7 +14154,6 @@ static void test_cursor_clipping(void) 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)); @@ -14163,7 +14162,6 @@ static void test_cursor_clipping(void) 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)); @@ -14204,7 +14202,6 @@ static void test_cursor_clipping(void) 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)); diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c index 4d1871e2100..57b51eef451 100644 --- a/dlls/ddraw/tests/ddraw4.c +++ b/dlls/ddraw/tests/ddraw4.c @@ -17179,7 +17179,6 @@ static void test_cursor_clipping(void) 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)); @@ -17188,7 +17187,6 @@ static void test_cursor_clipping(void) 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)); @@ -17229,7 +17227,6 @@ static void test_cursor_clipping(void) 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)); diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 10c3204683e..e44308761b0 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -17408,7 +17408,6 @@ static void test_cursor_clipping(void) 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)); @@ -17417,7 +17416,6 @@ static void test_cursor_clipping(void) 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)); @@ -17458,7 +17456,6 @@ static void test_cursor_clipping(void) 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)); diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index 6e01961a0c0..b5dcd5b0dea 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -6118,7 +6118,6 @@ static void test_cursor_clipping(IUnknown *device, BOOL is_d3d12) ok(GetClipCursor(&clip_rect), "Adapter %u output %u: GetClipCursor failed, error %#x.\n", adapter_idx, output_idx, GetLastError()); - todo_wine_if(!EqualRect(&clip_rect, &virtual_rect)) ok(EqualRect(&clip_rect, &virtual_rect), "Adapter %u output %u: Expect clip rect %s, got %s.\n", adapter_idx, output_idx, wine_dbgstr_rect(&virtual_rect), wine_dbgstr_rect(&clip_rect)); @@ -6139,7 +6138,6 @@ static void test_cursor_clipping(IUnknown *device, BOOL is_d3d12) ok(GetClipCursor(&clip_rect), "Adapter %u output %u: GetClipCursor failed, error %#x.\n", adapter_idx, output_idx, GetLastError()); - todo_wine_if(!EqualRect(&clip_rect, &virtual_rect)) ok(EqualRect(&clip_rect, &virtual_rect), "Adapter %u output %u: Expect clip rect %s, got %s.\n", adapter_idx, output_idx, wine_dbgstr_rect(&virtual_rect), wine_dbgstr_rect(&clip_rect)); diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index cb3e0dd1041..42e1578561f 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -1260,7 +1260,6 @@ HRESULT CDECL wined3d_output_set_display_mode(struct wined3d_output *output, const struct wined3d_display_mode *mode) { DEVMODEW new_mode, current_mode; - RECT clip_rc; LONG ret; enum wined3d_format_id new_format_id; @@ -1341,10 +1340,6 @@ HRESULT CDECL wined3d_output_set_display_mode(struct wined3d_output *output, /* Store the new values. */ output->screen_format = new_format_id; - /* And finally clip mouse to our screen. */ - SetRect(&clip_rc, 0, 0, new_mode.dmPelsWidth, new_mode.dmPelsHeight); - ClipCursor(&clip_rc); - return WINED3D_OK; } diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index e4cb5a27469..86f8277a27d 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -1067,7 +1067,6 @@ err: if (!output || FAILED(wined3d_output_set_display_mode(output, &swapchain->state.original_mode))) ERR("Failed to restore display mode.\n"); - ClipCursor(NULL); } if (swapchain->back_buffers) -- 2.20.1