From: Stefan Dösinger Subject: [PATCH 6/6] wined3d: Restore the display mode on focus change. Message-Id: <1416342417-15963-6-git-send-email-stefan@codeweavers.com> Date: Tue, 18 Nov 2014 21:26:57 +0100 Setting on activation and deactivation have to be introduced together, otherwise the existing ddraw tests fail. --- dlls/d3d8/tests/device.c | 6 +-- dlls/d3d9/directx.c | 3 ++ dlls/d3d9/tests/d3d9ex.c | 6 +-- dlls/d3d9/tests/device.c | 6 +-- dlls/ddraw/ddraw.c | 2 +- dlls/ddraw/tests/ddraw1.c | 8 ++-- dlls/ddraw/tests/ddraw2.c | 8 ++-- dlls/ddraw/tests/ddraw4.c | 8 ++-- dlls/ddraw/tests/ddraw7.c | 8 ++-- dlls/wined3d/device.c | 4 +- dlls/wined3d/directx.c | 92 +++++++++++++++++++++++++----------------- dlls/wined3d/swapchain.c | 36 ++++++++++++----- dlls/wined3d/wined3d_private.h | 4 +- include/wine/wined3d.h | 1 + 14 files changed, 115 insertions(+), 77 deletions(-) diff --git a/dlls/d3d8/tests/device.c b/dlls/d3d8/tests/device.c index 8dcd163..6244254 100644 --- a/dlls/d3d8/tests/device.c +++ b/dlls/d3d8/tests/device.c @@ -2443,7 +2443,7 @@ static void test_wndproc(void) * an inactive titlebar if reactivated with SetForegroundWindow. Reactivating * the device is difficult, see below. */ SetForegroundWindow(GetDesktopWindow()); - todo_wine ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it.\n", + ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it.\n", expect_messages->message, expect_messages->window); expect_messages = NULL; tmp = GetFocus(); @@ -2462,7 +2462,7 @@ static void test_wndproc(void) ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode); ok(ret, "Failed to get display mode.\n"); - todo_wine ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth + ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth && devmode.dmPelsHeight == registry_mode.dmPelsHeight, "Got unexpect screen size %ux%u.\n", devmode.dmPelsWidth, devmode.dmPelsHeight); @@ -2482,7 +2482,7 @@ static void test_wndproc(void) ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode); ok(ret, "Failed to get display mode.\n"); - todo_wine ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth + ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth && devmode.dmPelsHeight == registry_mode.dmPelsHeight, "Got unexpect screen size %ux%u.\n", devmode.dmPelsWidth, devmode.dmPelsHeight); diff --git a/dlls/d3d9/directx.c b/dlls/d3d9/directx.c index 6280d12..dc36be1 100644 --- a/dlls/d3d9/directx.c +++ b/dlls/d3d9/directx.c @@ -640,6 +640,9 @@ BOOL d3d9_init(struct d3d9 *d3d9, BOOL extended) if (!extended) flags |= WINED3D_VIDMEM_ACCOUNTING; + else + flags |= WINED3D_RESTORE_MODE_ON_ACTIVATE; + d3d9->IDirect3D9Ex_iface.lpVtbl = &d3d9_vtbl; d3d9->refcount = 1; diff --git a/dlls/d3d9/tests/d3d9ex.c b/dlls/d3d9/tests/d3d9ex.c index 06953a3..5f54d5b 100644 --- a/dlls/d3d9/tests/d3d9ex.c +++ b/dlls/d3d9/tests/d3d9ex.c @@ -2031,7 +2031,7 @@ static void test_wndproc(void) * an inactive titlebar if reactivated with SetForegroundWindow. Reactivating * the device is difficult, see below. */ SetForegroundWindow(GetDesktopWindow()); - todo_wine ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n", + ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n", expect_messages->message, expect_messages->window, i); expect_messages = NULL; tmp = GetFocus(); @@ -2043,7 +2043,7 @@ static void test_wndproc(void) ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode); ok(ret, "Failed to get display mode.\n"); - todo_wine ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth + ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth && devmode.dmPelsHeight == registry_mode.dmPelsHeight, "Got unexpect screen size %ux%u.\n", devmode.dmPelsWidth, devmode.dmPelsHeight); @@ -2066,7 +2066,7 @@ static void test_wndproc(void) ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode); ok(ret, "Failed to get display mode.\n"); - todo_wine ok(devmode.dmPelsWidth == d3d_width + ok(devmode.dmPelsWidth == d3d_width && devmode.dmPelsHeight == d3d_height, "Got unexpect screen size %ux%u.\n", devmode.dmPelsWidth, devmode.dmPelsHeight); diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c index d3e8ab8..3fd25d1 100644 --- a/dlls/d3d9/tests/device.c +++ b/dlls/d3d9/tests/device.c @@ -3416,7 +3416,7 @@ static void test_wndproc(void) * an inactive titlebar if reactivated with SetForegroundWindow. Reactivating * the device is difficult, see below. */ SetForegroundWindow(GetDesktopWindow()); - todo_wine ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n", + ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n", expect_messages->message, expect_messages->window, i); expect_messages = NULL; tmp = GetFocus(); @@ -3428,7 +3428,7 @@ static void test_wndproc(void) ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode); ok(ret, "Failed to get display mode.\n"); - todo_wine ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth + ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth && devmode.dmPelsHeight == registry_mode.dmPelsHeight, "Got unexpect screen size %ux%u.\n", devmode.dmPelsWidth, devmode.dmPelsHeight); @@ -3458,7 +3458,7 @@ static void test_wndproc(void) ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode); ok(ret, "Failed to get display mode.\n"); - todo_wine ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth + ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth && devmode.dmPelsHeight == registry_mode.dmPelsHeight, "Got unexpect screen size %ux%u.\n", devmode.dmPelsWidth, devmode.dmPelsHeight); diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index 36eb679..ce9edf6 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -4862,7 +4862,7 @@ HRESULT ddraw_init(struct ddraw *ddraw, enum wined3d_device_type device_type) ddraw->numIfaces = 1; ddraw->ref7 = 1; - flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING; + flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING | WINED3D_RESTORE_MODE_ON_ACTIVATE; if (!(ddraw->wined3d = wined3d_create(flags))) { if (!(ddraw->wined3d = wined3d_create(flags | WINED3D_NO3D))) diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index 6cc139d..6648937 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -2358,17 +2358,17 @@ static void test_coop_level_mode_set(void) expect_messages = exclusive_focus_loss_messages; ret = SetForegroundWindow(GetDesktopWindow()); ok(ret, "Failed to set foreground window.\n"); - todo_wine ok(!expect_messages->message, "Expected message %#x, but didn't receive it.\n", expect_messages->message); + ok(!expect_messages->message, "Expected message %#x, but didn't receive it.\n", expect_messages->message); ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode); ok(ret, "Failed to get display mode.\n"); - todo_wine ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth + ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth && devmode.dmPelsHeight == registry_mode.dmPelsHeight, "Got unexpect screen size %ux%u.\n", devmode.dmPelsWidth, devmode.dmPelsHeight); ShowWindow(window, SW_RESTORE); ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode); ok(ret, "Failed to get display mode.\n"); - todo_wine ok(devmode.dmPelsWidth == param.ddraw_width + ok(devmode.dmPelsWidth == param.ddraw_width && devmode.dmPelsHeight == param.ddraw_height, "Got unexpect screen size %ux%u.\n", devmode.dmPelsWidth, devmode.dmPelsHeight); @@ -2387,7 +2387,7 @@ static void test_coop_level_mode_set(void) hr = IDirectDraw_RestoreDisplayMode(ddraw); ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr); - todo_wine ok(!expect_messages->message, "Expected message %#x, but didn't receive it.\n", expect_messages->message); + ok(!expect_messages->message, "Expected message %#x, but didn't receive it.\n", expect_messages->message); expect_messages = NULL; todo_wine ok(screen_size.cx == registry_mode.dmPelsWidth && screen_size.cy == registry_mode.dmPelsHeight, diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c index f9454ad..16ceaf0 100644 --- a/dlls/ddraw/tests/ddraw2.c +++ b/dlls/ddraw/tests/ddraw2.c @@ -2562,19 +2562,19 @@ static void test_coop_level_mode_set(void) expect_messages = exclusive_focus_loss_messages; ret = SetForegroundWindow(GetDesktopWindow()); ok(ret, "Failed to set foreground window.\n"); - todo_wine ok(!expect_messages->message, "Expected message %#x, but didn't receive it.\n", expect_messages->message); + ok(!expect_messages->message, "Expected message %#x, but didn't receive it.\n", expect_messages->message); memset(&devmode, 0, sizeof(devmode)); devmode.dmSize = sizeof(devmode); ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode); ok(ret, "Failed to get display mode.\n"); - todo_wine ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth + ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth && devmode.dmPelsHeight == registry_mode.dmPelsHeight, "Got unexpect screen size %ux%u.\n", devmode.dmPelsWidth, devmode.dmPelsHeight); ShowWindow(window, SW_RESTORE); ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode); ok(ret, "Failed to get display mode.\n"); - todo_wine ok(devmode.dmPelsWidth == param.ddraw_width + ok(devmode.dmPelsWidth == param.ddraw_width && devmode.dmPelsHeight == param.ddraw_height, "Got unexpect screen size %ux%u.\n", devmode.dmPelsWidth, devmode.dmPelsHeight); @@ -2593,7 +2593,7 @@ static void test_coop_level_mode_set(void) hr = IDirectDraw2_RestoreDisplayMode(ddraw); ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr); - todo_wine ok(!expect_messages->message, "Expected message %#x, but didn't receive it.\n", expect_messages->message); + ok(!expect_messages->message, "Expected message %#x, but didn't receive it.\n", expect_messages->message); expect_messages = NULL; todo_wine ok(screen_size.cx == registry_mode.dmPelsWidth && screen_size.cy == registry_mode.dmPelsHeight, diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c index 0aa796e..03e7362 100644 --- a/dlls/ddraw/tests/ddraw4.c +++ b/dlls/ddraw/tests/ddraw4.c @@ -2749,19 +2749,19 @@ static void test_coop_level_mode_set(void) expect_messages = exclusive_focus_loss_messages; ret = SetForegroundWindow(GetDesktopWindow()); ok(ret, "Failed to set foreground window.\n"); - todo_wine ok(!expect_messages->message, "Expected message %#x, but didn't receive it.\n", expect_messages->message); + ok(!expect_messages->message, "Expected message %#x, but didn't receive it.\n", expect_messages->message); memset(&devmode, 0, sizeof(devmode)); devmode.dmSize = sizeof(devmode); ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode); ok(ret, "Failed to get display mode.\n"); - todo_wine ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth + ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth && devmode.dmPelsHeight == registry_mode.dmPelsHeight, "Got unexpect screen size %ux%u.\n", devmode.dmPelsWidth, devmode.dmPelsHeight); ShowWindow(window, SW_RESTORE); ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode); ok(ret, "Failed to get display mode.\n"); - todo_wine ok(devmode.dmPelsWidth == param.ddraw_width + ok(devmode.dmPelsWidth == param.ddraw_width && devmode.dmPelsHeight == param.ddraw_height, "Got unexpect screen size %ux%u.\n", devmode.dmPelsWidth, devmode.dmPelsHeight); @@ -2780,7 +2780,7 @@ static void test_coop_level_mode_set(void) hr = IDirectDraw4_RestoreDisplayMode(ddraw); ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr); - todo_wine ok(!expect_messages->message, "Expected message %#x, but didn't receive it.\n", expect_messages->message); + ok(!expect_messages->message, "Expected message %#x, but didn't receive it.\n", expect_messages->message); expect_messages = NULL; todo_wine ok(screen_size.cx == registry_mode.dmPelsWidth && screen_size.cy == registry_mode.dmPelsHeight, diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 65b3242..1efd1fb 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -2426,19 +2426,19 @@ static void test_coop_level_mode_set(void) expect_messages = exclusive_focus_loss_messages; ret = SetForegroundWindow(GetDesktopWindow()); ok(ret, "Failed to set foreground window.\n"); - todo_wine ok(!expect_messages->message, "Expected message %#x, but didn't receive it.\n", expect_messages->message); + ok(!expect_messages->message, "Expected message %#x, but didn't receive it.\n", expect_messages->message); memset(&devmode, 0, sizeof(devmode)); devmode.dmSize = sizeof(devmode); ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode); ok(ret, "Failed to get display mode.\n"); - todo_wine ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth + ok(devmode.dmPelsWidth == registry_mode.dmPelsWidth && devmode.dmPelsHeight == registry_mode.dmPelsHeight, "Got unexpect screen size %ux%u.\n", devmode.dmPelsWidth, devmode.dmPelsHeight); ShowWindow(window, SW_RESTORE); ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode); ok(ret, "Failed to get display mode.\n"); - todo_wine ok(devmode.dmPelsWidth == param.ddraw_width + ok(devmode.dmPelsWidth == param.ddraw_width && devmode.dmPelsHeight == param.ddraw_height, "Got unexpect screen size %ux%u.\n", devmode.dmPelsWidth, devmode.dmPelsHeight); @@ -2457,7 +2457,7 @@ static void test_coop_level_mode_set(void) hr = IDirectDraw7_RestoreDisplayMode(ddraw); ok(SUCCEEDED(hr), "RestoreDisplayMode failed, hr %#x.\n", hr); - todo_wine ok(!expect_messages->message, "Expected message %#x, but didn't receive it.\n", expect_messages->message); + ok(!expect_messages->message, "Expected message %#x, but didn't receive it.\n", expect_messages->message); expect_messages = NULL; todo_wine ok(screen_size.cx == registry_mode.dmPelsWidth && screen_size.cy == registry_mode.dmPelsHeight, diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 0de444b..ae6600e 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -4322,7 +4322,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, struct wined3d_resource *resource, *cursor; struct wined3d_swapchain *swapchain; struct wined3d_display_mode m; - BOOL DisplayModeChanged = FALSE; + BOOL DisplayModeChanged; BOOL update_desc = FALSE; UINT backbuffer_width = swapchain_desc->backbuffer_width; UINT backbuffer_height = swapchain_desc->backbuffer_height; @@ -4336,6 +4336,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, ERR("Failed to get the first implicit swapchain.\n"); return WINED3DERR_INVALIDCALL; } + DisplayModeChanged = swapchain->reapply_mode; if (reset_state) { @@ -4602,6 +4603,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, swapchain_desc->backbuffer_height, TRUE); } + swapchain->d3d_mode = m; } else if (!swapchain->desc.windowed) { diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index d5dbd3d..dbd433b 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -3281,78 +3281,94 @@ HRESULT CDECL wined3d_get_adapter_display_mode(const struct wined3d *wined3d, UI HRESULT CDECL wined3d_set_adapter_display_mode(struct wined3d *wined3d, UINT adapter_idx, const struct wined3d_display_mode *mode) { - struct wined3d_display_mode current_mode; - const struct wined3d_format *format; struct wined3d_adapter *adapter; - DEVMODEW devmode; + DEVMODEW new_mode, current_mode; RECT clip_rc; - HRESULT hr; LONG ret; + enum wined3d_format_id new_format_id; - TRACE("wined3d %p, adapter_idx %u, mode %p (%ux%u@%u %s %#x).\n", wined3d, adapter_idx, mode, - mode->width, mode->height, mode->refresh_rate, debug_d3dformat(mode->format_id), - mode->scanline_ordering); + TRACE("wined3d %p, adapter_idx %u, mode %p.\n", wined3d, adapter_idx, mode); if (adapter_idx >= wined3d->adapter_count) return WINED3DERR_INVALIDCALL; - adapter = &wined3d->adapters[adapter_idx]; - format = wined3d_get_format(&adapter->gl_info, mode->format_id); - memset(&devmode, 0, sizeof(devmode)); - devmode.dmSize = sizeof(devmode); - devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; - devmode.dmBitsPerPel = format->byte_count * CHAR_BIT; - devmode.dmPelsWidth = mode->width; - devmode.dmPelsHeight = mode->height; + memset(&new_mode, 0, sizeof(new_mode)); + new_mode.dmSize = sizeof(new_mode); + memset(¤t_mode, 0, sizeof(current_mode)); + current_mode.dmSize = sizeof(current_mode); + if (mode) + { + const struct wined3d_format *format; + + TRACE("mode %ux%u@%u %s %#x.\n", mode->width, mode->height, mode->refresh_rate, + debug_d3dformat(mode->format_id), mode->scanline_ordering); + + format = wined3d_get_format(&adapter->gl_info, mode->format_id); + + new_mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; + new_mode.dmBitsPerPel = format->byte_count * CHAR_BIT; + new_mode.dmPelsWidth = mode->width; + new_mode.dmPelsHeight = mode->height; - devmode.dmDisplayFrequency = mode->refresh_rate; - if (mode->refresh_rate) - devmode.dmFields |= DM_DISPLAYFREQUENCY; + new_mode.dmDisplayFrequency = mode->refresh_rate; + if (mode->refresh_rate) + new_mode.dmFields |= DM_DISPLAYFREQUENCY; - if (mode->scanline_ordering != WINED3D_SCANLINE_ORDERING_UNKNOWN) + if (mode->scanline_ordering != WINED3D_SCANLINE_ORDERING_UNKNOWN) + { + new_mode.dmFields |= DM_DISPLAYFLAGS; + if (mode->scanline_ordering == WINED3D_SCANLINE_ORDERING_INTERLACED) + new_mode.u2.dmDisplayFlags |= DM_INTERLACED; + } + new_format_id = mode->format_id; + } + else { - devmode.dmFields |= DM_DISPLAYFLAGS; - if (mode->scanline_ordering == WINED3D_SCANLINE_ORDERING_INTERLACED) - devmode.u2.dmDisplayFlags |= DM_INTERLACED; + if(!EnumDisplaySettingsW(adapter->DeviceName, ENUM_REGISTRY_SETTINGS, &new_mode)) + { + ERR("Failed to read mode from registry.\n"); + return WINED3DERR_NOTAVAILABLE; + } + new_format_id = pixelformat_for_depth(new_mode.dmBitsPerPel); } /* Only change the mode if necessary. */ - if (FAILED(hr = wined3d_get_adapter_display_mode(wined3d, adapter_idx, ¤t_mode, NULL))) + if (!EnumDisplaySettingsW(adapter->DeviceName, ENUM_CURRENT_SETTINGS, ¤t_mode)) { - ERR("Failed to get current display mode, hr %#x.\n", hr); + ERR("Failed to get current display mode.\n"); } - else if (current_mode.width == mode->width - && current_mode.height == mode->height - && current_mode.format_id == mode->format_id - && (current_mode.refresh_rate == mode->refresh_rate - || !mode->refresh_rate) - && (current_mode.scanline_ordering == mode->scanline_ordering - || mode->scanline_ordering == WINED3D_SCANLINE_ORDERING_UNKNOWN)) + else if (current_mode.dmPelsWidth == new_mode.dmPelsWidth + && current_mode.dmPelsHeight == new_mode.dmPelsHeight + && current_mode.dmBitsPerPel == new_mode.dmBitsPerPel + && (current_mode.dmDisplayFrequency == new_mode.dmDisplayFrequency + || !(new_mode.dmFields & DM_DISPLAYFREQUENCY)) + && (current_mode.u2.dmDisplayFlags == new_mode.u2.dmDisplayFlags + || new_mode.dmFields & DM_DISPLAYFLAGS)) { TRACE("Skipping redundant mode setting call.\n"); return WINED3D_OK; } - ret = ChangeDisplaySettingsExW(adapter->DeviceName, &devmode, NULL, CDS_FULLSCREEN, NULL); + ret = ChangeDisplaySettingsExW(adapter->DeviceName, &new_mode, NULL, CDS_FULLSCREEN, NULL); if (ret != DISP_CHANGE_SUCCESSFUL) { - if (devmode.dmDisplayFrequency) + if (new_mode.dmFields & DM_DISPLAYFREQUENCY) { WARN("ChangeDisplaySettingsExW failed, trying without the refresh rate.\n"); - devmode.dmFields &= ~DM_DISPLAYFREQUENCY; - devmode.dmDisplayFrequency = 0; - ret = ChangeDisplaySettingsExW(adapter->DeviceName, &devmode, NULL, CDS_FULLSCREEN, NULL); + new_mode.dmFields &= ~DM_DISPLAYFREQUENCY; + new_mode.dmDisplayFrequency = 0; + ret = ChangeDisplaySettingsExW(adapter->DeviceName, &new_mode, NULL, CDS_FULLSCREEN, NULL); } if (ret != DISP_CHANGE_SUCCESSFUL) return WINED3DERR_NOTAVAILABLE; } /* Store the new values. */ - adapter->screen_format = mode->format_id; + adapter->screen_format = new_format_id; /* And finally clip mouse to our screen. */ - SetRect(&clip_rc, 0, 0, mode->width, mode->height); + 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 4c0948f..20731ef 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -875,16 +875,14 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 if (!desc->windowed) { - struct wined3d_display_mode mode; - /* Change the display settings */ - mode.width = desc->backbuffer_width; - mode.height = desc->backbuffer_height; - mode.format_id = desc->backbuffer_format; - mode.refresh_rate = desc->refresh_rate; - mode.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN; + swapchain->d3d_mode.width = desc->backbuffer_width; + swapchain->d3d_mode.height = desc->backbuffer_height; + swapchain->d3d_mode.format_id = desc->backbuffer_format; + swapchain->d3d_mode.refresh_rate = desc->refresh_rate; + swapchain->d3d_mode.scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN; - if (FAILED(hr = wined3d_set_adapter_display_mode(device->wined3d, adapter->ordinal, &mode))) + if (FAILED(hr = wined3d_set_adapter_display_mode(device->wined3d, adapter->ordinal, &swapchain->d3d_mode))) { WARN("Failed to set display mode, hr %#x.\n", hr); goto err; @@ -1178,6 +1176,24 @@ void swapchain_update_draw_bindings(struct wined3d_swapchain *swapchain) void wined3d_swapchain_activate(struct wined3d_swapchain *swapchain, BOOL activate) { - if (!activate && !(swapchain->device->create_parms.flags & WINED3DCREATE_NOWINDOWCHANGES)) - ShowWindow(swapchain->device_window, SW_MINIMIZE); + if (activate) + { + if (swapchain->device->wined3d->flags & WINED3D_RESTORE_MODE_ON_ACTIVATE) + { + if (FAILED(wined3d_set_adapter_display_mode(swapchain->device->wined3d, + swapchain->device->adapter->ordinal, &swapchain->d3d_mode))) + ERR("Failed to set display mode.\n"); + } + } + else + { + if (FAILED(wined3d_set_adapter_display_mode(swapchain->device->wined3d, + swapchain->device->adapter->ordinal, NULL))) + ERR("Failed to set display mode.\n"); + + swapchain->reapply_mode = TRUE; + + if (!(swapchain->device->create_parms.flags & WINED3DCREATE_NOWINDOWCHANGES)) + ShowWindow(swapchain->device_window, SW_MINIMIZE); + } } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 193f10a..740dabc 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2684,9 +2684,9 @@ struct wined3d_swapchain struct wined3d_texture **back_buffers; struct wined3d_texture *front_buffer; struct wined3d_swapchain_desc desc; - struct wined3d_display_mode original_mode; + struct wined3d_display_mode original_mode, d3d_mode; struct wined3d_gamma_ramp orig_gamma; - BOOL render_to_fbo; + BOOL render_to_fbo, reapply_mode; const struct wined3d_format *ds_format; struct wined3d_palette *palette; diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index ef9850b..44a2726 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -1237,6 +1237,7 @@ enum wined3d_display_rotation #define WINED3D_NO3D 0x00000002 #define WINED3D_VIDMEM_ACCOUNTING 0x00000004 #define WINED3D_PRESENT_CONVERSION 0x00000008 +#define WINED3D_RESTORE_MODE_ON_ACTIVATE 0x00000010 #define WINED3D_RESZ_CODE 0x7fa05000 -- 2.0.4