user32: Always use the default alignment when displaying submenu popups.
[wine/multimedia.git] / dlls / ddraw / clipper.c
blobc67a951c8ddc7938d454d680c8e8c41a550c634b
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)
72 HeapFree(GetProcessHeap(), 0, clipper);
74 return refcount;
77 static HRESULT WINAPI ddraw_clipper_SetHWnd(IDirectDrawClipper *iface, DWORD flags, HWND window)
79 struct ddraw_clipper *clipper = impl_from_IDirectDrawClipper(iface);
81 TRACE("iface %p, flags %#x, window %p.\n", iface, flags, window);
83 if (flags)
85 FIXME("flags %#x, not supported.\n", flags);
86 return DDERR_INVALIDPARAMS;
89 wined3d_mutex_lock();
90 clipper->window = window;
91 wined3d_mutex_unlock();
93 return DD_OK;
96 /*****************************************************************************
97 * IDirectDrawClipper::GetClipList
99 * Retrieve a copy of the clip list
101 * Arguments:
102 * rect: Rectangle to be used to clip the clip list or NULL for the
103 * entire clip list.
104 * clip_list: structure for the resulting copy of the clip list.
105 * If NULL, fills Size up to the number of bytes necessary to hold
106 * the entire clip.
107 * clip_list_size: Size of resulting clip list; size of the buffer at clip_list
108 * or, if clip_list is NULL, receives the required size of the buffer
109 * in bytes.
111 * RETURNS
112 * Either DD_OK or DDERR_*
113 ************************************************************************/
114 static HRESULT WINAPI ddraw_clipper_GetClipList(IDirectDrawClipper *iface, RECT *rect,
115 RGNDATA *clip_list, DWORD *clip_list_size)
117 struct ddraw_clipper *clipper = impl_from_IDirectDrawClipper(iface);
118 static unsigned int once;
120 TRACE("iface %p, rect %s, clip_list %p, clip_list_size %p.\n",
121 iface, wine_dbgstr_rect(rect), clip_list, clip_list_size);
123 wined3d_mutex_lock();
125 if (clipper->window)
127 HDC dc = GetDCEx(clipper->window, NULL, DCX_WINDOW);
128 if (dc)
130 HRGN rgn = CreateRectRgn(0, 0, 0, 0);
131 if (GetRandomRgn(dc, rgn, SYSRGN))
133 if (GetVersion() & 0x80000000)
135 POINT origin;
136 GetDCOrgEx(dc, &origin);
137 OffsetRgn(rgn, origin.x, origin.y);
139 if (rect)
141 HRGN clip_rgn = CreateRectRgn(rect->left, rect->top,
142 rect->right, rect->bottom);
143 CombineRgn(rgn, rgn, clip_rgn, RGN_AND);
144 DeleteObject(clip_rgn);
146 *clip_list_size = GetRegionData(rgn, *clip_list_size, clip_list);
148 DeleteObject(rgn);
149 ReleaseDC(clipper->window, dc);
152 wined3d_mutex_unlock();
153 return DD_OK;
156 if (!once++)
157 FIXME("clipper %p, rect %s, clip_list %p, clip_list_size %p stub!\n",
158 clipper, wine_dbgstr_rect(rect), clip_list, clip_list_size);
160 if (clip_list_size)
161 *clip_list_size = 0;
163 wined3d_mutex_unlock();
164 return DDERR_NOCLIPLIST;
167 /*****************************************************************************
168 * IDirectDrawClipper::SetClipList
170 * Sets or deletes (if region is NULL) the clip list
172 * This implementation is a stub and returns DD_OK always to make the app
173 * happy.
175 * PARAMS
176 * region Pointer to a LRGNDATA structure or NULL
177 * flags not used, must be 0
178 * RETURNS
179 * Either DD_OK or DDERR_*
180 *****************************************************************************/
181 static HRESULT WINAPI ddraw_clipper_SetClipList(IDirectDrawClipper *iface, RGNDATA *region, DWORD flags)
183 FIXME("iface %p, region %p, flags %#x stub!\n", iface, region, flags);
185 return DD_OK;
188 static HRESULT WINAPI ddraw_clipper_GetHWnd(IDirectDrawClipper *iface, HWND *window)
190 struct ddraw_clipper *clipper = impl_from_IDirectDrawClipper(iface);
192 TRACE("iface %p, window %p.\n", iface, window);
194 wined3d_mutex_lock();
195 *window = clipper->window;
196 wined3d_mutex_unlock();
198 return DD_OK;
201 static HRESULT WINAPI ddraw_clipper_Initialize(IDirectDrawClipper *iface,
202 IDirectDraw *ddraw, DWORD flags)
204 struct ddraw_clipper *clipper = impl_from_IDirectDrawClipper(iface);
206 TRACE("iface %p, ddraw %p, flags %#x.\n", iface, ddraw, flags);
208 wined3d_mutex_lock();
209 if (clipper->initialized)
211 wined3d_mutex_unlock();
212 return DDERR_ALREADYINITIALIZED;
215 clipper->initialized = TRUE;
216 wined3d_mutex_unlock();
218 return DD_OK;
221 static HRESULT WINAPI ddraw_clipper_IsClipListChanged(IDirectDrawClipper *iface, BOOL *changed)
223 FIXME("iface %p, changed %p stub!\n", iface, changed);
225 /* XXX What is safest? */
226 *changed = FALSE;
228 return DD_OK;
231 static const struct IDirectDrawClipperVtbl ddraw_clipper_vtbl =
233 ddraw_clipper_QueryInterface,
234 ddraw_clipper_AddRef,
235 ddraw_clipper_Release,
236 ddraw_clipper_GetClipList,
237 ddraw_clipper_GetHWnd,
238 ddraw_clipper_Initialize,
239 ddraw_clipper_IsClipListChanged,
240 ddraw_clipper_SetClipList,
241 ddraw_clipper_SetHWnd,
244 HRESULT ddraw_clipper_init(struct ddraw_clipper *clipper)
246 clipper->IDirectDrawClipper_iface.lpVtbl = &ddraw_clipper_vtbl;
247 clipper->ref = 1;
249 return DD_OK;
252 struct ddraw_clipper *unsafe_impl_from_IDirectDrawClipper(IDirectDrawClipper *iface)
254 if (!iface)
255 return NULL;
256 assert(iface->lpVtbl == &ddraw_clipper_vtbl);
258 return impl_from_IDirectDrawClipper(iface);