[PATCH 6/6] wined3d: Restore the display mode on focus change.

Stefan Dösinger stefan at codeweavers.com
Tue Nov 18 14:26:57 CST 2014


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(&current_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, &current_mode, NULL)))
+    if (!EnumDisplaySettingsW(adapter->DeviceName, ENUM_CURRENT_SETTINGS, &current_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




More information about the wine-patches mailing list