Module: wine Branch: refs/heads/master Commit: 566cdcf55c35eba9ceb07420922d60123dcdb711 URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=566cdcf55c35eba9ceb07420...
Author: Stefan Dösinger stefandoesinger@gmx.at Date: Thu May 18 22:42:22 2006 +0200
wined3d: Implement IWineD3DDevice::SetDisplayMode.
---
dlls/wined3d/device.c | 87 ++++++++++++++++++++++++++++++++++++---- dlls/wined3d/directx.c | 8 ++++ dlls/wined3d/wined3d_private.h | 2 + 3 files changed, 89 insertions(+), 8 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index a612f99..776fca6 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1316,7 +1316,10 @@ #endif *(pPresentationParameters->BackBufferWidth), *(pPresentationParameters->BackBufferHeight), SWP_SHOWWINDOW | SWP_FRAMECHANGED);
- + /* For GetDisplayMode */ + This->ddraw_width = devmode.dmPelsWidth; + This->ddraw_height = devmode.dmPelsHeight; + This->ddraw_format = *(pPresentationParameters->BackBufferFormat); }
@@ -1866,8 +1869,60 @@ HRESULT WINAPI IWineD3DDeviceImpl_EnumDi }
HRESULT WINAPI IWineD3DDeviceImpl_SetDisplayMode(IWineD3DDevice *iface, UINT iSwapChain, WINED3DDISPLAYMODE* pMode) { - FIXME("This call is a d3d7 merge stub. It will be implemented later\n"); - return WINED3DERR_INVALIDCALL; + DEVMODEW devmode; + IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + LONG ret; + + TRACE("(%p)->(%d,%p) Mode=%dx%dx@%d, %s\n", This, iSwapChain, pMode, pMode->Width, pMode->Height, pMode->RefreshRate, debug_d3dformat(pMode->Format)); + + /* Resize the screen even without a window: + * The app could have unset it with SetCooperativeLevel, but not called + * RestoreDisplayMode first. Then the release will call RestoreDisplayMode, + * but we don't have any hwnd + */ + + devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; + devmode.dmBitsPerPel = D3DFmtGetBpp(This, pMode->Format) * 8; + if(devmode.dmBitsPerPel == 24) devmode.dmBitsPerPel = 32; + devmode.dmPelsWidth = pMode->Width; + devmode.dmPelsHeight = pMode->Height; + + devmode.dmDisplayFrequency = pMode->RefreshRate; + if (pMode->RefreshRate != 0) { + devmode.dmFields |= DM_DISPLAYFREQUENCY; + } + + /* Only change the mode if necessary */ + if( (This->ddraw_width == pMode->Width) && + (This->ddraw_height == pMode->Height) && + (This->ddraw_format == pMode->Format) && + (pMode->RefreshRate == 0) ) { + return D3D_OK; + } + + ret = ChangeDisplaySettingsExW(NULL, &devmode, NULL, CDS_FULLSCREEN, NULL); + if (ret != DISP_CHANGE_SUCCESSFUL) { + if(devmode.dmDisplayFrequency != 0) { + WARN("ChangeDisplaySettingsExW failed, trying without the refresh rate\n"); + devmode.dmFields &= ~DM_DISPLAYFREQUENCY; + devmode.dmDisplayFrequency = 0; + ret = ChangeDisplaySettingsExW(NULL, &devmode, NULL, CDS_FULLSCREEN, NULL) != DISP_CHANGE_SUCCESSFUL; + } + if(ret != DISP_CHANGE_SUCCESSFUL) { + return DDERR_INVALIDMODE; + } + } + + /* Store the new values */ + This->ddraw_width = pMode->Width; + This->ddraw_height = pMode->Height; + This->ddraw_format = pMode->Format; + + /* Only do this with a window of course */ + if(This->ddraw_window) + MoveWindow(This->ddraw_window, 0, 0, pMode->Width, pMode->Height, TRUE); + + return WINED3D_OK; }
HRESULT WINAPI IWineD3DDeviceImpl_EnumZBufferFormats(IWineD3DDevice *iface, D3DCB_ENUMPIXELFORMATS Callback, void *Context) { @@ -5265,13 +5320,29 @@ HRESULT WINAPI IWineD3DDeviceImpl_GetDis IWineD3DSwapChain *swapChain; HRESULT hr;
- hr = IWineD3DDeviceImpl_GetSwapChain(iface, iSwapChain, (IWineD3DSwapChain **)&swapChain); - if (hr == WINED3D_OK) { - hr = IWineD3DSwapChain_GetDisplayMode(swapChain, pMode); - IWineD3DSwapChain_Release(swapChain); + if(iSwapChain > 0) { + hr = IWineD3DDeviceImpl_GetSwapChain(iface, iSwapChain, (IWineD3DSwapChain **)&swapChain); + if (hr == WINED3D_OK) { + hr = IWineD3DSwapChain_GetDisplayMode(swapChain, pMode); + IWineD3DSwapChain_Release(swapChain); + } else { + FIXME("(%p) Error getting display mode\n", This); + } } else { - FIXME("(%p) Error getting display mode\n", This); + /* Don't read the real display mode, + but return the stored mode instead. X11 can't change the color + depth, and some apps are pretty angry if they SetDisplayMode from + 24 to 16 bpp and find out that GetDisplayMode still returns 24 bpp + + Also don't relay to the swapchain because with ddraw it's possible + that there isn't a swapchain at all */ + pMode->Width = This->ddraw_width; + pMode->Height = This->ddraw_height; + pMode->Format = This->ddraw_format; + pMode->RefreshRate = 0; + hr = WINED3D_OK; } + return hr; }
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 9b1813a..788fbf0 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -1772,6 +1772,7 @@ HRESULT WINAPI IWineD3DImpl_CreateDevi
IWineD3DDeviceImpl *object = NULL; IWineD3DImpl *This = (IWineD3DImpl *)iface; + HDC hDC;
/* Validate the adapter number */ if (Adapter >= IWineD3D_GetAdapterCount(iface)) { @@ -1831,6 +1832,13 @@ HRESULT WINAPI IWineD3DImpl_CreateDevi /* set the state of the device to valid */ object->state = WINED3D_OK;
+ /* Get the initial screen setup for ddraw */ + object->ddraw_width = GetSystemMetrics(SM_CXSCREEN); + object->ddraw_height = GetSystemMetrics(SM_CYSCREEN); + hDC = CreateDCA("DISPLAY", NULL, NULL, NULL); + object->ddraw_format = pixelformat_for_depth(GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES)); + DeleteDC(hDC); + return WINED3D_OK; create_device_error:
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 6754877..ebb2d86 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -567,6 +567,8 @@ #define NEEDS_DI /* DirectDraw stuff */ HWND ddraw_window; IWineD3DSurface *ddraw_primary; + DWORD ddraw_width, ddraw_height; + WINED3DFORMAT ddraw_format;
} IWineD3DDeviceImpl;