Signed-off-by: Stefan Dösinger stefan@codeweavers.com
---
During focus restore the state differs between Windows versions.
The primary surface is lost before the first WM_DISPLAYCHANGED message is delivered. I am not testing this here because we change the display mode before we drop focus, to test if ddraw restores the mode. I would have to add another mode switch cycle to document the surface loss behavior, which I prefer not to do until we have an application that is picky about it.
On a sidenode, it seems that DDERR_SURFACELOST is picked up without any messages. If I hide all messages from ddraw by replacing the WNDPROC the primary still gets lost. The focus loss needs the WM_ACTIVATEAPP message though. If I hide that message, weird things happen. --- dlls/ddraw/tests/ddraw4.c | 38 ++++++++++++++++++++++++++------------ dlls/ddraw/tests/ddraw7.c | 38 ++++++++++++++++++++++++++------------ 2 files changed, 52 insertions(+), 24 deletions(-)
diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c index 7cf61cea911..3aae42554f2 100644 --- a/dlls/ddraw/tests/ddraw4.c +++ b/dlls/ddraw/tests/ddraw4.c @@ -532,12 +532,16 @@ struct message UINT message; BOOL check_wparam; WPARAM expect_wparam; + HRESULT ddraw_state; };
static const struct message *expect_messages; +static IDirectDraw4 *focus_test_ddraw;
static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { + HRESULT hr; + if (expect_messages && message == expect_messages->message) { if (expect_messages->check_wparam) @@ -545,6 +549,13 @@ static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM "Got unexpected wparam %lx for message %x, expected %lx.\n", wparam, message, expect_messages->expect_wparam);
+ if (focus_test_ddraw) + { + hr = IDirectDraw4_TestCooperativeLevel(focus_test_ddraw); + ok(hr == expect_messages->ddraw_state, "Got ddraw state %#x on message %#x, expected %#x.\n", + hr, message, expect_messages->ddraw_state); + } + ++expect_messages; }
@@ -2712,22 +2723,22 @@ static void test_coop_level_mode_set(void) }; static const struct message exclusive_focus_loss_messages[] = { - {WM_ACTIVATE, TRUE, WA_INACTIVE}, - {WM_WINDOWPOSCHANGING, FALSE, 0}, /* Window resize due to mode change. */ - {WM_WINDOWPOSCHANGED, FALSE, 0}, - {WM_SIZE, TRUE, SIZE_RESTORED}, /* Generated by DefWindowProc. */ - {WM_DISPLAYCHANGE, FALSE, 0}, - {WM_KILLFOCUS, FALSE, 0}, - {WM_WINDOWPOSCHANGING, FALSE, 0}, /* Window minimized. */ + {WM_ACTIVATE, TRUE, WA_INACTIVE, DD_OK}, + {WM_WINDOWPOSCHANGING, FALSE, 0, DD_OK}, /* Window resize due to mode change. */ + {WM_WINDOWPOSCHANGED, FALSE, 0, DD_OK}, + {WM_SIZE, TRUE, SIZE_RESTORED, DD_OK}, /* Generated by DefWindowProc. */ + {WM_DISPLAYCHANGE, FALSE, 0, DD_OK}, + {WM_KILLFOCUS, FALSE, 0, DDERR_NOEXCLUSIVEMODE}, + {WM_WINDOWPOSCHANGING, FALSE, 0, DDERR_NOEXCLUSIVEMODE}, /* Window minimized. */ /* Like d3d8 and d3d9 ddraw seems to use SW_SHOWMINIMIZED instead of * SW_MINIMIZED, causing a recursive window activation that does not * produce the same result in Wine yet. Ignore the difference for now. * {WM_ACTIVATE, TRUE, 0x200000 | WA_ACTIVE}, */ - {WM_WINDOWPOSCHANGED, FALSE, 0}, - {WM_MOVE, FALSE, 0}, - {WM_SIZE, TRUE, SIZE_MINIMIZED}, - {WM_ACTIVATEAPP, TRUE, FALSE}, - {0, FALSE, 0}, + {WM_WINDOWPOSCHANGED, FALSE, 0, DDERR_NOEXCLUSIVEMODE}, + {WM_MOVE, FALSE, 0, DDERR_NOEXCLUSIVEMODE}, + {WM_SIZE, TRUE, SIZE_MINIMIZED, DDERR_NOEXCLUSIVEMODE}, + {WM_ACTIVATEAPP, TRUE, FALSE, DDERR_NOEXCLUSIVEMODE}, + {0, FALSE, 0, 0}, }; static const struct message exclusive_focus_restore_messages[] = { @@ -2912,9 +2923,12 @@ static void test_coop_level_mode_set(void) wine_dbgstr_rect(&r));
expect_messages = exclusive_focus_loss_messages; + focus_test_ddraw = ddraw; ret = SetForegroundWindow(GetDesktopWindow()); ok(ret, "Failed to set foreground window.\n"); ok(!expect_messages->message, "Expected message %#x, but didn't receive it.\n", expect_messages->message); + focus_test_ddraw = NULL; + memset(&devmode, 0, sizeof(devmode)); devmode.dmSize = sizeof(devmode); ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode); diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 6ae4207b34b..4691135186b 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -448,12 +448,16 @@ struct message UINT message; BOOL check_wparam; WPARAM expect_wparam; + HRESULT ddraw_state; };
static const struct message *expect_messages; +static IDirectDraw7 *focus_test_ddraw;
static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) { + HRESULT hr; + if (expect_messages && message == expect_messages->message) { if (expect_messages->check_wparam) @@ -461,6 +465,13 @@ static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM "Got unexpected wparam %lx for message %x, expected %lx.\n", wparam, message, expect_messages->expect_wparam);
+ if (focus_test_ddraw) + { + hr = IDirectDraw7_TestCooperativeLevel(focus_test_ddraw); + ok(hr == expect_messages->ddraw_state, "Got ddraw state %#x on message %#x, expected %#x.\n", + hr, message, expect_messages->ddraw_state); + } + ++expect_messages; }
@@ -2441,22 +2452,22 @@ static void test_coop_level_mode_set(void) }; static const struct message exclusive_focus_loss_messages[] = { - {WM_ACTIVATE, TRUE, WA_INACTIVE}, - {WM_WINDOWPOSCHANGING, FALSE, 0}, /* Window resize due to mode change. */ - {WM_WINDOWPOSCHANGED, FALSE, 0}, - {WM_SIZE, TRUE, SIZE_RESTORED}, /* Generated by DefWindowProc. */ - {WM_DISPLAYCHANGE, FALSE, 0}, - {WM_KILLFOCUS, FALSE, 0}, - {WM_WINDOWPOSCHANGING, FALSE, 0}, /* Window minimized. */ + {WM_ACTIVATE, TRUE, WA_INACTIVE, DD_OK}, + {WM_WINDOWPOSCHANGING, FALSE, 0, DD_OK}, /* Window resize due to mode change. */ + {WM_WINDOWPOSCHANGED, FALSE, 0, DD_OK}, + {WM_SIZE, TRUE, SIZE_RESTORED, DD_OK}, /* Generated by DefWindowProc. */ + {WM_DISPLAYCHANGE, FALSE, 0, DD_OK}, + {WM_KILLFOCUS, FALSE, 0, DDERR_NOEXCLUSIVEMODE}, + {WM_WINDOWPOSCHANGING, FALSE, 0, DDERR_NOEXCLUSIVEMODE}, /* Window minimized. */ /* Like d3d8 and d3d9 ddraw seems to use SW_SHOWMINIMIZED instead of * SW_MINIMIZED, causing a recursive window activation that does not * produce the same result in Wine yet. Ignore the difference for now. * {WM_ACTIVATE, TRUE, 0x200000 | WA_ACTIVE}, */ - {WM_WINDOWPOSCHANGED, FALSE, 0}, - {WM_MOVE, FALSE, 0}, - {WM_SIZE, TRUE, SIZE_MINIMIZED}, - {WM_ACTIVATEAPP, TRUE, FALSE}, - {0, FALSE, 0}, + {WM_WINDOWPOSCHANGED, FALSE, 0, DDERR_NOEXCLUSIVEMODE}, + {WM_MOVE, FALSE, 0, DDERR_NOEXCLUSIVEMODE}, + {WM_SIZE, TRUE, SIZE_MINIMIZED, DDERR_NOEXCLUSIVEMODE}, + {WM_ACTIVATEAPP, TRUE, FALSE, DDERR_NOEXCLUSIVEMODE}, + {0, FALSE, 0, 0}, }; static const struct message exclusive_focus_restore_messages[] = { @@ -2641,9 +2652,12 @@ static void test_coop_level_mode_set(void) wine_dbgstr_rect(&r));
expect_messages = exclusive_focus_loss_messages; + focus_test_ddraw = ddraw; ret = SetForegroundWindow(GetDesktopWindow()); ok(ret, "Failed to set foreground window.\n"); ok(!expect_messages->message, "Expected message %#x, but didn't receive it.\n", expect_messages->message); + focus_test_ddraw = NULL; + memset(&devmode, 0, sizeof(devmode)); devmode.dmSize = sizeof(devmode); ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);