- sync d3d8, d3d9 with wine
[reactos.git] / reactos / dll / directx / wine / 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 }