diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index ce7bef8fe4a..60836a7b925 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -29,6 +29,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(ddraw); static const struct ddraw *exclusive_ddraw; +static HWND exclusive_window; /* Device identifier. Don't relay it to WineD3D */ static const DDDEVICEIDENTIFIER2 deviceidentifier = @@ -900,6 +901,12 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window, } } + if ((cooplevel & DDSCL_EXCLUSIVE) && exclusive_window != window) + { + ddraw->device_state = DDRAW_DEVICE_STATE_NOT_RESTORED; + exclusive_window = window; + } + if (cooplevel & DDSCL_MULTITHREADED && !(ddraw->cooperative_level & DDSCL_MULTITHREADED)) wined3d_device_set_multithreaded(ddraw->wined3d_device); @@ -927,7 +934,6 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window, wined3d_rendertarget_view_incref(dsv); } - ddraw->device_state = DDRAW_DEVICE_STATE_NOT_RESTORED; ddraw_destroy_swapchain(ddraw); } @@ -4707,9 +4713,14 @@ static void CDECL device_parent_activate(struct wined3d_device_parent *device_pa TRACE("device_parent %p, activate %#x.\n", device_parent, activate); if (!activate) + { ddraw->device_state = DDRAW_DEVICE_STATE_LOST; + exclusive_window = NULL; + } else + { InterlockedCompareExchange(&ddraw->device_state, DDRAW_DEVICE_STATE_NOT_RESTORED, DDRAW_DEVICE_STATE_LOST); + } } void ddraw_update_lost_surfaces(struct ddraw *ddraw) diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index f5122b62083..c537170f374 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -6158,17 +6158,19 @@ static void test_lost_device(void) { IDirectDrawSurface *surface; DDSURFACEDESC surface_desc; + HWND window1, window2; IDirectDraw *ddraw; ULONG refcount; - HWND window; HRESULT hr; BOOL ret; - window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, + window1 = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, + 0, 0, 640, 480, 0, 0, 0, 0); + window2 = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0); ddraw = create_ddraw(); ok(!!ddraw, "Failed to create a ddraw object.\n"); - hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); + hr = IDirectDraw_SetCooperativeLevel(ddraw, window1, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr); memset(&surface_desc, 0, sizeof(surface_desc)); @@ -6191,7 +6193,7 @@ static void test_lost_device(void) hr = IDirectDrawSurface_Flip(surface, NULL, DDFLIP_WAIT); ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr); - ret = SetForegroundWindow(window); + ret = SetForegroundWindow(window1); ok(ret, "Failed to set foreground window.\n"); hr = IDirectDrawSurface_IsLost(surface); ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr); @@ -6205,12 +6207,12 @@ static void test_lost_device(void) hr = IDirectDrawSurface_Flip(surface, NULL, DDFLIP_WAIT); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); - hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL); + hr = IDirectDraw_SetCooperativeLevel(ddraw, window1, DDSCL_NORMAL); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirectDrawSurface_IsLost(surface); - todo_wine ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirectDrawSurface_Flip(surface, NULL, DDFLIP_WAIT); - todo_wine ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#x.\n", hr); + ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#x.\n", hr); /* Trying to restore the primary will crash, probably because flippable * surfaces can't exist in DDSCL_NORMAL. */ @@ -6230,12 +6232,12 @@ static void test_lost_device(void) hr = IDirectDrawSurface_IsLost(surface); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); - ret = SetForegroundWindow(window); + ret = SetForegroundWindow(window1); ok(ret, "Failed to set foreground window.\n"); hr = IDirectDrawSurface_IsLost(surface); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); - hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); + hr = IDirectDraw_SetCooperativeLevel(ddraw, window1, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirectDrawSurface_IsLost(surface); ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr); @@ -6245,10 +6247,62 @@ static void test_lost_device(void) hr = IDirectDrawSurface_IsLost(surface); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + IDirectDrawSurface_Release(surface); + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; + surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP; + U5(surface_desc).dwBackBufferCount = 1; + hr = IDirectDraw_CreateSurface(ddraw, &surface_desc, &surface, NULL); + ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr); + + hr = IDirectDraw_SetCooperativeLevel(ddraw, window1, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface_IsLost(surface); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface_Flip(surface, NULL, DDFLIP_WAIT); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirectDraw_SetCooperativeLevel(ddraw, window1, DDSCL_NORMAL | DDSCL_FULLSCREEN); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface_IsLost(surface); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface_Flip(surface, NULL, DDFLIP_WAIT); + ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#x.\n", hr); + + hr = IDirectDraw_SetCooperativeLevel(ddraw, window1, DDSCL_NORMAL); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface_IsLost(surface); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface_Flip(surface, NULL, DDFLIP_WAIT); + ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#x.\n", hr); + + hr = IDirectDraw_SetCooperativeLevel(ddraw, window2, DDSCL_NORMAL); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface_IsLost(surface); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface_Flip(surface, NULL, DDFLIP_WAIT); + ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#x.\n", hr); + + hr = IDirectDraw_SetCooperativeLevel(ddraw, window2, DDSCL_NORMAL | DDSCL_FULLSCREEN); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface_IsLost(surface); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface_Flip(surface, NULL, DDFLIP_WAIT); + ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#x.\n", hr); + + hr = IDirectDraw_SetCooperativeLevel(ddraw, window2, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface_IsLost(surface); + ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface_Flip(surface, NULL, DDFLIP_WAIT); + ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr); + IDirectDrawSurface_Release(surface); refcount = IDirectDraw_Release(ddraw); ok(!refcount, "Got unexpected refcount %u.\n", refcount); - DestroyWindow(window); + DestroyWindow(window2); + DestroyWindow(window1); } static void test_surface_desc_lock(void) diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c index 177f3ece667..79870c02ade 100644 --- a/dlls/ddraw/tests/ddraw2.c +++ b/dlls/ddraw/tests/ddraw2.c @@ -7405,17 +7405,19 @@ static void test_lost_device(void) { IDirectDrawSurface *surface; DDSURFACEDESC surface_desc; + HWND window1, window2; IDirectDraw2 *ddraw; ULONG refcount; - HWND window; HRESULT hr; BOOL ret; - window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, + window1 = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, + 0, 0, 640, 480, 0, 0, 0, 0); + window2 = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0); ddraw = create_ddraw(); ok(!!ddraw, "Failed to create a ddraw object.\n"); - hr = IDirectDraw2_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); + hr = IDirectDraw2_SetCooperativeLevel(ddraw, window1, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr); memset(&surface_desc, 0, sizeof(surface_desc)); @@ -7438,7 +7440,7 @@ static void test_lost_device(void) hr = IDirectDrawSurface_Flip(surface, NULL, DDFLIP_WAIT); ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr); - ret = SetForegroundWindow(window); + ret = SetForegroundWindow(window1); ok(ret, "Failed to set foreground window.\n"); hr = IDirectDrawSurface_IsLost(surface); ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr); @@ -7452,12 +7454,12 @@ static void test_lost_device(void) hr = IDirectDrawSurface_Flip(surface, NULL, DDFLIP_WAIT); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); - hr = IDirectDraw2_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL); + hr = IDirectDraw2_SetCooperativeLevel(ddraw, window1, DDSCL_NORMAL); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirectDrawSurface_IsLost(surface); - ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr); + todo_wine ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr); hr = IDirectDrawSurface_Flip(surface, NULL, DDFLIP_WAIT); - ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr); + todo_wine ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr); /* Trying to restore the primary will crash, probably because flippable * surfaces can't exist in DDSCL_NORMAL. */ @@ -7477,12 +7479,12 @@ static void test_lost_device(void) hr = IDirectDrawSurface_IsLost(surface); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); - ret = SetForegroundWindow(window); + ret = SetForegroundWindow(window1); ok(ret, "Failed to set foreground window.\n"); hr = IDirectDrawSurface_IsLost(surface); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); - hr = IDirectDraw2_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); + hr = IDirectDraw2_SetCooperativeLevel(ddraw, window1, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirectDrawSurface_IsLost(surface); ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr); @@ -7492,10 +7494,62 @@ static void test_lost_device(void) hr = IDirectDrawSurface_IsLost(surface); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + IDirectDrawSurface_Release(surface); + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; + surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP; + U5(surface_desc).dwBackBufferCount = 1; + hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &surface, NULL); + ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr); + + hr = IDirectDraw2_SetCooperativeLevel(ddraw, window1, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface_IsLost(surface); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface_Flip(surface, NULL, DDFLIP_WAIT); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirectDraw2_SetCooperativeLevel(ddraw, window1, DDSCL_NORMAL | DDSCL_FULLSCREEN); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface_IsLost(surface); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface_Flip(surface, NULL, DDFLIP_WAIT); + ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#x.\n", hr); + + hr = IDirectDraw2_SetCooperativeLevel(ddraw, window1, DDSCL_NORMAL); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface_IsLost(surface); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface_Flip(surface, NULL, DDFLIP_WAIT); + ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#x.\n", hr); + + hr = IDirectDraw2_SetCooperativeLevel(ddraw, window2, DDSCL_NORMAL); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface_IsLost(surface); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface_Flip(surface, NULL, DDFLIP_WAIT); + ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#x.\n", hr); + + hr = IDirectDraw2_SetCooperativeLevel(ddraw, window2, DDSCL_NORMAL | DDSCL_FULLSCREEN); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface_IsLost(surface); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface_Flip(surface, NULL, DDFLIP_WAIT); + ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#x.\n", hr); + + hr = IDirectDraw2_SetCooperativeLevel(ddraw, window2, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface_IsLost(surface); + ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface_Flip(surface, NULL, DDFLIP_WAIT); + ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr); + IDirectDrawSurface_Release(surface); refcount = IDirectDraw2_Release(ddraw); ok(!refcount, "Got unexpected refcount %u.\n", refcount); - DestroyWindow(window); + DestroyWindow(window2); + DestroyWindow(window1); } static void test_surface_desc_lock(void) diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c index c521e515393..6eb51d23a63 100644 --- a/dlls/ddraw/tests/ddraw4.c +++ b/dlls/ddraw/tests/ddraw4.c @@ -8464,17 +8464,19 @@ static void test_lost_device(void) { IDirectDrawSurface4 *surface; DDSURFACEDESC2 surface_desc; + HWND window1, window2; IDirectDraw4 *ddraw; ULONG refcount; - HWND window; HRESULT hr; BOOL ret; - window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, + window1 = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, + 0, 0, 640, 480, 0, 0, 0, 0); + window2 = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0); ddraw = create_ddraw(); ok(!!ddraw, "Failed to create a ddraw object.\n"); - hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); + hr = IDirectDraw4_SetCooperativeLevel(ddraw, window1, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr); memset(&surface_desc, 0, sizeof(surface_desc)); @@ -8501,7 +8503,7 @@ static void test_lost_device(void) hr = IDirectDrawSurface4_Flip(surface, NULL, DDFLIP_WAIT); ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr); - ret = SetForegroundWindow(window); + ret = SetForegroundWindow(window1); ok(ret, "Failed to set foreground window.\n"); hr = IDirectDraw4_TestCooperativeLevel(ddraw); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); @@ -8519,14 +8521,14 @@ static void test_lost_device(void) hr = IDirectDrawSurface4_Flip(surface, NULL, DDFLIP_WAIT); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); - hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL); + hr = IDirectDraw4_SetCooperativeLevel(ddraw, window1, DDSCL_NORMAL); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirectDraw4_TestCooperativeLevel(ddraw); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirectDrawSurface4_IsLost(surface); - ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr); + todo_wine ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr); hr = IDirectDrawSurface4_Flip(surface, NULL, DDFLIP_WAIT); - ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr); + todo_wine ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr); /* Trying to restore the primary will crash, probably because flippable * surfaces can't exist in DDSCL_NORMAL. */ @@ -8550,14 +8552,14 @@ static void test_lost_device(void) hr = IDirectDrawSurface4_IsLost(surface); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); - ret = SetForegroundWindow(window); + ret = SetForegroundWindow(window1); ok(ret, "Failed to set foreground window.\n"); hr = IDirectDraw4_TestCooperativeLevel(ddraw); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirectDrawSurface4_IsLost(surface); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); - hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); + hr = IDirectDraw4_SetCooperativeLevel(ddraw, window1, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirectDraw4_TestCooperativeLevel(ddraw); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); @@ -8571,10 +8573,74 @@ static void test_lost_device(void) hr = IDirectDrawSurface4_IsLost(surface); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + IDirectDrawSurface4_Release(surface); + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; + surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP; + U5(surface_desc).dwBackBufferCount = 1; + hr = IDirectDraw4_CreateSurface(ddraw, &surface_desc, &surface, NULL); + ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr); + + hr = IDirectDraw4_SetCooperativeLevel(ddraw, window1, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDraw4_TestCooperativeLevel(ddraw); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface4_IsLost(surface); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface4_Flip(surface, NULL, DDFLIP_WAIT); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirectDraw4_SetCooperativeLevel(ddraw, window1, DDSCL_NORMAL | DDSCL_FULLSCREEN); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDraw4_TestCooperativeLevel(ddraw); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface4_IsLost(surface); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface4_Flip(surface, NULL, DDFLIP_WAIT); + ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#x.\n", hr); + + hr = IDirectDraw4_SetCooperativeLevel(ddraw, window1, DDSCL_NORMAL); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDraw4_TestCooperativeLevel(ddraw); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface4_IsLost(surface); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface4_Flip(surface, NULL, DDFLIP_WAIT); + ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#x.\n", hr); + + hr = IDirectDraw4_SetCooperativeLevel(ddraw, window2, DDSCL_NORMAL); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDraw4_TestCooperativeLevel(ddraw); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface4_IsLost(surface); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface4_Flip(surface, NULL, DDFLIP_WAIT); + ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#x.\n", hr); + + hr = IDirectDraw4_SetCooperativeLevel(ddraw, window2, DDSCL_NORMAL | DDSCL_FULLSCREEN); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDraw4_TestCooperativeLevel(ddraw); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface4_IsLost(surface); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface4_Flip(surface, NULL, DDFLIP_WAIT); + ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#x.\n", hr); + + hr = IDirectDraw4_SetCooperativeLevel(ddraw, window2, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDraw4_TestCooperativeLevel(ddraw); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface4_IsLost(surface); + ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface4_Flip(surface, NULL, DDFLIP_WAIT); + ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr); + IDirectDrawSurface4_Release(surface); refcount = IDirectDraw4_Release(ddraw); ok(!refcount, "Got unexpected refcount %u.\n", refcount); - DestroyWindow(window); + DestroyWindow(window2); + DestroyWindow(window1); } static void test_surface_desc_lock(void) diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index 57cec093a93..cce86171a39 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -8214,17 +8214,19 @@ static void test_lost_device(void) { IDirectDrawSurface7 *surface; DDSURFACEDESC2 surface_desc; + HWND window1, window2; IDirectDraw7 *ddraw; ULONG refcount; - HWND window; HRESULT hr; BOOL ret; - window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, + window1 = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, + 0, 0, 640, 480, 0, 0, 0, 0); + window2 = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, 0, 0); ddraw = create_ddraw(); ok(!!ddraw, "Failed to create a ddraw object.\n"); - hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); + hr = IDirectDraw7_SetCooperativeLevel(ddraw, window1, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr); memset(&surface_desc, 0, sizeof(surface_desc)); @@ -8251,7 +8253,7 @@ static void test_lost_device(void) hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT); ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr); - ret = SetForegroundWindow(window); + ret = SetForegroundWindow(window1); ok(ret, "Failed to set foreground window.\n"); hr = IDirectDraw7_TestCooperativeLevel(ddraw); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); @@ -8269,14 +8271,14 @@ static void test_lost_device(void) hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); - hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL); + hr = IDirectDraw7_SetCooperativeLevel(ddraw, window1, DDSCL_NORMAL); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirectDraw7_TestCooperativeLevel(ddraw); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirectDrawSurface7_IsLost(surface); - ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr); + todo_wine ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr); hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT); - ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr); + todo_wine ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr); /* Trying to restore the primary will crash, probably because flippable * surfaces can't exist in DDSCL_NORMAL. */ @@ -8300,14 +8302,14 @@ static void test_lost_device(void) hr = IDirectDrawSurface7_IsLost(surface); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); - ret = SetForegroundWindow(window); + ret = SetForegroundWindow(window1); ok(ret, "Failed to set foreground window.\n"); hr = IDirectDraw7_TestCooperativeLevel(ddraw); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirectDrawSurface7_IsLost(surface); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); - hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); + hr = IDirectDraw7_SetCooperativeLevel(ddraw, window1, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); hr = IDirectDraw7_TestCooperativeLevel(ddraw); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); @@ -8321,10 +8323,74 @@ static void test_lost_device(void) hr = IDirectDrawSurface7_IsLost(surface); ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + IDirectDrawSurface7_Release(surface); + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; + surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP; + U5(surface_desc).dwBackBufferCount = 1; + hr = IDirectDraw7_CreateSurface(ddraw, &surface_desc, &surface, NULL); + ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr); + + hr = IDirectDraw7_SetCooperativeLevel(ddraw, window1, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDraw7_TestCooperativeLevel(ddraw); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface7_IsLost(surface); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + + hr = IDirectDraw7_SetCooperativeLevel(ddraw, window1, DDSCL_NORMAL | DDSCL_FULLSCREEN); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDraw7_TestCooperativeLevel(ddraw); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface7_IsLost(surface); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT); + ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#x.\n", hr); + + hr = IDirectDraw7_SetCooperativeLevel(ddraw, window1, DDSCL_NORMAL); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDraw7_TestCooperativeLevel(ddraw); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface7_IsLost(surface); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT); + ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#x.\n", hr); + + hr = IDirectDraw7_SetCooperativeLevel(ddraw, window2, DDSCL_NORMAL); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDraw7_TestCooperativeLevel(ddraw); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface7_IsLost(surface); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT); + ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#x.\n", hr); + + hr = IDirectDraw7_SetCooperativeLevel(ddraw, window2, DDSCL_NORMAL | DDSCL_FULLSCREEN); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDraw7_TestCooperativeLevel(ddraw); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface7_IsLost(surface); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT); + ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#x.\n", hr); + + hr = IDirectDraw7_SetCooperativeLevel(ddraw, window2, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDraw7_TestCooperativeLevel(ddraw); + ok(hr == DD_OK, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface7_IsLost(surface); + ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr); + hr = IDirectDrawSurface7_Flip(surface, NULL, DDFLIP_WAIT); + ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#x.\n", hr); + IDirectDrawSurface7_Release(surface); refcount = IDirectDraw7_Release(ddraw); ok(!refcount, "Got unexpected refcount %u.\n", refcount); - DestroyWindow(window); + DestroyWindow(window2); + DestroyWindow(window1); } static void test_resource_priority(void)