wrc: Fix parsing of virtkey accelerators.
[wine/multimedia.git] / dlls / ddraw / clipper.c
blob81e9e8b8f9d845e4fce1d5b2b290a47383dc8eb1
1 /* DirectDrawClipper implementation
3 * Copyright 2000 (c) Marcus Meissner
4 * Copyright 2000 (c) TransGaming Technologies Inc.
5 * Copyright 2006 (c) Stefan Dösinger
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.
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.
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
22 #include "config.h"
23 #include "wine/port.h"
25 #include "ddraw_private.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
29 static inline struct ddraw_clipper *impl_from_IDirectDrawClipper(IDirectDrawClipper *iface)
31 return CONTAINING_RECORD(iface, struct ddraw_clipper, IDirectDrawClipper_iface);
34 static HRESULT WINAPI ddraw_clipper_QueryInterface(IDirectDrawClipper *iface, REFIID iid, void **object)
36 struct ddraw_clipper *clipper = impl_from_IDirectDrawClipper(iface);
38 TRACE("iface %p, iid %s, object %p.\n", iface, debugstr_guid(iid), object);
40 if (IsEqualGUID(&IID_IDirectDrawClipper, iid)
41 || IsEqualGUID(&IID_IUnknown, iid))
43 IDirectDrawClipper_AddRef(&clipper->IDirectDrawClipper_iface);
44 *object = &clipper->IDirectDrawClipper_iface;
45 return S_OK;
48 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
49 *object = NULL;
51 return E_NOINTERFACE;
54 static ULONG WINAPI ddraw_clipper_AddRef(IDirectDrawClipper *iface)
56 struct ddraw_clipper *clipper = impl_from_IDirectDrawClipper(iface);
57 ULONG refcount = InterlockedIncrement(&clipper->ref);
59 TRACE("%p increasing refcount to %u.\n", clipper, refcount);
61 return refcount;
64 static ULONG WINAPI ddraw_clipper_Release(IDirectDrawClipper *iface)
66 struct ddraw_clipper *clipper = impl_from_IDirectDrawClipper(iface);
67 ULONG refcount = InterlockedDecrement(&clipper->ref);
69 TRACE("%p decreasing refcount to %u.\n", clipper, refcount);
71 if (!refcount)
73 if (clipper->region)
74 DeleteObject(clipper->region);
75 HeapFree(GetProcessHeap(), 0, clipper);
78 return refcount;
81 static HRESULT WINAPI ddraw_clipper_SetHWnd(IDirectDrawClipper *iface, DWORD flags, HWND window)
83 struct ddraw_clipper *clipper = impl_from_IDirectDrawClipper(iface);
85 TRACE("iface %p, flags %#x, window %p.\n", iface, flags, window);
87 if (flags)
89 FIXME("flags %#x, not supported.\n", flags);
90 return DDERR_INVALIDPARAMS;
93 wined3d_mutex_lock();
94 clipper->window = window;
95 wined3d_mutex_unlock();
97 return DD_OK;
100 static HRGN get_window_region(HWND window)
102 POINT origin = {0, 0};
103 RECT client_rect;
105 if (!GetClientRect(window, &client_rect))
107 /* This can happen if the window is destroyed, for example. */
108 WARN("Failed to get client rect.\n");
109 return NULL;
112 if (!ClientToScreen(window, &origin))
114 ERR("Failed to translate origin.\n");
115 return NULL;
118 if (!OffsetRect(&client_rect, origin.x, origin.y))
120 ERR("Failed to translate client rect.\n");
121 return NULL;
124 return CreateRectRgnIndirect(&client_rect);
127 /*****************************************************************************
128 * IDirectDrawClipper::GetClipList
130 * Retrieve a copy of the clip list
132 * Arguments:
133 * rect: Rectangle to be used to clip the clip list or NULL for the
134 * entire clip list.
135 * clip_list: structure for the resulting copy of the clip list.
136 * If NULL, fills Size up to the number of bytes necessary to hold
137 * the entire clip.
138 * clip_list_size: Size of resulting clip list; size of the buffer at clip_list
139 * or, if clip_list is NULL, receives the required size of the buffer
140 * in bytes.
142 * RETURNS
143 * Either DD_OK or DDERR_*
144 ************************************************************************/
145 static HRESULT WINAPI ddraw_clipper_GetClipList(IDirectDrawClipper *iface, RECT *rect,
146 RGNDATA *clip_list, DWORD *clip_list_size)
148 struct ddraw_clipper *clipper = impl_from_IDirectDrawClipper(iface);
149 HRGN region;
151 TRACE("iface %p, rect %s, clip_list %p, clip_list_size %p.\n",
152 iface, wine_dbgstr_rect(rect), clip_list, clip_list_size);
154 wined3d_mutex_lock();
156 if (clipper->window)
158 if (!(region = get_window_region(clipper->window)))
160 wined3d_mutex_unlock();
161 WARN("Failed to get window region.\n");
162 return E_FAIL;
165 else
167 if (!(region = clipper->region))
169 wined3d_mutex_unlock();
170 WARN("No clip list set.\n");
171 return DDERR_NOCLIPLIST;
175 if (rect)
177 HRGN clip_region;
179 if (!(clip_region = CreateRectRgnIndirect(rect)))
181 wined3d_mutex_unlock();
182 ERR("Failed to create region.\n");
183 if (clipper->window)
184 DeleteObject(region);
185 return E_FAIL;
188 if (CombineRgn(clip_region, region, clip_region, RGN_AND) == ERROR)
190 wined3d_mutex_unlock();
191 ERR("Failed to combine regions.\n");
192 DeleteObject(clip_region);
193 if (clipper->window)
194 DeleteObject(region);
195 return E_FAIL;
198 if (clipper->window)
199 DeleteObject(region);
200 region = clip_region;
203 *clip_list_size = GetRegionData(region, *clip_list_size, clip_list);
204 if (rect || clipper->window)
205 DeleteObject(region);
207 wined3d_mutex_unlock();
208 return DD_OK;
211 /*****************************************************************************
212 * IDirectDrawClipper::SetClipList
214 * Sets or deletes (if region is NULL) the clip list
216 * This implementation is a stub and returns DD_OK always to make the app
217 * happy.
219 * PARAMS
220 * region Pointer to a LRGNDATA structure or NULL
221 * flags not used, must be 0
222 * RETURNS
223 * Either DD_OK or DDERR_*
224 *****************************************************************************/
225 static HRESULT WINAPI ddraw_clipper_SetClipList(IDirectDrawClipper *iface, RGNDATA *region, DWORD flags)
227 struct ddraw_clipper *clipper = impl_from_IDirectDrawClipper(iface);
229 TRACE("iface %p, region %p, flags %#x.\n", iface, region, flags);
231 wined3d_mutex_lock();
233 if (clipper->window)
235 wined3d_mutex_unlock();
236 return DDERR_CLIPPERISUSINGHWND;
239 if (clipper->region)
240 DeleteObject(clipper->region);
241 if (!region)
242 clipper->region = NULL;
243 else if (!(clipper->region = ExtCreateRegion(NULL, 0, region)))
245 wined3d_mutex_unlock();
246 ERR("Failed to create region.\n");
247 return E_FAIL;
250 wined3d_mutex_unlock();
252 return DD_OK;
255 static HRESULT WINAPI ddraw_clipper_GetHWnd(IDirectDrawClipper *iface, HWND *window)
257 struct ddraw_clipper *clipper = impl_from_IDirectDrawClipper(iface);
259 TRACE("iface %p, window %p.\n", iface, window);
261 wined3d_mutex_lock();
262 *window = clipper->window;
263 wined3d_mutex_unlock();
265 return DD_OK;
268 static HRESULT WINAPI ddraw_clipper_Initialize(IDirectDrawClipper *iface,
269 IDirectDraw *ddraw, DWORD flags)
271 struct ddraw_clipper *clipper = impl_from_IDirectDrawClipper(iface);
273 TRACE("iface %p, ddraw %p, flags %#x.\n", iface, ddraw, flags);
275 wined3d_mutex_lock();
276 if (clipper->initialized)
278 wined3d_mutex_unlock();
279 return DDERR_ALREADYINITIALIZED;
282 clipper->initialized = TRUE;
283 wined3d_mutex_unlock();
285 return DD_OK;
288 static HRESULT WINAPI ddraw_clipper_IsClipListChanged(IDirectDrawClipper *iface, BOOL *changed)
290 FIXME("iface %p, changed %p stub!\n", iface, changed);
292 /* XXX What is safest? */
293 *changed = FALSE;
295 return DD_OK;
298 static const struct IDirectDrawClipperVtbl ddraw_clipper_vtbl =
300 ddraw_clipper_QueryInterface,
301 ddraw_clipper_AddRef,
302 ddraw_clipper_Release,
303 ddraw_clipper_GetClipList,
304 ddraw_clipper_GetHWnd,
305 ddraw_clipper_Initialize,
306 ddraw_clipper_IsClipListChanged,
307 ddraw_clipper_SetClipList,
308 ddraw_clipper_SetHWnd,
311 HRESULT ddraw_clipper_init(struct ddraw_clipper *clipper)
313 clipper->IDirectDrawClipper_iface.lpVtbl = &ddraw_clipper_vtbl;
314 clipper->ref = 1;
316 return DD_OK;
319 struct ddraw_clipper *unsafe_impl_from_IDirectDrawClipper(IDirectDrawClipper *iface)
321 if (!iface)
322 return NULL;
323 assert(iface->lpVtbl == &ddraw_clipper_vtbl);
325 return impl_from_IDirectDrawClipper(iface);