diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c index d2855891f37..c3e59f7fd39 100644 --- a/dlls/ddraw/ddraw.c +++ b/dlls/ddraw/ddraw.c @@ -4,6 +4,7 @@ * Copyright 2000-2001 TransGaming Technologies Inc. * Copyright 2006 Stefan Dösinger * Copyright 2008 Denver Gingerich + * Copyright 2007-2008, 2011, 2013 Stefan Dösinger for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -652,6 +653,75 @@ static HRESULT ddraw_create_swapchain(struct ddraw *ddraw, HWND window, BOOL win return DD_OK; } +/***************************************************************************** + * IDirectDraw7::RestoreDisplayMode + * + * Restores the display mode to what it was at creation time. Basically. + * + * Returns + * DD_OK on success + * DDERR_NOEXCLUSIVE mode if the device isn't in fullscreen mode + * + *****************************************************************************/ +static HRESULT WINAPI ddraw7_RestoreDisplayMode(IDirectDraw7 *iface) +{ + struct ddraw *ddraw = impl_from_IDirectDraw7(iface); + HRESULT hr; + + TRACE("iface %p.\n", iface); + + wined3d_mutex_lock(); + + if (!(ddraw->flags & DDRAW_RESTORE_MODE)) + { + wined3d_mutex_unlock(); + return DD_OK; + } + + if (exclusive_ddraw && exclusive_ddraw != ddraw) + { + wined3d_mutex_unlock(); + return DDERR_NOEXCLUSIVEMODE; + } + + if (SUCCEEDED(hr = wined3d_set_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &original_mode))) + { + ddraw->flags &= ~DDRAW_RESTORE_MODE; + restore_mode = FALSE; + } + + wined3d_mutex_unlock(); + + return hr; +} + +static HRESULT WINAPI ddraw4_RestoreDisplayMode(IDirectDraw4 *iface) +{ + struct ddraw *ddraw = impl_from_IDirectDraw4(iface); + + TRACE("iface %p.\n", iface); + + return ddraw7_RestoreDisplayMode(&ddraw->IDirectDraw7_iface); +} + +static HRESULT WINAPI ddraw2_RestoreDisplayMode(IDirectDraw2 *iface) +{ + struct ddraw *ddraw = impl_from_IDirectDraw2(iface); + + TRACE("iface %p.\n", iface); + + return ddraw7_RestoreDisplayMode(&ddraw->IDirectDraw7_iface); +} + +static HRESULT WINAPI ddraw1_RestoreDisplayMode(IDirectDraw *iface) +{ + struct ddraw *ddraw = impl_from_IDirectDraw(iface); + + TRACE("iface %p.\n", iface); + + return ddraw7_RestoreDisplayMode(&ddraw->IDirectDraw7_iface); +} + /***************************************************************************** * IDirectDraw7::SetCooperativeLevel * @@ -696,15 +766,16 @@ static HRESULT ddraw_create_swapchain(struct ddraw *ddraw, HWND window, BOOL win * (Probably others too, have to investigate) * *****************************************************************************/ -static HRESULT WINAPI ddraw7_SetCooperativeLevel(IDirectDraw7 *iface, HWND window, DWORD cooplevel) +static HRESULT WINAPI ddraw_set_cooperative_level(struct ddraw *ddraw, HWND window, + DWORD cooplevel, BOOL restore_mode_on_normal) { - struct ddraw *This = impl_from_IDirectDraw7(iface); struct wined3d_surface *rt = NULL, *ds = NULL; struct wined3d_stateblock *stateblock; BOOL restore_state = FALSE; HRESULT hr; - TRACE("iface %p, window %p, flags %#x.\n", iface, window, cooplevel); + TRACE("ddraw %p, window %p, flags %#x, restore_mode_on_normal %x.\n", ddraw, window, cooplevel, + restore_mode_on_normal); DDRAW_dump_cooperativelevel(cooplevel); wined3d_mutex_lock(); @@ -745,7 +816,7 @@ static HRESULT WINAPI ddraw7_SetCooperativeLevel(IDirectDraw7 *iface, HWND windo return DDERR_INVALIDPARAMS; } - hr = ddraw_set_focus_window(This, window); + hr = ddraw_set_focus_window(ddraw, window); wined3d_mutex_unlock(); return hr; } @@ -763,7 +834,7 @@ static HRESULT WINAPI ddraw7_SetCooperativeLevel(IDirectDraw7 *iface, HWND windo { HWND device_window; - if (!This->focuswindow && !(cooplevel & DDSCL_SETFOCUSWINDOW)) + if (!ddraw->focuswindow && !(cooplevel & DDSCL_SETFOCUSWINDOW)) { WARN("No focus window set.\n"); wined3d_mutex_unlock(); @@ -785,8 +856,8 @@ static HRESULT WINAPI ddraw7_SetCooperativeLevel(IDirectDraw7 *iface, HWND windo /* Native apparently leaks the created device window if setting the * focus window below fails. */ - This->cooperative_level |= DDSCL_CREATEDEVICEWINDOW; - This->devicewindow = device_window; + ddraw->cooperative_level |= DDSCL_CREATEDEVICEWINDOW; + ddraw->devicewindow = device_window; if (cooplevel & DDSCL_SETFOCUSWINDOW) { @@ -796,7 +867,7 @@ static HRESULT WINAPI ddraw7_SetCooperativeLevel(IDirectDraw7 *iface, HWND windo return DDERR_NOHWND; } - if (FAILED(hr = ddraw_set_focus_window(This, window))) + if (FAILED(hr = ddraw_set_focus_window(ddraw, window))) { wined3d_mutex_unlock(); return hr; @@ -808,37 +879,37 @@ static HRESULT WINAPI ddraw7_SetCooperativeLevel(IDirectDraw7 *iface, HWND windo } else { - if (This->cooperative_level & DDSCL_CREATEDEVICEWINDOW) - DestroyWindow(This->devicewindow); - This->devicewindow = NULL; - This->focuswindow = NULL; + if (ddraw->cooperative_level & DDSCL_CREATEDEVICEWINDOW) + DestroyWindow(ddraw->devicewindow); + ddraw->devicewindow = NULL; + ddraw->focuswindow = NULL; } - if ((cooplevel & DDSCL_FULLSCREEN) != (This->cooperative_level & DDSCL_FULLSCREEN) || window != This->dest_window) + if ((cooplevel & DDSCL_FULLSCREEN) != (ddraw->cooperative_level & DDSCL_FULLSCREEN) || window != ddraw->dest_window) { - if (This->cooperative_level & DDSCL_FULLSCREEN) - wined3d_device_restore_fullscreen_window(This->wined3d_device, This->dest_window); + if (ddraw->cooperative_level & DDSCL_FULLSCREEN) + wined3d_device_restore_fullscreen_window(ddraw->wined3d_device, ddraw->dest_window); if (cooplevel & DDSCL_FULLSCREEN) { struct wined3d_display_mode display_mode; - wined3d_get_adapter_display_mode(This->wined3d, WINED3DADAPTER_DEFAULT, &display_mode, NULL); - wined3d_device_setup_fullscreen_window(This->wined3d_device, window, + wined3d_get_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &display_mode, NULL); + wined3d_device_setup_fullscreen_window(ddraw->wined3d_device, window, display_mode.width, display_mode.height); } } - if (cooplevel & DDSCL_MULTITHREADED && !(This->cooperative_level & DDSCL_MULTITHREADED)) - wined3d_device_set_multithreaded(This->wined3d_device); + if (cooplevel & DDSCL_MULTITHREADED && !(ddraw->cooperative_level & DDSCL_MULTITHREADED)) + wined3d_device_set_multithreaded(ddraw->wined3d_device); - if (This->wined3d_swapchain) + if (ddraw->wined3d_swapchain) { - if (!(This->flags & DDRAW_NO3D)) + if (!(ddraw->flags & DDRAW_NO3D)) { restore_state = TRUE; - if (FAILED(hr = wined3d_stateblock_create(This->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); wined3d_mutex_unlock(); @@ -846,33 +917,33 @@ static HRESULT WINAPI ddraw7_SetCooperativeLevel(IDirectDraw7 *iface, HWND windo } wined3d_stateblock_capture(stateblock); - rt = wined3d_device_get_render_target(This->wined3d_device, 0); - if (rt == This->wined3d_frontbuffer) + rt = wined3d_device_get_render_target(ddraw->wined3d_device, 0); + if (rt == ddraw->wined3d_frontbuffer) rt = NULL; else if (rt) wined3d_surface_incref(rt); - if ((ds = wined3d_device_get_depth_stencil(This->wined3d_device))) + if ((ds = wined3d_device_get_depth_stencil(ddraw->wined3d_device))) wined3d_surface_incref(ds); } - ddraw_destroy_swapchain(This); + ddraw_destroy_swapchain(ddraw); } - if (FAILED(hr = ddraw_create_swapchain(This, window, !(cooplevel & DDSCL_FULLSCREEN)))) + if (FAILED(hr = ddraw_create_swapchain(ddraw, window, !(cooplevel & DDSCL_FULLSCREEN)))) ERR("Failed to create swapchain, hr %#x.\n", hr); if (restore_state) { if (ds) { - wined3d_device_set_depth_stencil(This->wined3d_device, ds); + wined3d_device_set_depth_stencil(ddraw->wined3d_device, ds); wined3d_surface_decref(ds); } if (rt) { - wined3d_device_set_render_target(This->wined3d_device, 0, rt, FALSE); + wined3d_device_set_render_target(ddraw->wined3d_device, 0, rt, FALSE); wined3d_surface_decref(rt); } @@ -880,14 +951,22 @@ static HRESULT WINAPI ddraw7_SetCooperativeLevel(IDirectDraw7 *iface, HWND windo wined3d_stateblock_decref(stateblock); } - if ((This->cooperative_level & DDSCL_EXCLUSIVE) - && (window != This->dest_window || !(cooplevel & DDSCL_EXCLUSIVE))) - wined3d_device_release_focus_window(This->wined3d_device); + if (!(cooplevel & DDSCL_EXCLUSIVE) && (ddraw->cooperative_level & DDSCL_EXCLUSIVE) + && restore_mode_on_normal) + { + hr = ddraw7_RestoreDisplayMode(&ddraw->IDirectDraw7_iface); + if (FAILED(hr)) + ERR("RestoreDisplayMode failed\n"); + } + + if ((ddraw->cooperative_level & DDSCL_EXCLUSIVE) + && (window != ddraw->dest_window || !(cooplevel & DDSCL_EXCLUSIVE))) + wined3d_device_release_focus_window(ddraw->wined3d_device); if ((cooplevel & DDSCL_EXCLUSIVE) - && (window != This->dest_window || !(This->cooperative_level & DDSCL_EXCLUSIVE))) + && (window != ddraw->dest_window || !(ddraw->cooperative_level & DDSCL_EXCLUSIVE))) { - hr = wined3d_device_acquire_focus_window(This->wined3d_device, window); + hr = wined3d_device_acquire_focus_window(ddraw->wined3d_device, window); if (FAILED(hr)) { ERR("Failed to acquire focus window, hr %#x.\n", hr); @@ -897,34 +976,44 @@ static HRESULT WINAPI ddraw7_SetCooperativeLevel(IDirectDraw7 *iface, HWND windo } /* Unhandled flags */ - if(cooplevel & DDSCL_ALLOWREBOOT) - WARN("(%p) Unhandled flag DDSCL_ALLOWREBOOT, harmless\n", This); - if(cooplevel & DDSCL_ALLOWMODEX) - WARN("(%p) Unhandled flag DDSCL_ALLOWMODEX, harmless\n", This); - if(cooplevel & DDSCL_FPUSETUP) - WARN("(%p) Unhandled flag DDSCL_FPUSETUP, harmless\n", This); + if (cooplevel & DDSCL_ALLOWREBOOT) + WARN("Unhandled flag DDSCL_ALLOWREBOOT, harmless\n"); + if (cooplevel & DDSCL_ALLOWMODEX) + WARN("Unhandled flag DDSCL_ALLOWMODEX, harmless\n"); + if (cooplevel & DDSCL_FPUSETUP) + WARN("Unhandled flag DDSCL_FPUSETUP, harmless\n"); if (cooplevel & DDSCL_EXCLUSIVE) - exclusive_ddraw = This; - else if (exclusive_ddraw == This) + exclusive_ddraw = ddraw; + else if (exclusive_ddraw == ddraw) exclusive_ddraw = NULL; /* Store the cooperative_level */ - This->cooperative_level = cooplevel; - This->dest_window = window; + ddraw->cooperative_level = cooplevel; + ddraw->dest_window = window; + TRACE("SetCooperativeLevel retuning DD_OK\n"); wined3d_mutex_unlock(); return DD_OK; } +static HRESULT WINAPI ddraw7_SetCooperativeLevel(IDirectDraw7 *iface, HWND window, DWORD flags) +{ + struct ddraw *ddraw = impl_from_IDirectDraw7(iface); + + TRACE("iface %p, window %p, flags %#x.\n", iface, window, flags); + + return ddraw_set_cooperative_level(ddraw, window, flags, !(ddraw->flags & DDRAW_SCL_DDRAW1)); +} + static HRESULT WINAPI ddraw4_SetCooperativeLevel(IDirectDraw4 *iface, HWND window, DWORD flags) { struct ddraw *ddraw = impl_from_IDirectDraw4(iface); TRACE("iface %p, window %p, flags %#x.\n", iface, window, flags); - return ddraw7_SetCooperativeLevel(&ddraw->IDirectDraw7_iface, window, flags); + return ddraw_set_cooperative_level(ddraw, window, flags, !(ddraw->flags & DDRAW_SCL_DDRAW1)); } static HRESULT WINAPI ddraw2_SetCooperativeLevel(IDirectDraw2 *iface, HWND window, DWORD flags) @@ -933,16 +1022,20 @@ static HRESULT WINAPI ddraw2_SetCooperativeLevel(IDirectDraw2 *iface, HWND windo TRACE("iface %p, window %p, flags %#x.\n", iface, window, flags); - return ddraw7_SetCooperativeLevel(&ddraw->IDirectDraw7_iface, window, flags); + return ddraw_set_cooperative_level(ddraw, window, flags, !(ddraw->flags & DDRAW_SCL_DDRAW1)); } static HRESULT WINAPI ddraw1_SetCooperativeLevel(IDirectDraw *iface, HWND window, DWORD flags) { struct ddraw *ddraw = impl_from_IDirectDraw(iface); + HRESULT hr; TRACE("iface %p, window %p, flags %#x.\n", iface, window, flags); - return ddraw7_SetCooperativeLevel(&ddraw->IDirectDraw7_iface, window, flags); + hr = ddraw_set_cooperative_level(ddraw, window, flags, FALSE); + if (SUCCEEDED(hr)) + ddraw->flags |= DDRAW_SCL_DDRAW1; + return hr; } /***************************************************************************** @@ -1069,75 +1162,6 @@ static HRESULT WINAPI ddraw1_SetDisplayMode(IDirectDraw *iface, DWORD width, DWO return ddraw7_SetDisplayMode(&ddraw->IDirectDraw7_iface, width, height, bpp, 0, 0); } -/***************************************************************************** - * IDirectDraw7::RestoreDisplayMode - * - * Restores the display mode to what it was at creation time. Basically. - * - * Returns - * DD_OK on success - * DDERR_NOEXCLUSIVE mode if the device isn't in fullscreen mode - * - *****************************************************************************/ -static HRESULT WINAPI ddraw7_RestoreDisplayMode(IDirectDraw7 *iface) -{ - struct ddraw *ddraw = impl_from_IDirectDraw7(iface); - HRESULT hr; - - TRACE("iface %p.\n", iface); - - wined3d_mutex_lock(); - - if (!(ddraw->flags & DDRAW_RESTORE_MODE)) - { - wined3d_mutex_unlock(); - return DD_OK; - } - - if (exclusive_ddraw && exclusive_ddraw != ddraw) - { - wined3d_mutex_unlock(); - return DDERR_NOEXCLUSIVEMODE; - } - - if (SUCCEEDED(hr = wined3d_set_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &original_mode))) - { - ddraw->flags &= ~DDRAW_RESTORE_MODE; - restore_mode = FALSE; - } - - wined3d_mutex_unlock(); - - return hr; -} - -static HRESULT WINAPI ddraw4_RestoreDisplayMode(IDirectDraw4 *iface) -{ - struct ddraw *ddraw = impl_from_IDirectDraw4(iface); - - TRACE("iface %p.\n", iface); - - return ddraw7_RestoreDisplayMode(&ddraw->IDirectDraw7_iface); -} - -static HRESULT WINAPI ddraw2_RestoreDisplayMode(IDirectDraw2 *iface) -{ - struct ddraw *ddraw = impl_from_IDirectDraw2(iface); - - TRACE("iface %p.\n", iface); - - return ddraw7_RestoreDisplayMode(&ddraw->IDirectDraw7_iface); -} - -static HRESULT WINAPI ddraw1_RestoreDisplayMode(IDirectDraw *iface) -{ - struct ddraw *ddraw = impl_from_IDirectDraw(iface); - - TRACE("iface %p.\n", iface); - - return ddraw7_RestoreDisplayMode(&ddraw->IDirectDraw7_iface); -} - /***************************************************************************** * IDirectDraw7::GetCaps * diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h index 83777321493..7408a2b3b89 100644 --- a/dlls/ddraw/ddraw_private.h +++ b/dlls/ddraw/ddraw_private.h @@ -53,6 +53,7 @@ struct FvfToDecl #define DDRAW_D3D_INITIALIZED 0x00000002 #define DDRAW_RESTORE_MODE 0x00000004 #define DDRAW_NO3D 0x00000008 +#define DDRAW_SCL_DDRAW1 0x00000010 struct ddraw {