[PATCH v3 3/3] ddraw: Restore the primary surface if we're the Foreground window, even if the device state is lost.

Gabriel Ivăncescu gabrielopcode at gmail.com
Mon Jul 27 12:53:43 CDT 2020


Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---

I haven't been able to add a reliable test for this, mostly because
WM_QUERYNEWPALETTE is rarely sent on Windows. In fact, for some reason even
changing the display mode to 8bpp still didn't send it. But it was sent if the
application was forced into "Run in 256 colors" (Windows XP) while having a
32bpp desktop display mode, which sounds like a compatibility shim hack to me.

 dlls/ddraw/surface.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index 8805014..f2182d5 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -3786,7 +3786,18 @@ static HRESULT WINAPI ddraw_surface7_Restore(IDirectDrawSurface7 *iface)
     }
 
     if (surface->ddraw->device_state == DDRAW_DEVICE_STATE_LOST && ddraw_surface_can_be_lost(surface))
-        return DDERR_WRONGMODE;
+    {
+        HWND window = surface->ddraw->focuswindow ? surface->ddraw->focuswindow : surface->ddraw->dest_window;
+
+        /* Railroad Tycoon 2 tries to restore the surface from within
+           a WM_QUERYNEWPALETTE message and expects it to succeed. We
+           haven't received the WM_ACTIVATEAPP message by that point,
+           so the device state is still LOST, even though we are in
+           the foreground. */
+        if (GetForegroundWindow() != window) return DDERR_WRONGMODE;
+
+        surface->ddraw->device_state = DDRAW_DEVICE_STATE_NOT_RESTORED;
+    }
 
     ddraw_update_lost_surfaces(surface->ddraw);
     surface->is_lost = FALSE;
-- 
2.21.0




More information about the wine-devel mailing list