Fix some DPA functions so they pass the new tests.
[wine/multimedia.git] / dlls / ddraw / clipper.c
blobca610ce51201ac88d088419b465be813367926aa
1 /* DirectDrawClipper implementation
3 * Copyright 2000 Marcus Meissner
4 * Copyright 2000 TransGaming Technologies Inc.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "config.h"
23 #include <stdarg.h>
24 #include <stdlib.h>
25 #include <string.h>
27 #define CONST_VTABLE
29 #include "windef.h"
30 #include "winbase.h"
31 #include "wingdi.h"
32 #include "ddraw.h"
33 #include "winerror.h"
35 #include "ddraw_private.h"
37 #include "wine/debug.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
41 /******************************************************************************
42 * DirectDrawCreateClipper (DDRAW.@)
45 static const IDirectDrawClipperVtbl DDRAW_Clipper_VTable;
47 HRESULT WINAPI DirectDrawCreateClipper(
48 DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter
49 ) {
50 IDirectDrawClipperImpl* This;
51 TRACE("(%08lx,%p,%p)\n", dwFlags, lplpDDClipper, pUnkOuter);
53 if (pUnkOuter != NULL) return CLASS_E_NOAGGREGATION;
55 This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
56 sizeof(IDirectDrawClipperImpl));
57 if (This == NULL) return E_OUTOFMEMORY;
59 ICOM_INIT_INTERFACE(This, IDirectDrawClipper, DDRAW_Clipper_VTable);
60 This->ref = 1;
61 This->hWnd = 0;
62 This->ddraw_owner = NULL;
64 *lplpDDClipper = ICOM_INTERFACE(This, IDirectDrawClipper);
65 return DD_OK;
68 /* This is the classfactory implementation. */
69 HRESULT DDRAW_CreateDirectDrawClipper(IUnknown* pUnkOuter, REFIID riid,
70 LPVOID* ppObj)
72 HRESULT hr;
73 LPDIRECTDRAWCLIPPER pClip;
75 hr = DirectDrawCreateClipper(0, &pClip, pUnkOuter);
76 if (FAILED(hr)) return hr;
78 hr = IDirectDrawClipper_QueryInterface(pClip, riid, ppObj);
79 IDirectDrawClipper_Release(pClip);
80 return hr;
83 /******************************************************************************
84 * IDirectDrawClipper
86 HRESULT WINAPI Main_DirectDrawClipper_SetHwnd(
87 LPDIRECTDRAWCLIPPER iface, DWORD dwFlags, HWND hWnd
88 ) {
89 IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
91 TRACE("(%p)->(0x%08lx,0x%08lx)\n", This, dwFlags, (DWORD)hWnd);
92 if( dwFlags ) {
93 FIXME("dwFlags = 0x%08lx, not supported.\n",dwFlags);
94 return DDERR_INVALIDPARAMS;
97 This->hWnd = hWnd;
98 return DD_OK;
101 static void Main_DirectDrawClipper_Destroy(IDirectDrawClipperImpl* This)
103 if (This->ddraw_owner != NULL)
104 Main_DirectDraw_RemoveClipper(This->ddraw_owner, This);
106 HeapFree(GetProcessHeap(), 0 ,This);
109 void Main_DirectDrawClipper_ForceDestroy(IDirectDrawClipperImpl* This)
111 WARN("deleting clipper %p with refcnt %lu\n", This, This->ref);
112 Main_DirectDrawClipper_Destroy(This);
115 ULONG WINAPI Main_DirectDrawClipper_Release(LPDIRECTDRAWCLIPPER iface) {
116 IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
117 ULONG ref = InterlockedDecrement(&This->ref);
119 TRACE("(%p)->() decrementing from %lu.\n", This, ref + 1);
121 if (ref == 0)
123 Main_DirectDrawClipper_Destroy(This);
124 return 0;
126 else return ref;
129 /***********************************************************************
130 * IDirectDrawClipper::GetClipList
132 * Retrieve a copy of the clip list
134 * PARAMS
135 * lpRect Rectangle to be used to clip the clip list or NULL for the
136 * entire clip list
137 * lpClipList structure for the resulting copy of the clip list.
138 If NULL, fills lpdwSize up to the number of bytes necessary to hold
139 the entire clip.
140 * lpdwSize Size of resulting clip list; size of the buffer at lpClipList
141 or, if lpClipList is NULL, receives the required size of the buffer
142 in bytes
143 * RETURNS
144 * Either DD_OK or DDERR_*
146 HRESULT WINAPI Main_DirectDrawClipper_GetClipList(
147 LPDIRECTDRAWCLIPPER iface, LPRECT lpRect, LPRGNDATA lpClipList,
148 LPDWORD lpdwSize)
150 IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
152 TRACE("(%p,%p,%p,%p)\n", This, lpRect, lpClipList, lpdwSize);
154 if (This->hWnd)
156 HDC hDC = GetDCEx(This->hWnd, NULL, DCX_WINDOW);
157 if (hDC)
159 HRGN hRgn = CreateRectRgn(0,0,0,0);
160 if (GetRandomRgn(hDC, hRgn, SYSRGN))
162 if (lpRect)
164 HRGN hRgnClip = CreateRectRgn(lpRect->left, lpRect->top,
165 lpRect->right, lpRect->bottom);
166 CombineRgn(hRgn, hRgn, hRgnClip, RGN_AND);
167 DeleteObject(hRgnClip);
169 *lpdwSize = GetRegionData(hRgn, *lpdwSize, lpClipList);
171 DeleteObject(hRgn);
172 ReleaseDC(This->hWnd, hDC);
174 return DD_OK;
176 else
178 static int warned = 0;
179 if (warned++ < 10)
180 FIXME("(%p,%p,%p,%p),stub!\n",This,lpRect,lpClipList,lpdwSize);
181 if (lpdwSize) *lpdwSize=0;
182 return DDERR_NOCLIPLIST;
186 /***********************************************************************
187 * IDirectDrawClipper::SetClipList
189 * Sets or deletes (if lprgn is NULL) the clip list
191 * PARAMS
192 * lprgn Pointer to a LRGNDATA structure or NULL
193 * dwFlags not used, must be 0
194 * RETURNS
195 * Either DD_OK or DDERR_*
197 HRESULT WINAPI Main_DirectDrawClipper_SetClipList(
198 LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD dwFlag
200 IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
201 static int warned = 0;
202 if (warned++ < 10 || lprgn == NULL)
203 FIXME("(%p,%p,%ld),stub!\n",This,lprgn,dwFlag);
204 return DD_OK;
207 HRESULT WINAPI Main_DirectDrawClipper_QueryInterface(
208 LPDIRECTDRAWCLIPPER iface, REFIID riid, LPVOID* ppvObj
210 IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
212 if (IsEqualGUID(&IID_IUnknown, riid)
213 || IsEqualGUID(&IID_IDirectDrawClipper, riid))
215 *ppvObj = ICOM_INTERFACE(This, IDirectDrawClipper);
216 InterlockedIncrement(&This->ref);
217 return S_OK;
219 else
221 return E_NOINTERFACE;
225 ULONG WINAPI Main_DirectDrawClipper_AddRef( LPDIRECTDRAWCLIPPER iface )
227 IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
228 ULONG ref = InterlockedIncrement(&This->ref);
230 TRACE("(%p)->() incrementing from %lu.\n", This, ref - 1);
232 return ref;
235 HRESULT WINAPI Main_DirectDrawClipper_GetHWnd(
236 LPDIRECTDRAWCLIPPER iface, HWND* hWndPtr
238 IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
239 TRACE("(%p)->(%p)\n", This, hWndPtr);
241 *hWndPtr = This->hWnd;
243 return DD_OK;
246 HRESULT WINAPI Main_DirectDrawClipper_Initialize(
247 LPDIRECTDRAWCLIPPER iface, LPDIRECTDRAW lpDD, DWORD dwFlags
249 IDirectDrawImpl* pOwner;
250 IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
251 TRACE("(%p)->(%p,0x%08lx)\n", This, lpDD, dwFlags);
253 if (This->ddraw_owner != NULL) return DDERR_ALREADYINITIALIZED;
255 pOwner = ICOM_OBJECT(IDirectDrawImpl, IDirectDraw, lpDD);
256 This->ddraw_owner = pOwner;
257 Main_DirectDraw_AddClipper(pOwner, This);
259 return DD_OK;
262 HRESULT WINAPI Main_DirectDrawClipper_IsClipListChanged(
263 LPDIRECTDRAWCLIPPER iface, BOOL* lpbChanged
265 IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
266 FIXME("(%p)->(%p),stub!\n",This,lpbChanged);
268 /* XXX What is safest? */
269 *lpbChanged = FALSE;
271 return DD_OK;
274 static const IDirectDrawClipperVtbl DDRAW_Clipper_VTable =
276 Main_DirectDrawClipper_QueryInterface,
277 Main_DirectDrawClipper_AddRef,
278 Main_DirectDrawClipper_Release,
279 Main_DirectDrawClipper_GetClipList,
280 Main_DirectDrawClipper_GetHWnd,
281 Main_DirectDrawClipper_Initialize,
282 Main_DirectDrawClipper_IsClipListChanged,
283 Main_DirectDrawClipper_SetClipList,
284 Main_DirectDrawClipper_SetHwnd