wined3d: Store the device window in the swapchain.
[wine] / dlls / wined3d / swapchain_base.c
1 /*
2  *IDirect3DSwapChain9 implementation
3  *
4  *Copyright 2002-2003 Jason Edmeades
5  *Copyright 2002-2003 Raphael Junqueira
6  *Copyright 2005 Oliver Stieber
7  *Copyright 2007-2008 Stefan Dösinger for CodeWeavers
8  *
9  *This library is free software; you can redistribute it and/or
10  *modify it under the terms of the GNU Lesser General Public
11  *License as published by the Free Software Foundation; either
12  *version 2.1 of the License, or (at your option) any later version.
13  *
14  *This library is distributed in the hope that it will be useful,
15  *but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  *Lesser General Public License for more details.
18  *
19  *You should have received a copy of the GNU Lesser General Public
20  *License along with this library; if not, write to the Free Software
21  *Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23
24 #include "config.h"
25 #include "wined3d_private.h"
26
27 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
28
29 /* IDirect3DSwapChain IUnknown parts follow: */
30 HRESULT WINAPI IWineD3DBaseSwapChainImpl_QueryInterface(IWineD3DSwapChain *iface, REFIID riid, void **object)
31 {
32     TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
33
34     if (IsEqualGUID(riid, &IID_IWineD3DSwapChain)
35             || IsEqualGUID(riid, &IID_IWineD3DBase)
36             || IsEqualGUID(riid, &IID_IUnknown))
37     {
38         IUnknown_AddRef(iface);
39         *object = iface;
40         return S_OK;
41     }
42
43     WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
44
45     *object = NULL;
46     return E_NOINTERFACE;
47 }
48
49 ULONG WINAPI IWineD3DBaseSwapChainImpl_AddRef(IWineD3DSwapChain *iface) {
50     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
51     DWORD refCount = InterlockedIncrement(&This->ref);
52     TRACE("(%p) : AddRef increasing from %d\n", This, refCount - 1);
53     return refCount;
54 }
55
56 ULONG WINAPI IWineD3DBaseSwapChainImpl_Release(IWineD3DSwapChain *iface) {
57     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
58     DWORD refCount;
59     refCount = InterlockedDecrement(&This->ref);
60     TRACE("(%p) : ReleaseRef to %d\n", This, refCount);
61     if (refCount == 0) {
62         IWineD3DSwapChain_Destroy(iface);
63     }
64     return refCount;
65 }
66
67 HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetParent(IWineD3DSwapChain *iface, IUnknown ** ppParent){
68     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
69     *ppParent = This->parent;
70     IUnknown_AddRef(*ppParent);
71     TRACE("(%p) returning %p\n", This , *ppParent);
72     return WINED3D_OK;
73 }
74
75 HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetFrontBufferData(IWineD3DSwapChain *iface, IWineD3DSurface *pDestSurface) {
76     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
77     POINT start;
78
79     TRACE("(%p) : iface(%p) pDestSurface(%p)\n", This, iface, pDestSurface);
80
81     start.x = 0;
82     start.y = 0;
83
84     if (This->presentParms.Windowed) {
85         MapWindowPoints(This->win_handle, NULL, &start, 1);
86     }
87
88     IWineD3DSurface_BltFast(pDestSurface, start.x, start.y, This->frontBuffer, NULL, 0);
89     return WINED3D_OK;
90 }
91
92 HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetBackBuffer(IWineD3DSwapChain *iface, UINT iBackBuffer, WINED3DBACKBUFFER_TYPE Type, IWineD3DSurface **ppBackBuffer) {
93
94     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
95
96     if (iBackBuffer > This->presentParms.BackBufferCount - 1) {
97         TRACE("Back buffer count out of range\n");
98         /* Native d3d9 doesn't set NULL here, just as wine's d3d9. But set it
99          * here in wined3d to avoid problems in other libs
100          */
101         *ppBackBuffer = NULL;
102         return WINED3DERR_INVALIDCALL;
103     }
104
105     /* Return invalid if there is no backbuffer array, otherwise it will crash when ddraw is
106      * used (there This->backBuffer is always NULL). We need this because this function has
107      * to be called from IWineD3DStateBlockImpl_InitStartupStateBlock to get the default
108      * scissorrect dimensions. */
109     if( !This->backBuffer ) {
110         *ppBackBuffer = NULL;
111         return WINED3DERR_INVALIDCALL;
112     }
113
114     *ppBackBuffer = This->backBuffer[iBackBuffer];
115     TRACE("(%p) : BackBuf %d Type %d  returning %p\n", This, iBackBuffer, Type, *ppBackBuffer);
116
117     /* Note inc ref on returned surface */
118     if(*ppBackBuffer) IWineD3DSurface_AddRef(*ppBackBuffer);
119     return WINED3D_OK;
120
121 }
122
123 HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetRasterStatus(IWineD3DSwapChain *iface, WINED3DRASTER_STATUS *pRasterStatus) {
124     static BOOL warned;
125     pRasterStatus->InVBlank = TRUE;
126     pRasterStatus->ScanLine = 0;
127     /* No openGL equivalent */
128     if (!warned)
129     {
130         FIXME("iface %p, raster_status %p stub!\n", iface, pRasterStatus);
131         warned = TRUE;
132     }
133     return WINED3D_OK;
134 }
135
136 HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetDisplayMode(IWineD3DSwapChain *iface, WINED3DDISPLAYMODE*pMode) {
137     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
138     HRESULT hr;
139
140     TRACE("(%p)->(%p): Calling GetAdapterDisplayMode\n", This, pMode);
141     hr = IWineD3D_GetAdapterDisplayMode(This->device->wined3d, This->device->adapter->ordinal, pMode);
142
143     TRACE("(%p) : returning w(%d) h(%d) rr(%d) fmt(%u,%s)\n", This, pMode->Width, pMode->Height, pMode->RefreshRate,
144           pMode->Format, debug_d3dformat(pMode->Format));
145     return hr;
146 }
147
148 HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetDevice(IWineD3DSwapChain *iface, IWineD3DDevice**ppDevice) {
149     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
150
151     *ppDevice = (IWineD3DDevice *)This->device;
152
153     /* Note  Calling this method will increase the internal reference count
154     on the IDirect3DDevice9 interface. */
155     IWineD3DDevice_AddRef(*ppDevice);
156     TRACE("(%p) : returning %p\n", This, *ppDevice);
157     return WINED3D_OK;
158 }
159
160 HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetPresentParameters(IWineD3DSwapChain *iface, WINED3DPRESENT_PARAMETERS *pPresentationParameters) {
161     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
162     TRACE("(%p)\n", This);
163
164     *pPresentationParameters = This->presentParms;
165
166     return WINED3D_OK;
167 }
168
169 HRESULT WINAPI IWineD3DBaseSwapChainImpl_SetGammaRamp(IWineD3DSwapChain *iface, DWORD Flags, CONST WINED3DGAMMARAMP *pRamp){
170
171     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
172     HDC hDC;
173     TRACE("(%p) : pRamp@%p flags(%d)\n", This, pRamp, Flags);
174     hDC = GetDC(This->device_window);
175     SetDeviceGammaRamp(hDC, (LPVOID)pRamp);
176     ReleaseDC(This->device_window, hDC);
177     return WINED3D_OK;
178
179 }
180
181 HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetGammaRamp(IWineD3DSwapChain *iface, WINED3DGAMMARAMP *pRamp){
182
183     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
184     HDC hDC;
185     TRACE("(%p) : pRamp@%p\n", This, pRamp);
186     hDC = GetDC(This->device_window);
187     GetDeviceGammaRamp(hDC, pRamp);
188     ReleaseDC(This->device_window, hDC);
189     return WINED3D_OK;
190
191 }