d3d9/tests: Add init/teardown handlers for state tests.
[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 #include "windef.h"
29 #include "winbase.h"
30 #include "wingdi.h"
31 #include "ddraw.h"
32 #include "winerror.h"
33
34 #include "ddraw_private.h"
35
36 #include "wine/debug.h"
37
38 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
39
40 /*****************************************************************************
41  * IUnknown methods
42  *****************************************************************************/
43
44 /*****************************************************************************
45  * IDirectDrawClipper::QueryInterface
46  *
47  * Can query the IUnknown and IDirectDrawClipper interface from a
48  * Clipper object. The IUnknown Interface is equal to the IDirectDrawClipper
49  * interface. Can't create other interfaces.
50  *
51  * Arguments:
52  *  riid: Interface id asked for
53  *  ppvObj: Returns the pointer to the interface
54  *
55  * Return values:
56  *  DD_OK on success
57  *  E_NOINTERFACE if the requested interface wasn't found.
58  *
59  *****************************************************************************/
60 static HRESULT WINAPI IDirectDrawClipperImpl_QueryInterface(
61     LPDIRECTDRAWCLIPPER iface, REFIID riid, LPVOID* ppvObj
62 ) {
63     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
64
65     if (IsEqualGUID(&IID_IUnknown, riid)
66         || IsEqualGUID(&IID_IDirectDrawClipper, riid))
67     {
68         *ppvObj = ICOM_INTERFACE(This, IDirectDrawClipper);
69         InterlockedIncrement(&This->ref);
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 %lu.\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 %lu.\n", This, ref + 1);
106
107     if (ref == 0)
108     {
109         HeapFree(GetProcessHeap(), 0, This);
110         return 0;
111     }
112     else return ref;
113 }
114
115 /*****************************************************************************
116  * IDirectDrawClipper::SetHwnd
117  *
118  * Assigns a hWnd to the clipper interface.
119  *
120  * Arguments:
121  *  Flags: Unsupported so far
122  *  hWnd: The hWnd to set
123  *
124  * Return values:
125  *  DD_OK on success
126  *  DDERR_INVALIDPARAMS if Flags was != 0
127  *
128  *****************************************************************************/
129
130 static HRESULT WINAPI IDirectDrawClipperImpl_SetHwnd(
131     LPDIRECTDRAWCLIPPER iface, DWORD dwFlags, HWND hWnd
132 ) {
133     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
134
135     TRACE("(%p)->(0x%08lx,0x%08lx)\n", This, dwFlags, (DWORD)hWnd);
136     if( dwFlags ) {
137         FIXME("dwFlags = 0x%08lx, not supported.\n",dwFlags);
138         return DDERR_INVALIDPARAMS;
139     }
140
141     This->hWnd = hWnd;
142     return DD_OK;
143 }
144
145 /*****************************************************************************
146  * IDirectDrawClipper::GetClipList
147  *
148  * Retrieve a copy of the clip list
149  *
150  * Arguments:
151  *  Rect: Rectangle to be used to clip the clip list or NULL for the
152  *        entire clip list
153  *  ClipList: structure for the resulting copy of the clip list.
154  *            If NULL, fills Size up to the number of bytes necessary to hold
155  *            the entire clip.
156  *  Size: Size of resulting clip list; size of the buffer at ClipList
157  *        or, if ClipList is NULL, receives the required size of the buffer
158  *        in bytes
159  *
160  * RETURNS
161  *  Either DD_OK or DDERR_*
162  ************************************************************************/
163 static HRESULT WINAPI IDirectDrawClipperImpl_GetClipList(
164     LPDIRECTDRAWCLIPPER iface, LPRECT lpRect, LPRGNDATA lpClipList,
165     LPDWORD lpdwSize)
166 {
167     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
168
169     TRACE("(%p,%p,%p,%p)\n", This, lpRect, lpClipList, lpdwSize);
170
171     if (This->hWnd)
172     {
173         HDC hDC = GetDCEx(This->hWnd, NULL, DCX_WINDOW);
174         if (hDC)
175         {
176             HRGN hRgn = CreateRectRgn(0,0,0,0);
177             if (GetRandomRgn(hDC, hRgn, SYSRGN))
178             {
179                 if (GetVersion() & 0x80000000)
180                 {
181                     /* map region to screen coordinates */
182                     POINT org;
183                     GetDCOrgEx( hDC, &org );
184                     OffsetRgn( hRgn, org.x, org.y );
185                 }
186                 if (lpRect)
187                 {
188                     HRGN hRgnClip = CreateRectRgn(lpRect->left, lpRect->top,
189                         lpRect->right, lpRect->bottom);
190                     CombineRgn(hRgn, hRgn, hRgnClip, RGN_AND);
191                     DeleteObject(hRgnClip);
192                 }
193                 *lpdwSize = GetRegionData(hRgn, *lpdwSize, lpClipList);
194             }
195             DeleteObject(hRgn);
196             ReleaseDC(This->hWnd, hDC);
197         }
198         return DD_OK;
199     }
200     else
201     {
202         static int warned = 0;
203         if (warned++ < 10)
204             FIXME("(%p,%p,%p,%p),stub!\n",This,lpRect,lpClipList,lpdwSize);
205         if (lpdwSize) *lpdwSize=0;
206         return DDERR_NOCLIPLIST;
207     }
208 }
209
210 /*****************************************************************************
211  * IDirectDrawClipper::SetClipList
212  *
213  * Sets or deletes (if lprgn is NULL) the clip list
214  *
215  * This implementation is a stub and returns DD_OK always to make the app
216  * happy.
217  *
218  * PARAMS
219  *  lprgn   Pointer to a LRGNDATA structure or NULL
220  *  dwFlags not used, must be 0
221  * RETURNS
222  *  Either DD_OK or DDERR_*
223  *****************************************************************************/
224 static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList(
225     LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD dwFlag
226 ) {
227     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
228     static int warned = 0;
229     if (warned++ < 10 || lprgn == NULL)
230         FIXME("(%p,%p,%ld),stub!\n",This,lprgn,dwFlag);
231     return DD_OK;
232 }
233
234 /*****************************************************************************
235  * IDirectDrawClipper::GetHwnd
236  *
237  * Returns the hwnd assigned with SetHwnd
238  *
239  * Arguments:
240  *  hWndPtr: Address to store the HWND at
241  *
242  * Return values:
243  *  Always returns DD_OK;
244  *****************************************************************************/
245 static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd(
246     LPDIRECTDRAWCLIPPER iface, HWND* hWndPtr
247 ) {
248     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
249     TRACE("(%p)->(%p)\n", This, hWndPtr);
250
251     *hWndPtr = This->hWnd;
252
253     return DD_OK;
254 }
255
256 /*****************************************************************************
257  * IDirectDrawClipper::Initialize
258  *
259  * Initializes the interface. Well, there isn't much to do for this
260  * implementation, but it stores the DirectDraw Interface.
261  *
262  * Arguments:
263  *  DD: Pointer to a IDirectDraw interface
264  *  Flags: Unsupported by now
265  *
266  * Return values:
267  *  DD_OK on success
268  *  DDERR_ALREADYINITIALIZED if this interface isn't initialized already
269  *****************************************************************************/
270 static HRESULT WINAPI IDirectDrawClipperImpl_Initialize(
271      LPDIRECTDRAWCLIPPER iface, LPDIRECTDRAW lpDD, DWORD dwFlags
272 ) {
273     IDirectDrawImpl* pOwner;
274     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
275     TRACE("(%p)->(%p,0x%08lx)\n", This, lpDD, dwFlags);
276
277     if (This->ddraw_owner != NULL) return DDERR_ALREADYINITIALIZED;
278
279     pOwner = ICOM_OBJECT(IDirectDrawImpl, IDirectDraw, lpDD);
280     This->ddraw_owner = pOwner;
281
282     return DD_OK;
283 }
284
285 /*****************************************************************************
286  * IDirectDrawClipper::IsClipListChanged
287  *
288  * This function is a stub
289  *
290  * Arguments:
291  *  Changed:
292  *
293  * Return values:
294  *  DD_OK, because it's a stub
295  *****************************************************************************/
296 static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged(
297     LPDIRECTDRAWCLIPPER iface, BOOL* lpbChanged
298 ) {
299     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
300     FIXME("(%p)->(%p),stub!\n",This,lpbChanged);
301
302     /* XXX What is safest? */
303     *lpbChanged = FALSE;
304
305     return DD_OK;
306 }
307
308 /*****************************************************************************
309  * The VTable
310  *****************************************************************************/
311 const IDirectDrawClipperVtbl IDirectDrawClipper_Vtbl =
312 {
313     IDirectDrawClipperImpl_QueryInterface,
314     IDirectDrawClipperImpl_AddRef,
315     IDirectDrawClipperImpl_Release,
316     IDirectDrawClipperImpl_GetClipList,
317     IDirectDrawClipperImpl_GetHWnd,
318     IDirectDrawClipperImpl_Initialize,
319     IDirectDrawClipperImpl_IsClipListChanged,
320     IDirectDrawClipperImpl_SetClipList,
321     IDirectDrawClipperImpl_SetHwnd
322 };