blob: d1109b3874674d495e42d9cb5189d34a7f36e18d [file] [log] [blame]
Marcus Meissner10ad97c2000-04-09 14:30:50 +00001/* DirectDrawClipper implementation
2 *
3 * Copyright 2000 Marcus Meissner
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +00004 * Copyright 2000 TransGaming Technologies Inc.
Alexandre Julliard0799c1a2002-03-09 23:29:33 +00005 *
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.
10 *
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.
15 *
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
Marcus Meissner10ad97c2000-04-09 14:30:50 +000019 */
20
21#include "config.h"
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +000022
Alexandre Julliarde37c6e12003-09-05 23:08:26 +000023#include <stdarg.h>
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +000024#include <stdlib.h>
James Juranf4d5fef2001-01-26 20:43:40 +000025#include <string.h>
Patrik Stridvall33929be2001-07-18 21:04:23 +000026
Alexandre Julliarde37c6e12003-09-05 23:08:26 +000027#include "windef.h"
28#include "winbase.h"
29#include "wingdi.h"
Patrik Stridvall33929be2001-07-18 21:04:23 +000030#include "ddraw.h"
James Juranf4d5fef2001-01-26 20:43:40 +000031#include "winerror.h"
Patrik Stridvall33929be2001-07-18 21:04:23 +000032
Marcus Meissner10ad97c2000-04-09 14:30:50 +000033#include "ddraw_private.h"
34
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000035#include "wine/debug.h"
Patrik Stridvall33929be2001-07-18 21:04:23 +000036
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000037WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
Marcus Meissner10ad97c2000-04-09 14:30:50 +000038
39/******************************************************************************
Patrik Stridvalld9b9c4c2001-06-11 20:14:43 +000040 * DirectDrawCreateClipper (DDRAW.@)
Marcus Meissner10ad97c2000-04-09 14:30:50 +000041 */
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +000042
Dmitry Timoshkov46256282005-05-27 20:17:35 +000043static const IDirectDrawClipperVtbl DDRAW_Clipper_VTable;
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +000044
Marcus Meissner10ad97c2000-04-09 14:30:50 +000045HRESULT WINAPI DirectDrawCreateClipper(
46 DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter
47) {
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +000048 IDirectDrawClipperImpl* This;
49 TRACE("(%08lx,%p,%p)\n", dwFlags, lplpDDClipper, pUnkOuter);
Marcus Meissner10ad97c2000-04-09 14:30:50 +000050
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +000051 if (pUnkOuter != NULL) return CLASS_E_NOAGGREGATION;
52
53 This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
54 sizeof(IDirectDrawClipperImpl));
55 if (This == NULL) return E_OUTOFMEMORY;
56
57 ICOM_INIT_INTERFACE(This, IDirectDrawClipper, DDRAW_Clipper_VTable);
58 This->ref = 1;
Vincent Béron9a624912002-05-31 23:06:46 +000059 This->hWnd = 0;
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +000060 This->ddraw_owner = NULL;
61
62 *lplpDDClipper = ICOM_INTERFACE(This, IDirectDrawClipper);
Marcus Meissner10ad97c2000-04-09 14:30:50 +000063 return DD_OK;
64}
65
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +000066/* This is the classfactory implementation. */
67HRESULT DDRAW_CreateDirectDrawClipper(IUnknown* pUnkOuter, REFIID riid,
68 LPVOID* ppObj)
69{
70 HRESULT hr;
71 LPDIRECTDRAWCLIPPER pClip;
72
73 hr = DirectDrawCreateClipper(0, &pClip, pUnkOuter);
74 if (FAILED(hr)) return hr;
75
76 hr = IDirectDrawClipper_QueryInterface(pClip, riid, ppObj);
77 IDirectDrawClipper_Release(pClip);
78 return hr;
79}
80
Marcus Meissner10ad97c2000-04-09 14:30:50 +000081/******************************************************************************
82 * IDirectDrawClipper
83 */
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +000084HRESULT WINAPI Main_DirectDrawClipper_SetHwnd(
Marcus Meissner10ad97c2000-04-09 14:30:50 +000085 LPDIRECTDRAWCLIPPER iface, DWORD dwFlags, HWND hWnd
86) {
Alexandre Julliardf5f7a182004-09-08 01:50:37 +000087 IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
Marcus Meissner10ad97c2000-04-09 14:30:50 +000088
Christian Costa967f11d2005-03-21 10:28:49 +000089 TRACE("(%p)->(0x%08lx,0x%08lx)\n", This, dwFlags, (DWORD)hWnd);
Marcus Meissner10ad97c2000-04-09 14:30:50 +000090 if( dwFlags ) {
91 FIXME("dwFlags = 0x%08lx, not supported.\n",dwFlags);
Vincent Béron9a624912002-05-31 23:06:46 +000092 return DDERR_INVALIDPARAMS;
Marcus Meissner10ad97c2000-04-09 14:30:50 +000093 }
94
95 This->hWnd = hWnd;
96 return DD_OK;
97}
98
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +000099static void Main_DirectDrawClipper_Destroy(IDirectDrawClipperImpl* This)
100{
101 if (This->ddraw_owner != NULL)
102 Main_DirectDraw_RemoveClipper(This->ddraw_owner, This);
103
104 HeapFree(GetProcessHeap(), 0 ,This);
105}
106
107void Main_DirectDrawClipper_ForceDestroy(IDirectDrawClipperImpl* This)
108{
109 WARN("deleting clipper %p with refcnt %lu\n", This, This->ref);
110 Main_DirectDrawClipper_Destroy(This);
111}
112
113ULONG WINAPI Main_DirectDrawClipper_Release(LPDIRECTDRAWCLIPPER iface) {
Alexandre Julliardf5f7a182004-09-08 01:50:37 +0000114 IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
Paul Vriens202b3402005-01-09 17:29:21 +0000115 ULONG ref = InterlockedDecrement(&This->ref);
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000116
Paul Vriens202b3402005-01-09 17:29:21 +0000117 TRACE("(%p)->() decrementing from %lu.\n", This, ref + 1);
118
119 if (ref == 0)
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +0000120 {
121 Main_DirectDrawClipper_Destroy(This);
122 return 0;
123 }
Paul Vriens202b3402005-01-09 17:29:21 +0000124 else return ref;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000125}
126
Tobias Burnus998a8272004-08-23 18:50:14 +0000127/***********************************************************************
128* IDirectDrawClipper::GetClipList
129*
130* Retrieve a copy of the clip list
131*
132* PARAMS
133* lpRect Rectangle to be used to clip the clip list or NULL for the
134* entire clip list
135* lpClipList structure for the resulting copy of the clip list.
136 If NULL, fills lpdwSize up to the number of bytes necessary to hold
137 the entire clip.
138* lpdwSize Size of resulting clip list; size of the buffer at lpClipList
139 or, if lpClipList is NULL, receives the required size of the buffer
140 in bytes
141* RETURNS
142* Either DD_OK or DDERR_*
143*/
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +0000144HRESULT WINAPI Main_DirectDrawClipper_GetClipList(
Tobias Burnus998a8272004-08-23 18:50:14 +0000145 LPDIRECTDRAWCLIPPER iface, LPRECT lpRect, LPRGNDATA lpClipList,
Robert Shearman9e2e5942004-08-24 20:14:26 +0000146 LPDWORD lpdwSize)
147{
Alexandre Julliardf5f7a182004-09-08 01:50:37 +0000148 IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
Robert Shearman9e2e5942004-08-24 20:14:26 +0000149
Christian Costa967f11d2005-03-21 10:28:49 +0000150 TRACE("(%p,%p,%p,%p)\n", This, lpRect, lpClipList, lpdwSize);
Robert Shearman9e2e5942004-08-24 20:14:26 +0000151
152 if (This->hWnd)
153 {
154 HDC hDC = GetDCEx(This->hWnd, NULL, DCX_WINDOW);
155 if (hDC)
156 {
157 HRGN hRgn = CreateRectRgn(0,0,0,0);
158 if (GetRandomRgn(hDC, hRgn, SYSRGN))
159 {
Alexandre Julliard860c4fe2005-09-27 09:34:24 +0000160 if (GetVersion() & 0x80000000)
161 {
162 /* map region to screen coordinates */
163 POINT org;
164 GetDCOrgEx( hDC, &org );
165 OffsetRgn( hRgn, org.x, org.y );
166 }
Robert Shearman9e2e5942004-08-24 20:14:26 +0000167 if (lpRect)
168 {
169 HRGN hRgnClip = CreateRectRgn(lpRect->left, lpRect->top,
170 lpRect->right, lpRect->bottom);
171 CombineRgn(hRgn, hRgn, hRgnClip, RGN_AND);
172 DeleteObject(hRgnClip);
173 }
174 *lpdwSize = GetRegionData(hRgn, *lpdwSize, lpClipList);
175 }
176 DeleteObject(hRgn);
177 ReleaseDC(This->hWnd, hDC);
178 }
179 return DD_OK;
180 }
181 else
182 {
183 static int warned = 0;
184 if (warned++ < 10)
185 FIXME("(%p,%p,%p,%p),stub!\n",This,lpRect,lpClipList,lpdwSize);
186 if (lpdwSize) *lpdwSize=0;
187 return DDERR_NOCLIPLIST;
188 }
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000189}
190
Tobias Burnus998a8272004-08-23 18:50:14 +0000191/***********************************************************************
192* IDirectDrawClipper::SetClipList
193*
194* Sets or deletes (if lprgn is NULL) the clip list
195*
196* PARAMS
197* lprgn Pointer to a LRGNDATA structure or NULL
198* dwFlags not used, must be 0
199* RETURNS
200* Either DD_OK or DDERR_*
201*/
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +0000202HRESULT WINAPI Main_DirectDrawClipper_SetClipList(
Tobias Burnus998a8272004-08-23 18:50:14 +0000203 LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD dwFlag
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000204) {
Alexandre Julliardf5f7a182004-09-08 01:50:37 +0000205 IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
Tobias Burnus998a8272004-08-23 18:50:14 +0000206 static int warned = 0;
207 if (warned++ < 10 || lprgn == NULL)
208 FIXME("(%p,%p,%ld),stub!\n",This,lprgn,dwFlag);
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000209 return DD_OK;
210}
211
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +0000212HRESULT WINAPI Main_DirectDrawClipper_QueryInterface(
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000213 LPDIRECTDRAWCLIPPER iface, REFIID riid, LPVOID* ppvObj
214) {
Alexandre Julliardf5f7a182004-09-08 01:50:37 +0000215 IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +0000216
217 if (IsEqualGUID(&IID_IUnknown, riid)
218 || IsEqualGUID(&IID_IDirectDrawClipper, riid))
219 {
220 *ppvObj = ICOM_INTERFACE(This, IDirectDrawClipper);
Paul Vriens202b3402005-01-09 17:29:21 +0000221 InterlockedIncrement(&This->ref);
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +0000222 return S_OK;
223 }
224 else
225 {
226 return E_NOINTERFACE;
227 }
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000228}
229
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +0000230ULONG WINAPI Main_DirectDrawClipper_AddRef( LPDIRECTDRAWCLIPPER iface )
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000231{
Alexandre Julliardf5f7a182004-09-08 01:50:37 +0000232 IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
Paul Vriens202b3402005-01-09 17:29:21 +0000233 ULONG ref = InterlockedIncrement(&This->ref);
234
235 TRACE("(%p)->() incrementing from %lu.\n", This, ref - 1);
236
237 return ref;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000238}
239
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +0000240HRESULT WINAPI Main_DirectDrawClipper_GetHWnd(
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000241 LPDIRECTDRAWCLIPPER iface, HWND* hWndPtr
242) {
Alexandre Julliardf5f7a182004-09-08 01:50:37 +0000243 IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
Christian Costa967f11d2005-03-21 10:28:49 +0000244 TRACE("(%p)->(%p)\n", This, hWndPtr);
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000245
Vincent Béron9a624912002-05-31 23:06:46 +0000246 *hWndPtr = This->hWnd;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000247
248 return DD_OK;
249}
250
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +0000251HRESULT WINAPI Main_DirectDrawClipper_Initialize(
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000252 LPDIRECTDRAWCLIPPER iface, LPDIRECTDRAW lpDD, DWORD dwFlags
253) {
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +0000254 IDirectDrawImpl* pOwner;
Alexandre Julliardf5f7a182004-09-08 01:50:37 +0000255 IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
Christian Costa967f11d2005-03-21 10:28:49 +0000256 TRACE("(%p)->(%p,0x%08lx)\n", This, lpDD, dwFlags);
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +0000257
258 if (This->ddraw_owner != NULL) return DDERR_ALREADYINITIALIZED;
259
260 pOwner = ICOM_OBJECT(IDirectDrawImpl, IDirectDraw, lpDD);
261 This->ddraw_owner = pOwner;
262 Main_DirectDraw_AddClipper(pOwner, This);
263
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000264 return DD_OK;
265}
266
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +0000267HRESULT WINAPI Main_DirectDrawClipper_IsClipListChanged(
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000268 LPDIRECTDRAWCLIPPER iface, BOOL* lpbChanged
269) {
Alexandre Julliardf5f7a182004-09-08 01:50:37 +0000270 IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000271 FIXME("(%p)->(%p),stub!\n",This,lpbChanged);
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +0000272
273 /* XXX What is safest? */
274 *lpbChanged = FALSE;
275
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000276 return DD_OK;
277}
278
Dmitry Timoshkov46256282005-05-27 20:17:35 +0000279static const IDirectDrawClipperVtbl DDRAW_Clipper_VTable =
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000280{
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +0000281 Main_DirectDrawClipper_QueryInterface,
282 Main_DirectDrawClipper_AddRef,
283 Main_DirectDrawClipper_Release,
284 Main_DirectDrawClipper_GetClipList,
285 Main_DirectDrawClipper_GetHWnd,
286 Main_DirectDrawClipper_Initialize,
287 Main_DirectDrawClipper_IsClipListChanged,
288 Main_DirectDrawClipper_SetClipList,
289 Main_DirectDrawClipper_SetHwnd
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000290};