blob: a0f69d7933fa844cf8a291c5af8cb40aa4700c39 [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"
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +000034#include "dclipper/main.h"
35#include "ddraw/main.h"
Marcus Meissner10ad97c2000-04-09 14:30:50 +000036
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000037#include "wine/debug.h"
Patrik Stridvall33929be2001-07-18 21:04:23 +000038
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000039WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
Marcus Meissner10ad97c2000-04-09 14:30:50 +000040
41/******************************************************************************
Patrik Stridvalld9b9c4c2001-06-11 20:14:43 +000042 * DirectDrawCreateClipper (DDRAW.@)
Marcus Meissner10ad97c2000-04-09 14:30:50 +000043 */
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +000044
Alexandre Julliard48c4bb32004-08-12 23:00:51 +000045static IDirectDrawClipperVtbl DDRAW_Clipper_VTable;
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +000046
Marcus Meissner10ad97c2000-04-09 14:30:50 +000047HRESULT WINAPI DirectDrawCreateClipper(
48 DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter
49) {
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +000050 IDirectDrawClipperImpl* This;
51 TRACE("(%08lx,%p,%p)\n", dwFlags, lplpDDClipper, pUnkOuter);
Marcus Meissner10ad97c2000-04-09 14:30:50 +000052
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +000053 if (pUnkOuter != NULL) return CLASS_E_NOAGGREGATION;
54
55 This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
56 sizeof(IDirectDrawClipperImpl));
57 if (This == NULL) return E_OUTOFMEMORY;
58
59 ICOM_INIT_INTERFACE(This, IDirectDrawClipper, DDRAW_Clipper_VTable);
60 This->ref = 1;
Vincent Béron9a624912002-05-31 23:06:46 +000061 This->hWnd = 0;
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +000062 This->ddraw_owner = NULL;
63
64 *lplpDDClipper = ICOM_INTERFACE(This, IDirectDrawClipper);
Marcus Meissner10ad97c2000-04-09 14:30:50 +000065 return DD_OK;
66}
67
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +000068/* This is the classfactory implementation. */
69HRESULT DDRAW_CreateDirectDrawClipper(IUnknown* pUnkOuter, REFIID riid,
70 LPVOID* ppObj)
71{
72 HRESULT hr;
73 LPDIRECTDRAWCLIPPER pClip;
74
75 hr = DirectDrawCreateClipper(0, &pClip, pUnkOuter);
76 if (FAILED(hr)) return hr;
77
78 hr = IDirectDrawClipper_QueryInterface(pClip, riid, ppObj);
79 IDirectDrawClipper_Release(pClip);
80 return hr;
81}
82
Marcus Meissner10ad97c2000-04-09 14:30:50 +000083/******************************************************************************
84 * IDirectDrawClipper
85 */
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +000086HRESULT WINAPI Main_DirectDrawClipper_SetHwnd(
Marcus Meissner10ad97c2000-04-09 14:30:50 +000087 LPDIRECTDRAWCLIPPER iface, DWORD dwFlags, HWND hWnd
88) {
Alexandre Julliardf5f7a182004-09-08 01:50:37 +000089 IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
Marcus Meissner10ad97c2000-04-09 14:30:50 +000090
91 TRACE("(%p)->SetHwnd(0x%08lx,0x%08lx)\n",This,dwFlags,(DWORD)hWnd);
92 if( dwFlags ) {
93 FIXME("dwFlags = 0x%08lx, not supported.\n",dwFlags);
Vincent Béron9a624912002-05-31 23:06:46 +000094 return DDERR_INVALIDPARAMS;
Marcus Meissner10ad97c2000-04-09 14:30:50 +000095 }
96
97 This->hWnd = hWnd;
98 return DD_OK;
99}
100
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +0000101static void Main_DirectDrawClipper_Destroy(IDirectDrawClipperImpl* This)
102{
103 if (This->ddraw_owner != NULL)
104 Main_DirectDraw_RemoveClipper(This->ddraw_owner, This);
105
106 HeapFree(GetProcessHeap(), 0 ,This);
107}
108
109void Main_DirectDrawClipper_ForceDestroy(IDirectDrawClipperImpl* This)
110{
111 WARN("deleting clipper %p with refcnt %lu\n", This, This->ref);
112 Main_DirectDrawClipper_Destroy(This);
113}
114
115ULONG WINAPI Main_DirectDrawClipper_Release(LPDIRECTDRAWCLIPPER iface) {
Alexandre Julliardf5f7a182004-09-08 01:50:37 +0000116 IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
Paul Vriens202b3402005-01-09 17:29:21 +0000117 ULONG ref = InterlockedDecrement(&This->ref);
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000118
Paul Vriens202b3402005-01-09 17:29:21 +0000119 TRACE("(%p)->() decrementing from %lu.\n", This, ref + 1);
120
121 if (ref == 0)
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +0000122 {
123 Main_DirectDrawClipper_Destroy(This);
124 return 0;
125 }
Paul Vriens202b3402005-01-09 17:29:21 +0000126 else return ref;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000127}
128
Tobias Burnus998a8272004-08-23 18:50:14 +0000129/***********************************************************************
130* IDirectDrawClipper::GetClipList
131*
132* Retrieve a copy of the clip list
133*
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_*
145*/
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +0000146HRESULT WINAPI Main_DirectDrawClipper_GetClipList(
Tobias Burnus998a8272004-08-23 18:50:14 +0000147 LPDIRECTDRAWCLIPPER iface, LPRECT lpRect, LPRGNDATA lpClipList,
Robert Shearman9e2e5942004-08-24 20:14:26 +0000148 LPDWORD lpdwSize)
149{
Alexandre Julliardf5f7a182004-09-08 01:50:37 +0000150 IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
Robert Shearman9e2e5942004-08-24 20:14:26 +0000151
152 TRACE("(%p,%p,%p,%p)\n", This, lpRect, lpClipList, lpdwSize);
153
154 if (This->hWnd)
155 {
156 HDC hDC = GetDCEx(This->hWnd, NULL, DCX_WINDOW);
157 if (hDC)
158 {
159 HRGN hRgn = CreateRectRgn(0,0,0,0);
160 if (GetRandomRgn(hDC, hRgn, SYSRGN))
161 {
162 if (lpRect)
163 {
164 HRGN hRgnClip = CreateRectRgn(lpRect->left, lpRect->top,
165 lpRect->right, lpRect->bottom);
166 CombineRgn(hRgn, hRgn, hRgnClip, RGN_AND);
167 DeleteObject(hRgnClip);
168 }
169 *lpdwSize = GetRegionData(hRgn, *lpdwSize, lpClipList);
170 }
171 DeleteObject(hRgn);
172 ReleaseDC(This->hWnd, hDC);
173 }
174 return DD_OK;
175 }
176 else
177 {
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;
183 }
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000184}
185
Tobias Burnus998a8272004-08-23 18:50:14 +0000186/***********************************************************************
187* IDirectDrawClipper::SetClipList
188*
189* Sets or deletes (if lprgn is NULL) the clip list
190*
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_*
196*/
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +0000197HRESULT WINAPI Main_DirectDrawClipper_SetClipList(
Tobias Burnus998a8272004-08-23 18:50:14 +0000198 LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD dwFlag
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000199) {
Alexandre Julliardf5f7a182004-09-08 01:50:37 +0000200 IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
Tobias Burnus998a8272004-08-23 18:50:14 +0000201 static int warned = 0;
202 if (warned++ < 10 || lprgn == NULL)
203 FIXME("(%p,%p,%ld),stub!\n",This,lprgn,dwFlag);
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000204 return DD_OK;
205}
206
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +0000207HRESULT WINAPI Main_DirectDrawClipper_QueryInterface(
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000208 LPDIRECTDRAWCLIPPER iface, REFIID riid, LPVOID* ppvObj
209) {
Alexandre Julliardf5f7a182004-09-08 01:50:37 +0000210 IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +0000211
212 if (IsEqualGUID(&IID_IUnknown, riid)
213 || IsEqualGUID(&IID_IDirectDrawClipper, riid))
214 {
215 *ppvObj = ICOM_INTERFACE(This, IDirectDrawClipper);
Paul Vriens202b3402005-01-09 17:29:21 +0000216 InterlockedIncrement(&This->ref);
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +0000217 return S_OK;
218 }
219 else
220 {
221 return E_NOINTERFACE;
222 }
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000223}
224
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +0000225ULONG WINAPI Main_DirectDrawClipper_AddRef( LPDIRECTDRAWCLIPPER iface )
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000226{
Alexandre Julliardf5f7a182004-09-08 01:50:37 +0000227 IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
Paul Vriens202b3402005-01-09 17:29:21 +0000228 ULONG ref = InterlockedIncrement(&This->ref);
229
230 TRACE("(%p)->() incrementing from %lu.\n", This, ref - 1);
231
232 return ref;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000233}
234
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +0000235HRESULT WINAPI Main_DirectDrawClipper_GetHWnd(
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000236 LPDIRECTDRAWCLIPPER iface, HWND* hWndPtr
237) {
Alexandre Julliardf5f7a182004-09-08 01:50:37 +0000238 IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000239 FIXME("(%p)->(%p),stub!\n",This,hWndPtr);
240
Vincent Béron9a624912002-05-31 23:06:46 +0000241 *hWndPtr = This->hWnd;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000242
243 return DD_OK;
244}
245
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +0000246HRESULT WINAPI Main_DirectDrawClipper_Initialize(
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000247 LPDIRECTDRAWCLIPPER iface, LPDIRECTDRAW lpDD, DWORD dwFlags
248) {
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +0000249 IDirectDrawImpl* pOwner;
Alexandre Julliardf5f7a182004-09-08 01:50:37 +0000250 IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000251 FIXME("(%p)->(%p,0x%08lx),stub!\n",This,lpDD,dwFlags);
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +0000252
253 if (This->ddraw_owner != NULL) return DDERR_ALREADYINITIALIZED;
254
255 pOwner = ICOM_OBJECT(IDirectDrawImpl, IDirectDraw, lpDD);
256 This->ddraw_owner = pOwner;
257 Main_DirectDraw_AddClipper(pOwner, This);
258
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000259 return DD_OK;
260}
261
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +0000262HRESULT WINAPI Main_DirectDrawClipper_IsClipListChanged(
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000263 LPDIRECTDRAWCLIPPER iface, BOOL* lpbChanged
264) {
Alexandre Julliardf5f7a182004-09-08 01:50:37 +0000265 IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000266 FIXME("(%p)->(%p),stub!\n",This,lpbChanged);
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +0000267
268 /* XXX What is safest? */
269 *lpbChanged = FALSE;
270
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000271 return DD_OK;
272}
273
Alexandre Julliard48c4bb32004-08-12 23:00:51 +0000274static IDirectDrawClipperVtbl DDRAW_Clipper_VTable =
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000275{
Alexandre Julliardd6c0f9f2001-01-04 22:44:55 +0000276 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
Marcus Meissner10ad97c2000-04-09 14:30:50 +0000285};