From: Rémi Bernon rbernon@codeweavers.com
The client rect might be empty or invalid. Fallout 3 in particular does a bogus call sequence after restoring minimized window which causes the window and client rects to be empty:
SetRect(&rect, 0, 0, width, height); AdjustWindowRectEx(&rect, style, FALSE, 0); SetWindowPos(hwnd, 0, rect.left, rect.bottom, rect.right - rect.left, rect.top - rect.bottom, 0);
We either need to hook the window messages and inhibit such window size changes, or we need to avoid relying on client and window rect when in fullscreen mode.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58844 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58443 --- dlls/wined3d/context_gl.c | 18 ++++++++++++++++++ dlls/wined3d/swapchain.c | 29 +++++++++++++++++++++++++++-- dlls/wined3d/texture.c | 15 +++++++++++++++ 3 files changed, 60 insertions(+), 2 deletions(-)
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index ac1b9370fc1..223652a51cc 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -2393,6 +2393,24 @@ static void wined3d_context_gl_get_rt_size(const struct wined3d_context_gl *cont { RECT window_size;
+ if (!rt->swapchain->state.desc.windowed) + { + struct wined3d_display_mode actual_mode; + struct wined3d_output *output; + HRESULT hr; + + if (!(output = wined3d_swapchain_get_output(rt->swapchain))) + ERR("Failed to get swapchain output.\n"); + else if (FAILED(hr = wined3d_output_get_display_mode(output, &actual_mode, NULL))) + ERR("Failed to get display mode, hr %#lx.\n", hr); + else + { + size->cx = actual_mode.width; + size->cy = actual_mode.height; + return; + } + } + GetClientRect(context_gl->window, &window_size); size->cx = window_size.right - window_size.left; size->cy = window_size.bottom - window_size.top; diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index d1f835fa809..f6b71021bd4 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -40,6 +40,31 @@ static BOOL set_window_present_rect(HWND hwnd, UINT x, UINT y, UINT width, UINT return !D3DKMTEscape(&escape); }
+static void get_swapchain_present_rect(struct wined3d_swapchain *swapchain, RECT *rect) +{ + if (!swapchain->state.desc.windowed) + { + struct wined3d_display_mode actual_mode; + struct wined3d_output_desc output_desc; + struct wined3d_output *output; + HRESULT hr; + + if (!(output = wined3d_swapchain_get_output(swapchain))) + ERR("Failed to get swapchain output.\n"); + else if (FAILED(hr = wined3d_output_get_desc(output, &output_desc))) + ERR("Failed to get output description, hr %#lx.\n", hr); + else if (FAILED(hr = wined3d_output_get_display_mode(output, &actual_mode, NULL))) + ERR("Failed to get display mode, hr %#lx.\n", hr); + else + SetRect(rect, output_desc.desktop_rect.left, output_desc.desktop_rect.top, + output_desc.desktop_rect.left + actual_mode.width, + output_desc.desktop_rect.top + actual_mode.height); + return; + } + + GetClientRect(swapchain->win_handle, rect); +} + void wined3d_swapchain_cleanup(struct wined3d_swapchain *swapchain) { HRESULT hr; @@ -235,7 +260,7 @@ HRESULT CDECL wined3d_swapchain_present(struct wined3d_swapchain *swapchain,
if (!dst_rect) { - GetClientRect(swapchain->win_handle, &d); + get_swapchain_present_rect(swapchain, &d); dst_rect = &d; }
@@ -583,7 +608,7 @@ static bool swapchain_present_is_partial_copy(struct wined3d_swapchain *swapchai if (swap_effect != WINED3D_SWAP_EFFECT_COPY && swap_effect != WINED3D_SWAP_EFFECT_COPY_VSYNC) return false;
- GetClientRect(swapchain->win_handle, &client_rect); + get_swapchain_present_rect(swapchain, &client_rect);
t = client_rect.right - client_rect.left; if ((dst_rect->left && dst_rect->right) || abs(dst_rect->right - dst_rect->left) != t) diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index dd61a2f0d3c..0d2ccea4541 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -82,6 +82,21 @@ void wined3d_texture_translate_drawable_coords(const struct wined3d_texture *tex }
GetClientRect(window, &windowsize); + + if (!texture->swapchain->state.desc.windowed) + { + struct wined3d_display_mode actual_mode; + struct wined3d_output *output; + HRESULT hr; + + if (!(output = wined3d_swapchain_get_output(texture->swapchain))) + ERR("Failed to get swapchain output.\n"); + else if (FAILED(hr = wined3d_output_get_display_mode(output, &actual_mode, NULL))) + ERR("Failed to get display mode, hr %#lx.\n", hr); + else + SetRect(&windowsize, 0, 0, actual_mode.width, actual_mode.height); + } + drawable_height = windowsize.bottom - windowsize.top;
rect->top = drawable_height - rect->top;