ReactOS  0.4.14-dev-376-gaedba84
clipper.c
Go to the documentation of this file.
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 
28 
29 static inline struct ddraw_clipper *impl_from_IDirectDrawClipper(IDirectDrawClipper *iface)
30 {
32 }
33 
34 static HRESULT WINAPI ddraw_clipper_QueryInterface(IDirectDrawClipper *iface, REFIID iid, void **object)
35 {
36  struct ddraw_clipper *clipper = impl_from_IDirectDrawClipper(iface);
37 
38  TRACE("iface %p, iid %s, object %p.\n", iface, debugstr_guid(iid), object);
39 
40  if (IsEqualGUID(&IID_IDirectDrawClipper, iid)
41  || IsEqualGUID(&IID_IUnknown, iid))
42  {
43  IDirectDrawClipper_AddRef(&clipper->IDirectDrawClipper_iface);
44  *object = &clipper->IDirectDrawClipper_iface;
45  return S_OK;
46  }
47 
48  WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
49  *object = NULL;
50 
51  return E_NOINTERFACE;
52 }
53 
54 static ULONG WINAPI ddraw_clipper_AddRef(IDirectDrawClipper *iface)
55 {
56  struct ddraw_clipper *clipper = impl_from_IDirectDrawClipper(iface);
57  ULONG refcount = InterlockedIncrement(&clipper->ref);
58 
59  TRACE("%p increasing refcount to %u.\n", clipper, refcount);
60 
61  return refcount;
62 }
63 
64 static ULONG WINAPI ddraw_clipper_Release(IDirectDrawClipper *iface)
65 {
66  struct ddraw_clipper *clipper = impl_from_IDirectDrawClipper(iface);
67  ULONG refcount = InterlockedDecrement(&clipper->ref);
68 
69  TRACE("%p decreasing refcount to %u.\n", clipper, refcount);
70 
71  if (!refcount)
72  {
73  if (clipper->region)
74  DeleteObject(clipper->region);
75  heap_free(clipper);
76  }
77 
78  return refcount;
79 }
80 
81 static HRESULT WINAPI ddraw_clipper_SetHWnd(IDirectDrawClipper *iface, DWORD flags, HWND window)
82 {
83  struct ddraw_clipper *clipper = impl_from_IDirectDrawClipper(iface);
84 
85  TRACE("iface %p, flags %#x, window %p.\n", iface, flags, window);
86 
87  if (flags)
88  {
89  FIXME("flags %#x, not supported.\n", flags);
90  return DDERR_INVALIDPARAMS;
91  }
92 
94  clipper->window = window;
96 
97  return DD_OK;
98 }
99 
101 {
102  POINT origin;
103  HRGN rgn;
104  HDC dc;
105 
106  if (!(dc = GetDC(window)))
107  {
108  WARN("Failed to get dc.\n");
109  return NULL;
110  }
111 
112  if (!(rgn = CreateRectRgn(0, 0, 0, 0)))
113  {
114  ERR("Failed to create region.\n");
115  ReleaseDC(window, dc);
116  return NULL;
117  }
118 
119  if (GetRandomRgn(dc, rgn, SYSRGN) != 1)
120  {
121  ERR("Failed to get window region.\n");
122  DeleteObject(rgn);
123  ReleaseDC(window, dc);
124  return NULL;
125  }
126 
127  if (GetVersion() & 0x80000000)
128  {
129  GetDCOrgEx(dc, &origin);
130  OffsetRgn(rgn, origin.x, origin.y);
131  }
132 
133  ReleaseDC(window, dc);
134  return rgn;
135 }
136 
137 /*****************************************************************************
138  * IDirectDrawClipper::GetClipList
139  *
140  * Retrieve a copy of the clip list
141  *
142  * Arguments:
143  * rect: Rectangle to be used to clip the clip list or NULL for the
144  * entire clip list.
145  * clip_list: structure for the resulting copy of the clip list.
146  * If NULL, fills Size up to the number of bytes necessary to hold
147  * the entire clip.
148  * clip_list_size: Size of resulting clip list; size of the buffer at clip_list
149  * or, if clip_list is NULL, receives the required size of the buffer
150  * in bytes.
151  *
152  * RETURNS
153  * Either DD_OK or DDERR_*
154  ************************************************************************/
155 static HRESULT WINAPI ddraw_clipper_GetClipList(IDirectDrawClipper *iface, RECT *rect,
156  RGNDATA *clip_list, DWORD *clip_list_size)
157 {
158  struct ddraw_clipper *clipper = impl_from_IDirectDrawClipper(iface);
159  HRGN region;
160 
161  TRACE("iface %p, rect %s, clip_list %p, clip_list_size %p.\n",
162  iface, wine_dbgstr_rect(rect), clip_list, clip_list_size);
163 
165 
166  if (clipper->window)
167  {
168  if (!(region = get_window_region(clipper->window)))
169  {
171  WARN("Failed to get window region.\n");
172  return E_FAIL;
173  }
174  }
175  else
176  {
177  if (!(region = clipper->region))
178  {
180  WARN("No clip list set.\n");
181  return DDERR_NOCLIPLIST;
182  }
183  }
184 
185  if (rect)
186  {
187  HRGN clip_region;
188 
189  if (!(clip_region = CreateRectRgnIndirect(rect)))
190  {
192  ERR("Failed to create region.\n");
193  if (clipper->window)
195  return E_FAIL;
196  }
197 
198  if (CombineRgn(clip_region, region, clip_region, RGN_AND) == ERROR)
199  {
201  ERR("Failed to combine regions.\n");
202  DeleteObject(clip_region);
203  if (clipper->window)
205  return E_FAIL;
206  }
207 
208  if (clipper->window)
210  region = clip_region;
211  }
212 
213  *clip_list_size = GetRegionData(region, *clip_list_size, clip_list);
214  if (rect || clipper->window)
216 
218  return DD_OK;
219 }
220 
221 /*****************************************************************************
222  * IDirectDrawClipper::SetClipList
223  *
224  * Sets or deletes (if region is NULL) the clip list
225  *
226  * This implementation is a stub and returns DD_OK always to make the app
227  * happy.
228  *
229  * PARAMS
230  * region Pointer to a LRGNDATA structure or NULL
231  * flags not used, must be 0
232  * RETURNS
233  * Either DD_OK or DDERR_*
234  *****************************************************************************/
235 static HRESULT WINAPI ddraw_clipper_SetClipList(IDirectDrawClipper *iface, RGNDATA *region, DWORD flags)
236 {
237  struct ddraw_clipper *clipper = impl_from_IDirectDrawClipper(iface);
238 
239  TRACE("iface %p, region %p, flags %#x.\n", iface, region, flags);
240 
242 
243  if (clipper->window)
244  {
247  }
248 
249  if (clipper->region)
250  DeleteObject(clipper->region);
251  if (!region)
252  clipper->region = NULL;
253  else if (!(clipper->region = ExtCreateRegion(NULL, 0, region)))
254  {
256  ERR("Failed to create region.\n");
257  return E_FAIL;
258  }
259 
261 
262  return DD_OK;
263 }
264 
265 static HRESULT WINAPI ddraw_clipper_GetHWnd(IDirectDrawClipper *iface, HWND *window)
266 {
267  struct ddraw_clipper *clipper = impl_from_IDirectDrawClipper(iface);
268 
269  TRACE("iface %p, window %p.\n", iface, window);
270 
272  *window = clipper->window;
274 
275  return DD_OK;
276 }
277 
278 static HRESULT WINAPI ddraw_clipper_Initialize(IDirectDrawClipper *iface,
279  IDirectDraw *ddraw, DWORD flags)
280 {
281  struct ddraw_clipper *clipper = impl_from_IDirectDrawClipper(iface);
282 
283  TRACE("iface %p, ddraw %p, flags %#x.\n", iface, ddraw, flags);
284 
286  if (clipper->initialized)
287  {
290  }
291 
292  clipper->initialized = TRUE;
294 
295  return DD_OK;
296 }
297 
298 static HRESULT WINAPI ddraw_clipper_IsClipListChanged(IDirectDrawClipper *iface, BOOL *changed)
299 {
300  FIXME("iface %p, changed %p stub!\n", iface, changed);
301 
302  /* XXX What is safest? */
303  *changed = FALSE;
304 
305  return DD_OK;
306 }
307 
308 static const struct IDirectDrawClipperVtbl ddraw_clipper_vtbl =
309 {
319 };
320 
322 {
323  clipper->IDirectDrawClipper_iface.lpVtbl = &ddraw_clipper_vtbl;
324  clipper->ref = 1;
325 
326  return DD_OK;
327 }
328 
329 struct ddraw_clipper *unsafe_impl_from_IDirectDrawClipper(IDirectDrawClipper *iface)
330 {
331  if (!iface)
332  return NULL;
333  assert(iface->lpVtbl == &ddraw_clipper_vtbl);
334 
335  return impl_from_IDirectDrawClipper(iface);
336 }
int WINAPI CombineRgn(_In_opt_ HRGN hrgnDest, _In_opt_ HRGN hrgnSrc1, _In_opt_ HRGN hrgnSrc2, _In_ int fnCombineMode)
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
#define E_NOINTERFACE
Definition: winerror.h:2364
static ULONG WINAPI ddraw_clipper_AddRef(IDirectDrawClipper *iface)
Definition: clipper.c:54
HDC WINAPI GetDC(_In_opt_ HWND)
static HRESULT WINAPI ddraw_clipper_Initialize(IDirectDrawClipper *iface, IDirectDraw *ddraw, DWORD flags)
Definition: clipper.c:278
WINE_DEFAULT_DEBUG_CHANNEL(ddraw)
#define ERROR(name)
Definition: error_private.h:53
#define WARN(fmt,...)
Definition: debug.h:111
HRGN WINAPI CreateRectRgnIndirect(_In_ LPCRECT)
static HDC
Definition: imagelist.c:92
void WINAPI wined3d_mutex_lock(void)
Definition: wined3d_main.c:368
#define assert(x)
Definition: debug.h:53
BOOL WINAPI DeleteObject(_In_ HGDIOBJ)
voidpf uLong int origin
Definition: ioapi.h:142
HDC dc
Definition: cylfrac.c:34
static HRESULT WINAPI ddraw_clipper_IsClipListChanged(IDirectDrawClipper *iface, BOOL *changed)
Definition: clipper.c:298
#define E_FAIL
Definition: ddrawi.h:102
int WINAPI OffsetRgn(_In_ HRGN, _In_ int, _In_ int)
& rect
Definition: startmenu.cpp:1413
DWORD WINAPI GetVersion(VOID)
Definition: version.c:22
static HRESULT WINAPI ddraw_clipper_SetClipList(IDirectDrawClipper *iface, RGNDATA *region, DWORD flags)
Definition: clipper.c:235
#define RGN_AND
Definition: wingdi.h:355
#define DD_OK
Definition: ddraw.h:186
unsigned int BOOL
Definition: ntddk_ex.h:94
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
#define FIXME(fmt,...)
Definition: debug.h:110
smooth NULL
Definition: ftsmooth.c:416
static struct ddraw_clipper * impl_from_IDirectDrawClipper(IDirectDrawClipper *iface)
Definition: clipper.c:29
#define debugstr_guid
Definition: kernel32.h:35
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define DDERR_ALREADYINITIALIZED
Definition: ddraw.h:67
HRGN WINAPI CreateRectRgn(_In_ int, _In_ int, _In_ int, _In_ int)
#define TRACE(s)
Definition: solgame.cpp:4
LONG HRESULT
Definition: typedefs.h:77
static HRESULT WINAPI ddraw_clipper_QueryInterface(IDirectDrawClipper *iface, REFIID iid, void **object)
Definition: clipper.c:34
const GUID IID_IUnknown
#define WINAPI
Definition: msvc.h:8
const char * wine_dbgstr_rect(const RECT *rect)
unsigned long DWORD
Definition: ntddk_ex.h:95
static HRESULT WINAPI ddraw_clipper_SetHWnd(IDirectDrawClipper *iface, DWORD flags, HWND window)
Definition: clipper.c:81
GLbitfield flags
Definition: glext.h:7161
static const struct IDirectDrawClipperVtbl ddraw_clipper_vtbl
Definition: clipper.c:308
IDirectDrawClipper IDirectDrawClipper_iface
#define InterlockedDecrement
Definition: armddk.h:52
HRESULT ddraw_clipper_init(struct ddraw_clipper *clipper)
Definition: clipper.c:321
static ULONG WINAPI ddraw_clipper_Release(IDirectDrawClipper *iface)
Definition: clipper.c:64
static IHTMLWindow2 * window
Definition: events.c:77
#define ERR(fmt,...)
Definition: debug.h:109
HRGN WINAPI ExtCreateRegion(_In_opt_ const XFORM *lpx, _In_ DWORD nCount, _In_reads_bytes_(nCount) const RGNDATA *lpData)
#define S_OK
Definition: intsafe.h:59
#define InterlockedIncrement
Definition: armddk.h:53
static HRGN get_window_region(HWND window)
Definition: clipper.c:100
#define DDERR_CLIPPERISUSINGHWND
Definition: ddraw.h:141
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4112
static HRESULT WINAPI ddraw_clipper_GetClipList(IDirectDrawClipper *iface, RECT *rect, RGNDATA *clip_list, DWORD *clip_list_size)
Definition: clipper.c:155
#define DDERR_NOCLIPLIST
Definition: ddraw.h:87
static HRESULT WINAPI ddraw_clipper_GetHWnd(IDirectDrawClipper *iface, HWND *window)
Definition: clipper.c:265
struct ddraw_clipper * unsafe_impl_from_IDirectDrawClipper(IDirectDrawClipper *iface)
Definition: clipper.c:329
int WINAPI GetRandomRgn(_In_ HDC, _In_ HRGN, _In_ INT)
unsigned int ULONG
Definition: retypes.h:1
void WINAPI wined3d_mutex_unlock(void)
Definition: wined3d_main.c:373
#define SYSRGN
Definition: GetRandomRgn.c:13
DWORD WINAPI GetRegionData(_In_ HRGN hrgn, _In_ DWORD nCount, _Out_writes_bytes_to_opt_(nCount, return) LPRGNDATA lpRgnData)
#define DDERR_INVALIDPARAMS
Definition: ddraw.h:79
BOOL WINAPI GetDCOrgEx(_In_ HDC, _Out_ LPPOINT)
Definition: coord.c:816
static BOOL heap_free(void *mem)
Definition: appwiz.h:75