Convert some registry helper functions to use unicode versions of
[wine] / dlls / ddraw / clipper.c
1 /*              DirectDrawClipper implementation
2  *
3  * Copyright 2000 Marcus Meissner
4  * Copyright 2000 TransGaming Technologies Inc.
5  *
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
19  */
20
21 #include "config.h"
22
23 #include <stdarg.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #define CONST_VTABLE
28
29 #include "windef.h"
30 #include "winbase.h"
31 #include "wingdi.h"
32 #include "ddraw.h"
33 #include "winerror.h"
34
35 #include "ddraw_private.h"
36
37 #include "wine/debug.h"
38
39 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
40
41 /******************************************************************************
42  *                      DirectDrawCreateClipper (DDRAW.@)
43  */
44
45 static const IDirectDrawClipperVtbl DDRAW_Clipper_VTable;
46
47 HRESULT WINAPI DirectDrawCreateClipper(
48     DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter
49 ) {
50     IDirectDrawClipperImpl* This;
51     TRACE("(%08lx,%p,%p)\n", dwFlags, lplpDDClipper, pUnkOuter);
52
53     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;
61     This->hWnd = 0;
62     This->ddraw_owner = NULL;
63
64     *lplpDDClipper = ICOM_INTERFACE(This, IDirectDrawClipper);
65     return DD_OK;
66 }
67
68 /* This is the classfactory implementation. */
69 HRESULT 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
83 /******************************************************************************
84  *                      IDirectDrawClipper
85  */
86 HRESULT WINAPI Main_DirectDrawClipper_SetHwnd(
87     LPDIRECTDRAWCLIPPER iface, DWORD dwFlags, HWND hWnd
88 ) {
89     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
90
91     TRACE("(%p)->(0x%08lx,0x%08lx)\n", This, dwFlags, (DWORD)hWnd);
92     if( dwFlags ) {
93         FIXME("dwFlags = 0x%08lx, not supported.\n",dwFlags);
94         return DDERR_INVALIDPARAMS;
95     }
96
97     This->hWnd = hWnd;
98     return DD_OK;
99 }
100
101 static 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
109 void 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
115 ULONG WINAPI Main_DirectDrawClipper_Release(LPDIRECTDRAWCLIPPER iface) {
116     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
117     ULONG ref = InterlockedDecrement(&This->ref);
118
119     TRACE("(%p)->() decrementing from %lu.\n", This, ref + 1);
120
121     if (ref == 0)
122     {
123         Main_DirectDrawClipper_Destroy(This);
124         return 0;
125     }
126     else return ref;
127 }
128
129 /***********************************************************************
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 */
146 HRESULT WINAPI Main_DirectDrawClipper_GetClipList(
147     LPDIRECTDRAWCLIPPER iface, LPRECT lpRect, LPRGNDATA lpClipList,
148     LPDWORD lpdwSize)
149 {
150     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
151
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     }
184 }
185
186 /***********************************************************************
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 */
197 HRESULT WINAPI Main_DirectDrawClipper_SetClipList(
198     LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD dwFlag
199 ) {
200     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
201     static int warned = 0;
202     if (warned++ < 10 || lprgn == NULL)
203         FIXME("(%p,%p,%ld),stub!\n",This,lprgn,dwFlag);
204     return DD_OK;
205 }
206
207 HRESULT WINAPI Main_DirectDrawClipper_QueryInterface(
208     LPDIRECTDRAWCLIPPER iface, REFIID riid, LPVOID* ppvObj
209 ) {
210     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
211
212     if (IsEqualGUID(&IID_IUnknown, riid)
213         || IsEqualGUID(&IID_IDirectDrawClipper, riid))
214     {
215         *ppvObj = ICOM_INTERFACE(This, IDirectDrawClipper);
216         InterlockedIncrement(&This->ref);
217         return S_OK;
218     }
219     else
220     {
221         return E_NOINTERFACE;
222     }
223 }
224
225 ULONG WINAPI Main_DirectDrawClipper_AddRef( LPDIRECTDRAWCLIPPER iface )
226 {
227     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
228     ULONG ref = InterlockedIncrement(&This->ref);
229
230     TRACE("(%p)->() incrementing from %lu.\n", This, ref - 1);
231
232     return ref;
233 }
234
235 HRESULT WINAPI Main_DirectDrawClipper_GetHWnd(
236     LPDIRECTDRAWCLIPPER iface, HWND* hWndPtr
237 ) {
238     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
239     TRACE("(%p)->(%p)\n", This, hWndPtr);
240
241     *hWndPtr = This->hWnd;
242
243     return DD_OK;
244 }
245
246 HRESULT WINAPI Main_DirectDrawClipper_Initialize(
247      LPDIRECTDRAWCLIPPER iface, LPDIRECTDRAW lpDD, DWORD dwFlags
248 ) {
249     IDirectDrawImpl* pOwner;
250     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
251     TRACE("(%p)->(%p,0x%08lx)\n", This, lpDD, dwFlags);
252
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
259     return DD_OK;
260 }
261
262 HRESULT WINAPI Main_DirectDrawClipper_IsClipListChanged(
263     LPDIRECTDRAWCLIPPER iface, BOOL* lpbChanged
264 ) {
265     IDirectDrawClipperImpl *This = (IDirectDrawClipperImpl *)iface;
266     FIXME("(%p)->(%p),stub!\n",This,lpbChanged);
267
268     /* XXX What is safest? */
269     *lpbChanged = FALSE;
270
271     return DD_OK;
272 }
273
274 static const IDirectDrawClipperVtbl DDRAW_Clipper_VTable =
275 {
276     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
285 };