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