ddraw: Add / improve TRACEs.
[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 #include "wine/port.h"
24
25 #include "ddraw_private.h"
26
27 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
28
29 /*****************************************************************************
30  * IUnknown methods
31  *****************************************************************************/
32
33 /*****************************************************************************
34  * IDirectDrawClipper::QueryInterface
35  *
36  * Can query the IUnknown and IDirectDrawClipper interface from a
37  * Clipper object. The IUnknown Interface is equal to the IDirectDrawClipper
38  * interface. Can't create other interfaces.
39  *
40  * Arguments:
41  *  riid: Interface id asked for
42  *  ppvObj: Returns the pointer to the interface
43  *
44  * Return values:
45  *  DD_OK on success
46  *  E_NOINTERFACE if the requested interface wasn't found.
47  *
48  *****************************************************************************/
49 static HRESULT WINAPI IDirectDrawClipperImpl_QueryInterface(
50     LPDIRECTDRAWCLIPPER iface, REFIID riid, LPVOID* ppvObj
51 ) {
52
53     TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), ppvObj);
54
55     if (IsEqualGUID(&IID_IUnknown, riid)
56         || IsEqualGUID(&IID_IDirectDrawClipper, riid))
57     {
58         IUnknown_AddRef(iface);
59         *ppvObj = iface;
60         return S_OK;
61     }
62     else
63     {
64         return E_NOINTERFACE;
65     }
66 }
67
68 /*****************************************************************************
69  * IDirectDrawClipper::AddRef
70  *
71  * Increases the reference count of the interface, returns the new count
72  *
73  *****************************************************************************/
74 static ULONG WINAPI IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface )
75 {
76     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
77     ULONG ref = InterlockedIncrement(&This->ref);
78
79     TRACE("%p increasing refcount to %u.\n", This, ref);
80
81     return ref;
82 }
83
84 /*****************************************************************************
85  * IDirectDrawClipper::Release
86  *
87  * Decreases the reference count of the interface, returns the new count
88  * If the refcount is decreased to 0, the interface is destroyed.
89  *
90  *****************************************************************************/
91 static ULONG WINAPI IDirectDrawClipperImpl_Release(IDirectDrawClipper *iface) {
92     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
93     ULONG ref = InterlockedDecrement(&This->ref);
94
95     TRACE("%p decreasing refcount to %u.\n", This, ref);
96
97     if (ref == 0)
98     {
99         EnterCriticalSection(&ddraw_cs);
100         IWineD3DClipper_Release(This->wineD3DClipper);
101         HeapFree(GetProcessHeap(), 0, This);
102         LeaveCriticalSection(&ddraw_cs);
103         return 0;
104     }
105     else return ref;
106 }
107
108 /*****************************************************************************
109  * IDirectDrawClipper::SetHwnd
110  *
111  * Assigns a hWnd to the clipper interface.
112  *
113  * Arguments:
114  *  Flags: Unsupported so far
115  *  hWnd: The hWnd to set
116  *
117  * Return values:
118  *  DD_OK on success
119  *  DDERR_INVALIDPARAMS if Flags was != 0
120  *
121  *****************************************************************************/
122
123 static HRESULT WINAPI IDirectDrawClipperImpl_SetHwnd(
124     LPDIRECTDRAWCLIPPER iface, DWORD dwFlags, HWND hWnd
125 ) {
126     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
127     HRESULT hr;
128
129     TRACE("iface %p, flags %#x, window %p.\n", iface, dwFlags, hWnd);
130
131     EnterCriticalSection(&ddraw_cs);
132     hr = IWineD3DClipper_SetHWnd(This->wineD3DClipper,
133                                  dwFlags,
134                                  hWnd);
135     LeaveCriticalSection(&ddraw_cs);
136     switch(hr)
137     {
138         case WINED3DERR_INVALIDCALL:        return DDERR_INVALIDPARAMS;
139         default:                            return hr;
140     }
141 }
142
143 /*****************************************************************************
144  * IDirectDrawClipper::GetClipList
145  *
146  * Retrieve a copy of the clip list
147  *
148  * Arguments:
149  *  Rect: Rectangle to be used to clip the clip list or NULL for the
150  *        entire clip list
151  *  ClipList: structure for the resulting copy of the clip list.
152  *            If NULL, fills Size up to the number of bytes necessary to hold
153  *            the entire clip.
154  *  Size: Size of resulting clip list; size of the buffer at ClipList
155  *        or, if ClipList is NULL, receives the required size of the buffer
156  *        in bytes
157  *
158  * RETURNS
159  *  Either DD_OK or DDERR_*
160  ************************************************************************/
161 static HRESULT WINAPI IDirectDrawClipperImpl_GetClipList(
162     LPDIRECTDRAWCLIPPER iface, LPRECT lpRect, LPRGNDATA lpClipList,
163     LPDWORD lpdwSize)
164 {
165     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
166     HRESULT hr;
167
168     TRACE("iface %p, rect %s, clip_list %p, clip_list_size %p.\n",
169             iface, wine_dbgstr_rect(lpRect), lpClipList, lpdwSize);
170
171     EnterCriticalSection(&ddraw_cs);
172     hr = IWineD3DClipper_GetClipList(This->wineD3DClipper,
173                                      lpRect,
174                                      lpClipList,
175                                      lpdwSize);
176     LeaveCriticalSection(&ddraw_cs);
177     return hr;
178 }
179
180 /*****************************************************************************
181  * IDirectDrawClipper::SetClipList
182  *
183  * Sets or deletes (if lprgn is NULL) the clip list
184  *
185  * This implementation is a stub and returns DD_OK always to make the app
186  * happy.
187  *
188  * PARAMS
189  *  lprgn   Pointer to a LRGNDATA structure or NULL
190  *  dwFlags not used, must be 0
191  * RETURNS
192  *  Either DD_OK or DDERR_*
193  *****************************************************************************/
194 static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList(
195     LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD dwFlag
196 ) {
197     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
198     HRESULT hr;
199
200     TRACE("iface %p, clip_list %p, flags %#x.\n", iface, lprgn, dwFlag);
201
202     EnterCriticalSection(&ddraw_cs);
203     hr = IWineD3DClipper_SetClipList(This->wineD3DClipper,
204                                      lprgn,
205                                      dwFlag);
206     LeaveCriticalSection(&ddraw_cs);
207     return hr;
208 }
209
210 /*****************************************************************************
211  * IDirectDrawClipper::GetHwnd
212  *
213  * Returns the hwnd assigned with SetHwnd
214  *
215  * Arguments:
216  *  hWndPtr: Address to store the HWND at
217  *
218  * Return values:
219  *  Always returns DD_OK;
220  *****************************************************************************/
221 static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd(
222     LPDIRECTDRAWCLIPPER iface, HWND* hWndPtr
223 ) {
224     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
225     HRESULT hr;
226
227     TRACE("iface %p, window %p.\n", iface, hWndPtr);
228
229     EnterCriticalSection(&ddraw_cs);
230     hr =  IWineD3DClipper_GetHWnd(This->wineD3DClipper,
231                                   hWndPtr);
232     LeaveCriticalSection(&ddraw_cs);
233     return hr;
234 }
235
236 /*****************************************************************************
237  * IDirectDrawClipper::Initialize
238  *
239  * Initializes the interface. Well, there isn't much to do for this
240  * implementation, but it stores the DirectDraw Interface.
241  *
242  * Arguments:
243  *  DD: Pointer to a IDirectDraw interface
244  *  Flags: Unsupported by now
245  *
246  * Return values:
247  *  DD_OK on success
248  *  DDERR_ALREADYINITIALIZED if this interface isn't initialized already
249  *****************************************************************************/
250 static HRESULT WINAPI IDirectDrawClipperImpl_Initialize(
251      LPDIRECTDRAWCLIPPER iface, LPDIRECTDRAW lpDD, DWORD dwFlags
252 ) {
253     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
254
255     TRACE("iface %p, ddraw %p, flags %#x.\n", iface, lpDD, dwFlags);
256
257     EnterCriticalSection(&ddraw_cs);
258     if (This->initialized)
259     {
260         LeaveCriticalSection(&ddraw_cs);
261         return DDERR_ALREADYINITIALIZED;
262     }
263
264     This->initialized = TRUE;
265
266     LeaveCriticalSection(&ddraw_cs);
267     return DD_OK;
268 }
269
270 /*****************************************************************************
271  * IDirectDrawClipper::IsClipListChanged
272  *
273  * This function is a stub
274  *
275  * Arguments:
276  *  Changed:
277  *
278  * Return values:
279  *  DD_OK, because it's a stub
280  *****************************************************************************/
281 static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged(
282     LPDIRECTDRAWCLIPPER iface, BOOL* lpbChanged
283 ) {
284     FIXME("iface %p, changed %p stub!\n", iface, lpbChanged);
285
286     /* XXX What is safest? */
287     *lpbChanged = FALSE;
288
289     return DD_OK;
290 }
291
292 /*****************************************************************************
293  * The VTable
294  *****************************************************************************/
295 static const struct IDirectDrawClipperVtbl ddraw_clipper_vtbl =
296 {
297     IDirectDrawClipperImpl_QueryInterface,
298     IDirectDrawClipperImpl_AddRef,
299     IDirectDrawClipperImpl_Release,
300     IDirectDrawClipperImpl_GetClipList,
301     IDirectDrawClipperImpl_GetHWnd,
302     IDirectDrawClipperImpl_Initialize,
303     IDirectDrawClipperImpl_IsClipListChanged,
304     IDirectDrawClipperImpl_SetClipList,
305     IDirectDrawClipperImpl_SetHwnd
306 };
307
308 HRESULT ddraw_clipper_init(IDirectDrawClipperImpl *clipper)
309 {
310     clipper->lpVtbl = &ddraw_clipper_vtbl;
311     clipper->ref = 1;
312     clipper->wineD3DClipper = pWineDirect3DCreateClipper((IUnknown *)clipper);
313     if (!clipper->wineD3DClipper)
314     {
315         WARN("Failed to create wined3d clipper.\n");
316         return E_OUTOFMEMORY;
317     }
318
319     return DD_OK;
320 }