shdocvw/tests: Fix test failures on XP SP2 and higher.
[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, LPVOID *ppobj)
31 {
32     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
33     TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppobj);
34     if (IsEqualGUID(riid, &IID_IUnknown)
35         || IsEqualGUID(riid, &IID_IWineD3DBase)
36         || IsEqualGUID(riid, &IID_IWineD3DSwapChain)){
37         IWineD3DSwapChain_AddRef(iface);
38         if(ppobj == NULL){
39             ERR("Query interface called but now data allocated\n");
40             return E_NOINTERFACE;
41         }
42         *ppobj = This;
43         return WINED3D_OK;
44         }
45         *ppobj = 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, D3DCB_DefaultDestroySurface);
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     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
125     static BOOL warned;
126     pRasterStatus->InVBlank = TRUE;
127     pRasterStatus->ScanLine = 0;
128     /* No openGL equivalent */
129     if (!warned)
130     {
131         FIXME("(%p) : stub (once)\n", This);
132         warned = TRUE;
133     }
134     return WINED3D_OK;
135 }
136
137 HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetDisplayMode(IWineD3DSwapChain *iface, WINED3DDISPLAYMODE*pMode) {
138     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
139     HRESULT hr;
140
141     TRACE("(%p)->(%p): Calling GetAdapterDisplayMode\n", This, pMode);
142     hr = IWineD3D_GetAdapterDisplayMode(This->wineD3DDevice->wineD3D, This->wineD3DDevice->adapter->num, pMode);
143
144     TRACE("(%p) : returning w(%d) h(%d) rr(%d) fmt(%u,%s)\n", This, pMode->Width, pMode->Height, pMode->RefreshRate,
145           pMode->Format, debug_d3dformat(pMode->Format));
146     return hr;
147 }
148
149 HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetDevice(IWineD3DSwapChain *iface, IWineD3DDevice**ppDevice) {
150     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
151
152     *ppDevice = (IWineD3DDevice *) This->wineD3DDevice;
153
154     /* Note  Calling this method will increase the internal reference count
155     on the IDirect3DDevice9 interface. */
156     IWineD3DDevice_AddRef(*ppDevice);
157     TRACE("(%p) : returning %p\n", This, *ppDevice);
158     return WINED3D_OK;
159 }
160
161 HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetPresentParameters(IWineD3DSwapChain *iface, WINED3DPRESENT_PARAMETERS *pPresentationParameters) {
162     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
163     TRACE("(%p)\n", This);
164
165     *pPresentationParameters = This->presentParms;
166
167     return WINED3D_OK;
168 }
169
170 HRESULT WINAPI IWineD3DBaseSwapChainImpl_SetGammaRamp(IWineD3DSwapChain *iface, DWORD Flags, CONST WINED3DGAMMARAMP *pRamp){
171
172     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
173     HDC hDC;
174     TRACE("(%p) : pRamp@%p flags(%d)\n", This, pRamp, Flags);
175     hDC = GetDC(This->win_handle);
176     SetDeviceGammaRamp(hDC, (LPVOID)pRamp);
177     ReleaseDC(This->win_handle, hDC);
178     return WINED3D_OK;
179
180 }
181
182 HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetGammaRamp(IWineD3DSwapChain *iface, WINED3DGAMMARAMP *pRamp){
183
184     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
185     HDC hDC;
186     TRACE("(%p) : pRamp@%p\n", This, pRamp);
187     hDC = GetDC(This->win_handle);
188     GetDeviceGammaRamp(hDC, pRamp);
189     ReleaseDC(This->win_handle, hDC);
190     return WINED3D_OK;
191
192 }