ddraw: Gracefully handle recursive SetCooperativeLevel calls.

This commit is contained in:
Stefan Dösinger 2013-09-02 11:22:30 +02:00 committed by Alexandre Julliard
parent 21c1706f79
commit 769dd6d158
2 changed files with 31 additions and 25 deletions

View File

@ -778,21 +778,29 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
wined3d_mutex_lock(); wined3d_mutex_lock();
if (ddraw->flags & DDRAW_SCL_RECURSIVE)
{
WARN("Recursive call, returning DD_OK.\n");
hr = DD_OK;
goto done;
}
ddraw->flags |= DDRAW_SCL_RECURSIVE;
/* Tests suggest that we need one of them: */ /* Tests suggest that we need one of them: */
if(!(cooplevel & (DDSCL_SETFOCUSWINDOW | if(!(cooplevel & (DDSCL_SETFOCUSWINDOW |
DDSCL_NORMAL | DDSCL_NORMAL |
DDSCL_EXCLUSIVE ))) DDSCL_EXCLUSIVE )))
{ {
TRACE("Incorrect cooplevel flags, returning DDERR_INVALIDPARAMS\n"); TRACE("Incorrect cooplevel flags, returning DDERR_INVALIDPARAMS\n");
wined3d_mutex_unlock(); hr = DDERR_INVALIDPARAMS;
return DDERR_INVALIDPARAMS; goto done;
} }
if ((cooplevel & DDSCL_CREATEDEVICEWINDOW) && !(cooplevel & DDSCL_EXCLUSIVE)) if ((cooplevel & DDSCL_CREATEDEVICEWINDOW) && !(cooplevel & DDSCL_EXCLUSIVE))
{ {
WARN("DDSCL_CREATEDEVICEWINDOW requires DDSCL_EXCLUSIVE.\n"); WARN("DDSCL_CREATEDEVICEWINDOW requires DDSCL_EXCLUSIVE.\n");
wined3d_mutex_unlock(); hr = DDERR_INVALIDPARAMS;
return DDERR_INVALIDPARAMS; goto done;
} }
/* Handle those levels first which set various hwnds */ /* Handle those levels first which set various hwnds */
@ -810,13 +818,12 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
| DDSCL_FULLSCREEN)) | DDSCL_FULLSCREEN))
{ {
WARN("Called with incompatible flags, returning DDERR_INVALIDPARAMS.\n"); WARN("Called with incompatible flags, returning DDERR_INVALIDPARAMS.\n");
wined3d_mutex_unlock(); hr = DDERR_INVALIDPARAMS;
return DDERR_INVALIDPARAMS; goto done;
} }
hr = ddraw_set_focus_window(ddraw, window); hr = ddraw_set_focus_window(ddraw, window);
wined3d_mutex_unlock(); goto done;
return hr;
} }
if (cooplevel & DDSCL_EXCLUSIVE) if (cooplevel & DDSCL_EXCLUSIVE)
@ -824,8 +831,8 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
if (!(cooplevel & DDSCL_FULLSCREEN) || !(window || (cooplevel & DDSCL_CREATEDEVICEWINDOW))) if (!(cooplevel & DDSCL_FULLSCREEN) || !(window || (cooplevel & DDSCL_CREATEDEVICEWINDOW)))
{ {
WARN("DDSCL_EXCLUSIVE requires DDSCL_FULLSCREEN and a window.\n"); WARN("DDSCL_EXCLUSIVE requires DDSCL_FULLSCREEN and a window.\n");
wined3d_mutex_unlock(); hr = DDERR_INVALIDPARAMS;
return DDERR_INVALIDPARAMS; goto done;
} }
if (cooplevel & DDSCL_CREATEDEVICEWINDOW) if (cooplevel & DDSCL_CREATEDEVICEWINDOW)
@ -835,8 +842,8 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
if (!ddraw->focuswindow && !(cooplevel & DDSCL_SETFOCUSWINDOW)) if (!ddraw->focuswindow && !(cooplevel & DDSCL_SETFOCUSWINDOW))
{ {
WARN("No focus window set.\n"); WARN("No focus window set.\n");
wined3d_mutex_unlock(); hr = DDERR_NOFOCUSWINDOW;
return DDERR_NOFOCUSWINDOW; goto done;
} }
device_window = CreateWindowExA(0, DDRAW_WINDOW_CLASS_NAME, "DirectDrawDeviceWnd", device_window = CreateWindowExA(0, DDRAW_WINDOW_CLASS_NAME, "DirectDrawDeviceWnd",
@ -845,8 +852,8 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
if (!device_window) if (!device_window)
{ {
ERR("Failed to create window, last error %#x.\n", GetLastError()); ERR("Failed to create window, last error %#x.\n", GetLastError());
wined3d_mutex_unlock(); hr = E_FAIL;
return E_FAIL; goto done;
} }
ShowWindow(device_window, SW_SHOW); ShowWindow(device_window, SW_SHOW);
@ -861,15 +868,12 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
{ {
if (!window) if (!window)
{ {
wined3d_mutex_unlock(); hr = DDERR_NOHWND;
return DDERR_NOHWND; goto done;
} }
if (FAILED(hr = ddraw_set_focus_window(ddraw, window))) if (FAILED(hr = ddraw_set_focus_window(ddraw, window)))
{ goto done;
wined3d_mutex_unlock();
return hr;
}
} }
window = device_window; window = device_window;
@ -910,8 +914,7 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
if (FAILED(hr = wined3d_stateblock_create(ddraw->wined3d_device, WINED3D_SBT_ALL, &stateblock))) if (FAILED(hr = wined3d_stateblock_create(ddraw->wined3d_device, WINED3D_SBT_ALL, &stateblock)))
{ {
ERR("Failed to create stateblock, hr %#x.\n", hr); ERR("Failed to create stateblock, hr %#x.\n", hr);
wined3d_mutex_unlock(); goto done;
return hr;
} }
wined3d_stateblock_capture(stateblock); wined3d_stateblock_capture(stateblock);
@ -968,8 +971,7 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
if (FAILED(hr)) if (FAILED(hr))
{ {
ERR("Failed to acquire focus window, hr %#x.\n", hr); ERR("Failed to acquire focus window, hr %#x.\n", hr);
wined3d_mutex_unlock(); goto done;
return hr;
} }
} }
@ -991,9 +993,12 @@ static HRESULT ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window,
ddraw->dest_window = window; ddraw->dest_window = window;
TRACE("SetCooperativeLevel retuning DD_OK\n"); TRACE("SetCooperativeLevel retuning DD_OK\n");
hr = DD_OK;
done:
ddraw->flags &= ~DDRAW_SCL_RECURSIVE;
wined3d_mutex_unlock(); wined3d_mutex_unlock();
return DD_OK; return hr;
} }
static HRESULT WINAPI ddraw7_SetCooperativeLevel(IDirectDraw7 *iface, HWND window, DWORD flags) static HRESULT WINAPI ddraw7_SetCooperativeLevel(IDirectDraw7 *iface, HWND window, DWORD flags)

View File

@ -54,6 +54,7 @@ struct FvfToDecl
#define DDRAW_RESTORE_MODE 0x00000004 #define DDRAW_RESTORE_MODE 0x00000004
#define DDRAW_NO3D 0x00000008 #define DDRAW_NO3D 0x00000008
#define DDRAW_SCL_DDRAW1 0x00000010 #define DDRAW_SCL_DDRAW1 0x00000010
#define DDRAW_SCL_RECURSIVE 0x00000020
#define DDRAW_STRIDE_ALIGNMENT 8 #define DDRAW_STRIDE_ALIGNMENT 8