wined3d: Use a lookup table in select_card_ati_binary().
[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_IDirectDrawClipper, riid)
56             || IsEqualGUID(&IID_IUnknown, riid))
57     {
58         IUnknown_AddRef(iface);
59         *ppvObj = iface;
60         return S_OK;
61     }
62
63     return E_NOINTERFACE;
64 }
65
66 /*****************************************************************************
67  * IDirectDrawClipper::AddRef
68  *
69  * Increases the reference count of the interface, returns the new count
70  *
71  *****************************************************************************/
72 static ULONG WINAPI IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface )
73 {
74     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
75     ULONG ref = InterlockedIncrement(&This->ref);
76
77     TRACE("%p increasing refcount to %u.\n", This, ref);
78
79     return ref;
80 }
81
82 /*****************************************************************************
83  * IDirectDrawClipper::Release
84  *
85  * Decreases the reference count of the interface, returns the new count
86  * If the refcount is decreased to 0, the interface is destroyed.
87  *
88  *****************************************************************************/
89 static ULONG WINAPI IDirectDrawClipperImpl_Release(IDirectDrawClipper *iface) {
90     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
91     ULONG ref = InterlockedDecrement(&This->ref);
92
93     TRACE("%p decreasing refcount to %u.\n", This, ref);
94
95     if (ref == 0)
96     {
97         EnterCriticalSection(&ddraw_cs);
98         IWineD3DClipper_Release(This->wineD3DClipper);
99         HeapFree(GetProcessHeap(), 0, This);
100         LeaveCriticalSection(&ddraw_cs);
101         return 0;
102     }
103     else return ref;
104 }
105
106 /*****************************************************************************
107  * IDirectDrawClipper::SetHwnd
108  *
109  * Assigns a hWnd to the clipper interface.
110  *
111  * Arguments:
112  *  Flags: Unsupported so far
113  *  hWnd: The hWnd to set
114  *
115  * Return values:
116  *  DD_OK on success
117  *  DDERR_INVALIDPARAMS if Flags was != 0
118  *
119  *****************************************************************************/
120
121 static HRESULT WINAPI IDirectDrawClipperImpl_SetHwnd(
122     LPDIRECTDRAWCLIPPER iface, DWORD dwFlags, HWND hWnd
123 ) {
124     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
125     HRESULT hr;
126
127     TRACE("iface %p, flags %#x, window %p.\n", iface, dwFlags, hWnd);
128
129     EnterCriticalSection(&ddraw_cs);
130     hr = IWineD3DClipper_SetHWnd(This->wineD3DClipper,
131                                  dwFlags,
132                                  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(
160     LPDIRECTDRAWCLIPPER iface, LPRECT lpRect, LPRGNDATA lpClipList,
161     LPDWORD lpdwSize)
162 {
163     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
164     HRESULT hr;
165
166     TRACE("iface %p, rect %s, clip_list %p, clip_list_size %p.\n",
167             iface, wine_dbgstr_rect(lpRect), lpClipList, lpdwSize);
168
169     EnterCriticalSection(&ddraw_cs);
170     hr = IWineD3DClipper_GetClipList(This->wineD3DClipper,
171                                      lpRect,
172                                      lpClipList,
173                                      lpdwSize);
174     LeaveCriticalSection(&ddraw_cs);
175     return hr;
176 }
177
178 /*****************************************************************************
179  * IDirectDrawClipper::SetClipList
180  *
181  * Sets or deletes (if lprgn is NULL) the clip list
182  *
183  * This implementation is a stub and returns DD_OK always to make the app
184  * happy.
185  *
186  * PARAMS
187  *  lprgn   Pointer to a LRGNDATA structure or NULL
188  *  dwFlags not used, must be 0
189  * RETURNS
190  *  Either DD_OK or DDERR_*
191  *****************************************************************************/
192 static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList(
193     LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD dwFlag
194 ) {
195     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
196     HRESULT hr;
197
198     TRACE("iface %p, clip_list %p, flags %#x.\n", iface, lprgn, dwFlag);
199
200     EnterCriticalSection(&ddraw_cs);
201     hr = IWineD3DClipper_SetClipList(This->wineD3DClipper,
202                                      lprgn,
203                                      dwFlag);
204     LeaveCriticalSection(&ddraw_cs);
205     return hr;
206 }
207
208 /*****************************************************************************
209  * IDirectDrawClipper::GetHwnd
210  *
211  * Returns the hwnd assigned with SetHwnd
212  *
213  * Arguments:
214  *  hWndPtr: Address to store the HWND at
215  *
216  * Return values:
217  *  Always returns DD_OK;
218  *****************************************************************************/
219 static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd(
220     LPDIRECTDRAWCLIPPER iface, HWND* hWndPtr
221 ) {
222     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
223     HRESULT hr;
224
225     TRACE("iface %p, window %p.\n", iface, hWndPtr);
226
227     EnterCriticalSection(&ddraw_cs);
228     hr =  IWineD3DClipper_GetHWnd(This->wineD3DClipper,
229                                   hWndPtr);
230     LeaveCriticalSection(&ddraw_cs);
231     return hr;
232 }
233
234 /*****************************************************************************
235  * IDirectDrawClipper::Initialize
236  *
237  * Initializes the interface. Well, there isn't much to do for this
238  * implementation, but it stores the DirectDraw Interface.
239  *
240  * Arguments:
241  *  DD: Pointer to a IDirectDraw interface
242  *  Flags: Unsupported by now
243  *
244  * Return values:
245  *  DD_OK on success
246  *  DDERR_ALREADYINITIALIZED if this interface isn't initialized already
247  *****************************************************************************/
248 static HRESULT WINAPI IDirectDrawClipperImpl_Initialize(
249      LPDIRECTDRAWCLIPPER iface, LPDIRECTDRAW lpDD, DWORD dwFlags
250 ) {
251     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
252
253     TRACE("iface %p, ddraw %p, flags %#x.\n", iface, lpDD, dwFlags);
254
255     EnterCriticalSection(&ddraw_cs);
256     if (This->initialized)
257     {
258         LeaveCriticalSection(&ddraw_cs);
259         return DDERR_ALREADYINITIALIZED;
260     }
261
262     This->initialized = TRUE;
263
264     LeaveCriticalSection(&ddraw_cs);
265     return DD_OK;
266 }
267
268 /*****************************************************************************
269  * IDirectDrawClipper::IsClipListChanged
270  *
271  * This function is a stub
272  *
273  * Arguments:
274  *  Changed:
275  *
276  * Return values:
277  *  DD_OK, because it's a stub
278  *****************************************************************************/
279 static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged(
280     LPDIRECTDRAWCLIPPER iface, BOOL* lpbChanged
281 ) {
282     FIXME("iface %p, changed %p stub!\n", iface, lpbChanged);
283
284     /* XXX What is safest? */
285     *lpbChanged = FALSE;
286
287     return DD_OK;
288 }
289
290 /*****************************************************************************
291  * The VTable
292  *****************************************************************************/
293 static const struct IDirectDrawClipperVtbl ddraw_clipper_vtbl =
294 {
295     IDirectDrawClipperImpl_QueryInterface,
296     IDirectDrawClipperImpl_AddRef,
297     IDirectDrawClipperImpl_Release,
298     IDirectDrawClipperImpl_GetClipList,
299     IDirectDrawClipperImpl_GetHWnd,
300     IDirectDrawClipperImpl_Initialize,
301     IDirectDrawClipperImpl_IsClipListChanged,
302     IDirectDrawClipperImpl_SetClipList,
303     IDirectDrawClipperImpl_SetHwnd
304 };
305
306 HRESULT ddraw_clipper_init(IDirectDrawClipperImpl *clipper)
307 {
308     clipper->lpVtbl = &ddraw_clipper_vtbl;
309     clipper->ref = 1;
310     clipper->wineD3DClipper = pWineDirect3DCreateClipper();
311     if (!clipper->wineD3DClipper)
312     {
313         WARN("Failed to create wined3d clipper.\n");
314         return E_OUTOFMEMORY;
315     }
316
317     return DD_OK;
318 }