ddraw: d3d7 does not support two sided stencil.
[wine] / dlls / ddraw / clipper.c
1 /* DirectDrawClipper implementation
2  *
3  * Copyright 2000 (c) Marcus Meissner
4  * Copyright 2000 (c) TransGaming Technologies Inc.
5  * Copyright 2006 (c) Stefan Dösinger
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #include "config.h"
23
24 #include <stdarg.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 #define COBJMACROS
29
30 #include "windef.h"
31 #include "winbase.h"
32 #include "wingdi.h"
33 #include "ddraw.h"
34 #include "winerror.h"
35
36 #include "ddraw_private.h"
37
38 #include "wine/debug.h"
39
40 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
41
42 /*****************************************************************************
43  * IUnknown methods
44  *****************************************************************************/
45
46 /*****************************************************************************
47  * IDirectDrawClipper::QueryInterface
48  *
49  * Can query the IUnknown and IDirectDrawClipper interface from a
50  * Clipper object. The IUnknown Interface is equal to the IDirectDrawClipper
51  * interface. Can't create other interfaces.
52  *
53  * Arguments:
54  *  riid: Interface id asked for
55  *  ppvObj: Returns the pointer to the interface
56  *
57  * Return values:
58  *  DD_OK on success
59  *  E_NOINTERFACE if the requested interface wasn't found.
60  *
61  *****************************************************************************/
62 static HRESULT WINAPI IDirectDrawClipperImpl_QueryInterface(
63     LPDIRECTDRAWCLIPPER iface, REFIID riid, LPVOID* ppvObj
64 ) {
65     if (IsEqualGUID(&IID_IUnknown, riid)
66         || IsEqualGUID(&IID_IDirectDrawClipper, riid))
67     {
68         IUnknown_AddRef(iface);
69         *ppvObj = iface;
70         return S_OK;
71     }
72     else
73     {
74         return E_NOINTERFACE;
75     }
76 }
77
78 /*****************************************************************************
79  * IDirectDrawClipper::AddRef
80  *
81  * Increases the reference count of the interface, returns the new count
82  *
83  *****************************************************************************/
84 static ULONG WINAPI IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface )
85 {
86     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
87     ULONG ref = InterlockedIncrement(&This->ref);
88
89     TRACE("(%p)->() incrementing from %u.\n", This, ref - 1);
90
91     return ref;
92 }
93
94 /*****************************************************************************
95  * IDirectDrawClipper::Release
96  *
97  * Decreases the reference count of the interface, returns the new count
98  * If the refcount is decreased to 0, the interface is destroyed.
99  *
100  *****************************************************************************/
101 static ULONG WINAPI IDirectDrawClipperImpl_Release(IDirectDrawClipper *iface) {
102     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
103     ULONG ref = InterlockedDecrement(&This->ref);
104
105     TRACE("(%p)->() decrementing from %u.\n", This, ref + 1);
106
107     if (ref == 0)
108     {
109         EnterCriticalSection(&ddraw_cs);
110         IWineD3DClipper_Release(This->wineD3DClipper);
111         HeapFree(GetProcessHeap(), 0, This);
112         LeaveCriticalSection(&ddraw_cs);
113         return 0;
114     }
115     else return ref;
116 }
117
118 /*****************************************************************************
119  * IDirectDrawClipper::SetHwnd
120  *
121  * Assigns a hWnd to the clipper interface.
122  *
123  * Arguments:
124  *  Flags: Unsupported so far
125  *  hWnd: The hWnd to set
126  *
127  * Return values:
128  *  DD_OK on success
129  *  DDERR_INVALIDPARAMS if Flags was != 0
130  *
131  *****************************************************************************/
132
133 static HRESULT WINAPI IDirectDrawClipperImpl_SetHwnd(
134     LPDIRECTDRAWCLIPPER iface, DWORD dwFlags, HWND hWnd
135 ) {
136     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
137     HRESULT hr;
138     TRACE("(%p)->(%08x,%p)\n", This, dwFlags, hWnd);
139
140     EnterCriticalSection(&ddraw_cs);
141     hr = IWineD3DClipper_SetHWnd(This->wineD3DClipper,
142                                  dwFlags,
143                                  hWnd);
144     LeaveCriticalSection(&ddraw_cs);
145     switch(hr)
146     {
147         case WINED3DERR_INVALIDCALL:        return DDERR_INVALIDPARAMS;
148         default:                            return hr;
149     }
150 }
151
152 /*****************************************************************************
153  * IDirectDrawClipper::GetClipList
154  *
155  * Retrieve a copy of the clip list
156  *
157  * Arguments:
158  *  Rect: Rectangle to be used to clip the clip list or NULL for the
159  *        entire clip list
160  *  ClipList: structure for the resulting copy of the clip list.
161  *            If NULL, fills Size up to the number of bytes necessary to hold
162  *            the entire clip.
163  *  Size: Size of resulting clip list; size of the buffer at ClipList
164  *        or, if ClipList is NULL, receives the required size of the buffer
165  *        in bytes
166  *
167  * RETURNS
168  *  Either DD_OK or DDERR_*
169  ************************************************************************/
170 static HRESULT WINAPI IDirectDrawClipperImpl_GetClipList(
171     LPDIRECTDRAWCLIPPER iface, LPRECT lpRect, LPRGNDATA lpClipList,
172     LPDWORD lpdwSize)
173 {
174     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
175     HRESULT hr;
176     TRACE("(%p,%p,%p,%p)\n", This, lpRect, lpClipList, lpdwSize);
177
178     EnterCriticalSection(&ddraw_cs);
179     hr = IWineD3DClipper_GetClipList(This->wineD3DClipper,
180                                      lpRect,
181                                      lpClipList,
182                                      lpdwSize);
183     LeaveCriticalSection(&ddraw_cs);
184     return hr;
185 }
186
187 /*****************************************************************************
188  * IDirectDrawClipper::SetClipList
189  *
190  * Sets or deletes (if lprgn is NULL) the clip list
191  *
192  * This implementation is a stub and returns DD_OK always to make the app
193  * happy.
194  *
195  * PARAMS
196  *  lprgn   Pointer to a LRGNDATA structure or NULL
197  *  dwFlags not used, must be 0
198  * RETURNS
199  *  Either DD_OK or DDERR_*
200  *****************************************************************************/
201 static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList(
202     LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD dwFlag
203 ) {
204     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
205     HRESULT hr;
206
207     EnterCriticalSection(&ddraw_cs);
208     hr = IWineD3DClipper_SetClipList(This->wineD3DClipper,
209                                      lprgn,
210                                      dwFlag);
211     LeaveCriticalSection(&ddraw_cs);
212     return hr;
213 }
214
215 /*****************************************************************************
216  * IDirectDrawClipper::GetHwnd
217  *
218  * Returns the hwnd assigned with SetHwnd
219  *
220  * Arguments:
221  *  hWndPtr: Address to store the HWND at
222  *
223  * Return values:
224  *  Always returns DD_OK;
225  *****************************************************************************/
226 static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd(
227     LPDIRECTDRAWCLIPPER iface, HWND* hWndPtr
228 ) {
229     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
230     HRESULT hr;
231     TRACE("(%p)->(%p)\n", This, hWndPtr);
232
233     EnterCriticalSection(&ddraw_cs);
234     hr =  IWineD3DClipper_GetHWnd(This->wineD3DClipper,
235                                   hWndPtr);
236     LeaveCriticalSection(&ddraw_cs);
237     return hr;
238 }
239
240 /*****************************************************************************
241  * IDirectDrawClipper::Initialize
242  *
243  * Initializes the interface. Well, there isn't much to do for this
244  * implementation, but it stores the DirectDraw Interface.
245  *
246  * Arguments:
247  *  DD: Pointer to a IDirectDraw interface
248  *  Flags: Unsupported by now
249  *
250  * Return values:
251  *  DD_OK on success
252  *  DDERR_ALREADYINITIALIZED if this interface isn't initialized already
253  *****************************************************************************/
254 static HRESULT WINAPI IDirectDrawClipperImpl_Initialize(
255      LPDIRECTDRAWCLIPPER iface, LPDIRECTDRAW lpDD, DWORD dwFlags
256 ) {
257     IDirectDrawImpl* pOwner;
258     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
259     TRACE("(%p)->(%p,0x%08x)\n", This, lpDD, dwFlags);
260
261     EnterCriticalSection(&ddraw_cs);
262     if (This->ddraw_owner != NULL)
263     {
264         LeaveCriticalSection(&ddraw_cs);
265         return DDERR_ALREADYINITIALIZED;
266     }
267
268     pOwner = lpDD ? ddraw_from_ddraw1(lpDD) : NULL;
269     This->ddraw_owner = pOwner;
270
271     LeaveCriticalSection(&ddraw_cs);
272     return DD_OK;
273 }
274
275 /*****************************************************************************
276  * IDirectDrawClipper::IsClipListChanged
277  *
278  * This function is a stub
279  *
280  * Arguments:
281  *  Changed:
282  *
283  * Return values:
284  *  DD_OK, because it's a stub
285  *****************************************************************************/
286 static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged(
287     LPDIRECTDRAWCLIPPER iface, BOOL* lpbChanged
288 ) {
289     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
290     FIXME("(%p)->(%p),stub!\n",This,lpbChanged);
291
292     /* XXX What is safest? */
293     *lpbChanged = FALSE;
294
295     return DD_OK;
296 }
297
298 /*****************************************************************************
299  * The VTable
300  *****************************************************************************/
301 const IDirectDrawClipperVtbl IDirectDrawClipper_Vtbl =
302 {
303     IDirectDrawClipperImpl_QueryInterface,
304     IDirectDrawClipperImpl_AddRef,
305     IDirectDrawClipperImpl_Release,
306     IDirectDrawClipperImpl_GetClipList,
307     IDirectDrawClipperImpl_GetHWnd,
308     IDirectDrawClipperImpl_Initialize,
309     IDirectDrawClipperImpl_IsClipListChanged,
310     IDirectDrawClipperImpl_SetClipList,
311     IDirectDrawClipperImpl_SetHwnd
312 };