dxgi/tests: Add test for swapchain window messages.

Signed-off-by: Józef Kucia <jkucia@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Józef Kucia 2018-09-19 16:55:29 +02:00 committed by Alexandre Julliard
parent 34700ae938
commit 1d1f340c90
1 changed files with 273 additions and 3 deletions

View File

@ -2152,9 +2152,9 @@ static void test_set_fullscreen(void)
ok(SUCCEEDED(hr), "CreateSwapChain failed, hr %#x.\n", hr);
check_swapchain_fullscreen_state(swapchain, &initial_state);
hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL);
ok(SUCCEEDED(hr) || hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE ||
broken(hr == DXGI_ERROR_UNSUPPORTED), /* Win 7 testbot */
"SetFullscreenState failed, hr %#x.\n", hr);
ok(SUCCEEDED(hr) || hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
|| broken(hr == DXGI_ERROR_UNSUPPORTED), /* Win 7 testbot */
"SetFullscreenState failed, hr %#x.\n", hr);
if (FAILED(hr))
{
skip("Could not change fullscreen state.\n");
@ -4211,6 +4211,275 @@ static void test_object_wrapping(void)
ok(!refcount, "Factory has %u references left.\n", refcount);
}
/* try to make sure pending X events have been processed before continuing */
static void flush_events(void)
{
int diff = 200;
DWORD time;
MSG msg;
time = GetTickCount() + diff;
while (diff > 0)
{
if (MsgWaitForMultipleObjects(0, NULL, FALSE, 100, QS_ALLINPUT) == WAIT_TIMEOUT)
break;
while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
DispatchMessageA(&msg);
diff = time - GetTickCount();
}
}
struct message
{
unsigned int message;
BOOL check_wparam;
WPARAM expect_wparam;
};
static BOOL expect_no_messages;
static const struct message *expect_messages;
static const struct message *expect_messages_broken;
static BOOL check_message(const struct message *expected,
HWND hwnd, unsigned int message, WPARAM wparam, LPARAM lparam)
{
if (expected->message != message)
return FALSE;
if (expected->check_wparam)
{
ok(wparam == expected->expect_wparam,
"Got unexpected wparam %lx for message %x, expected %lx.\n",
wparam, message, expected->expect_wparam);
}
return TRUE;
}
static LRESULT CALLBACK test_wndproc(HWND hwnd, unsigned int message, WPARAM wparam, LPARAM lparam)
{
ok(!expect_no_messages, "Got unexpected message %#x, hwnd %p, wparam %#lx, lparam %#lx.\n",
message, hwnd, wparam, lparam);
if (expect_messages)
{
if (check_message(expect_messages, hwnd, message, wparam, lparam))
++expect_messages;
}
if (expect_messages_broken)
{
if (check_message(expect_messages_broken, hwnd, message, wparam, lparam))
++expect_messages_broken;
}
return DefWindowProcA(hwnd, message, wparam, lparam);
}
static void test_swapchain_window_messages(void)
{
DXGI_SWAP_CHAIN_DESC swapchain_desc;
IDXGISwapChain *swapchain;
DXGI_MODE_DESC mode_desc;
IDXGIFactory *factory;
IDXGIAdapter *adapter;
IDXGIDevice *device;
ULONG refcount;
WNDCLASSA wc;
HWND window;
HRESULT hr;
static const struct message enter_fullscreen_messages[] =
{
{WM_STYLECHANGING, TRUE, GWL_STYLE},
{WM_STYLECHANGED, TRUE, GWL_STYLE},
{WM_STYLECHANGING, TRUE, GWL_EXSTYLE},
{WM_STYLECHANGED, TRUE, GWL_EXSTYLE},
{WM_WINDOWPOSCHANGING, FALSE, 0},
{WM_GETMINMAXINFO, FALSE, 0},
{WM_NCCALCSIZE, FALSE, 0},
{WM_WINDOWPOSCHANGED, FALSE, 0},
{WM_MOVE, FALSE, 0},
{WM_SIZE, FALSE, 0},
{0, FALSE, 0},
};
static const struct message enter_fullscreen_messages_vista[] =
{
{WM_STYLECHANGING, TRUE, GWL_STYLE},
{WM_STYLECHANGED, TRUE, GWL_STYLE},
{WM_WINDOWPOSCHANGING, FALSE, 0},
{WM_NCCALCSIZE, FALSE, 0},
{WM_WINDOWPOSCHANGED, FALSE, 0},
{WM_MOVE, FALSE, 0},
{WM_SIZE, FALSE, 0},
{WM_STYLECHANGING, TRUE, GWL_EXSTYLE},
{WM_STYLECHANGED, TRUE, GWL_EXSTYLE},
{WM_WINDOWPOSCHANGING, FALSE, 0},
{WM_GETMINMAXINFO, FALSE, 0},
{WM_NCCALCSIZE, FALSE, 0},
{WM_WINDOWPOSCHANGED, FALSE, 0},
{WM_SIZE, FALSE, 0},
{0, FALSE, 0},
};
static const struct message leave_fullscreen_messages[] =
{
{WM_STYLECHANGING, TRUE, GWL_STYLE},
{WM_STYLECHANGED, TRUE, GWL_STYLE},
{WM_STYLECHANGING, TRUE, GWL_EXSTYLE},
{WM_STYLECHANGED, TRUE, GWL_EXSTYLE},
{WM_WINDOWPOSCHANGING, FALSE, 0},
{WM_GETMINMAXINFO, FALSE, 0},
{WM_NCCALCSIZE, FALSE, 0},
{WM_WINDOWPOSCHANGED, FALSE, 0},
{WM_MOVE, FALSE, 0},
{WM_SIZE, FALSE, 0},
{0, FALSE, 0},
};
static const struct message resize_target_messages[] =
{
{WM_WINDOWPOSCHANGING, FALSE, 0},
{WM_GETMINMAXINFO, FALSE, 0},
{WM_NCCALCSIZE, FALSE, 0},
{WM_WINDOWPOSCHANGED, FALSE, 0},
{WM_SIZE, FALSE, 0},
{0, FALSE, 0},
};
if (!(device = create_device(0)))
{
skip("Failed to create device.\n");
return;
}
memset(&wc, 0, sizeof(wc));
wc.lpfnWndProc = test_wndproc;
wc.lpszClassName = "dxgi_test_wndproc_wc";
ok(RegisterClassA(&wc), "Failed to register window class.\n");
window = CreateWindowA("dxgi_test_wndproc_wc", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0);
ok(!!window, "Failed to create window.\n");
hr = IDXGIDevice_GetAdapter(device, &adapter);
ok(hr == S_OK, "Failed to get adapter, hr %#x.\n", hr);
hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory);
ok(hr == S_OK, "Failed to get parent, hr %#x.\n", hr);
IDXGIAdapter_Release(adapter);
swapchain_desc.BufferDesc.Width = 800;
swapchain_desc.BufferDesc.Height = 600;
swapchain_desc.BufferDesc.RefreshRate.Numerator = 60;
swapchain_desc.BufferDesc.RefreshRate.Denominator = 60;
swapchain_desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapchain_desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
swapchain_desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
swapchain_desc.SampleDesc.Count = 1;
swapchain_desc.SampleDesc.Quality = 0;
swapchain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapchain_desc.BufferCount = 1;
swapchain_desc.OutputWindow = window;
swapchain_desc.Windowed = TRUE;
swapchain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
swapchain_desc.Flags = 0;
/* create swapchain */
flush_events();
expect_no_messages = TRUE;
hr = IDXGIFactory_CreateSwapChain(factory, (IUnknown *)device, &swapchain_desc, &swapchain);
ok(hr == S_OK, "Failed to create swapchain, hr %#x.\n", hr);
flush_events();
expect_no_messages = FALSE;
/* resize target */
expect_messages = resize_target_messages;
memset(&mode_desc, 0, sizeof(mode_desc));
mode_desc.Width = 800;
mode_desc.Width = 600;
hr = IDXGISwapChain_ResizeTarget(swapchain, &mode_desc);
ok(hr == S_OK, "Failed to resize target, hr %#x.\n", hr);
flush_events();
ok(!expect_messages->message, "Expected message %#x.\n", expect_messages->message);
expect_messages = resize_target_messages;
memset(&mode_desc, 0, sizeof(mode_desc));
mode_desc.Width = 400;
mode_desc.Width = 200;
hr = IDXGISwapChain_ResizeTarget(swapchain, &mode_desc);
ok(hr == S_OK, "Failed to resize target, hr %#x.\n", hr);
flush_events();
ok(!expect_messages->message, "Expected message %#x.\n", expect_messages->message);
/* enter fullscreen */
expect_messages = enter_fullscreen_messages;
expect_messages_broken = enter_fullscreen_messages_vista;
hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL);
ok(hr == S_OK || hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
|| broken(hr == DXGI_ERROR_UNSUPPORTED), /* Win 7 testbot */
"Failed to enter fullscreen, hr %#x.\n", hr);
if (FAILED(hr))
{
skip("Could not change fullscreen state.\n");
goto done;
}
flush_events();
todo_wine
ok(!expect_messages->message || broken(!expect_messages_broken->message),
"Expected message %#x or %#x.\n",
expect_messages->message, expect_messages_broken->message);
expect_messages_broken = NULL;
/* leave fullscreen */
expect_messages = leave_fullscreen_messages;
hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
flush_events();
todo_wine
ok(!expect_messages->message, "Expected message %#x.\n", expect_messages->message);
expect_messages = NULL;
refcount = IDXGISwapChain_Release(swapchain);
ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount);
/* create fullscreen swapchain */
DestroyWindow(window);
window = CreateWindowA("dxgi_test_wndproc_wc", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0);
ok(!!window, "Failed to create window.\n");
swapchain_desc.OutputWindow = window;
swapchain_desc.Windowed = FALSE;
swapchain_desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
flush_events();
expect_messages = enter_fullscreen_messages;
expect_messages_broken = enter_fullscreen_messages_vista;
hr = IDXGIFactory_CreateSwapChain(factory, (IUnknown *)device, &swapchain_desc, &swapchain);
ok(hr == S_OK, "Failed to create swapchain, hr %#x.\n", hr);
flush_events();
todo_wine
ok(!expect_messages->message || broken(!expect_messages_broken->message),
"Expected message %#x or %#x.\n",
expect_messages->message, expect_messages_broken->message);
expect_messages_broken = NULL;
/* leave fullscreen */
expect_messages = leave_fullscreen_messages;
hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL);
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
flush_events();
todo_wine
ok(!expect_messages->message, "Expected message %#x.\n", expect_messages->message);
expect_messages = NULL;
done:
refcount = IDXGISwapChain_Release(swapchain);
ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount);
DestroyWindow(window);
refcount = IDXGIDevice_Release(device);
ok(!refcount, "Device has %u references left.\n", refcount);
refcount = IDXGIFactory_Release(factory);
ok(!refcount, "Factory has %u references left.\n", refcount);
UnregisterClassA("dxgi_test_wndproc_wc", GetModuleHandleA(NULL));
}
static void run_on_d3d10(void (*test_func)(IUnknown *device, BOOL is_d3d12))
{
IDXGIDevice *device;
@ -4304,6 +4573,7 @@ START_TEST(dxgi)
test_resize_target();
test_inexact_modes();
test_swapchain_parameters();
test_swapchain_window_messages();
run_on_d3d10(test_swapchain_resize);
run_on_d3d10(test_swapchain_backbuffer_index);
run_on_d3d10(test_swapchain_formats);