Avoid excessive heap memory reallocation when generating EMF
[wine] / dlls / ddraw / dclipper / main.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 #include "windef.h"
28 #include "winbase.h"
29 #include "wingdi.h"
30 #include "ddraw.h"
31 #include "winerror.h"
32
33 #include "ddraw_private.h"
34 #include "dclipper/main.h"
35 #include "ddraw/main.h"
36
37 #include "wine/debug.h"
38
39 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
40
41 /******************************************************************************
42  *                      DirectDrawCreateClipper (DDRAW.@)
43  */
44
45 static ICOM_VTABLE(IDirectDrawClipper) 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     ICOM_THIS(IDirectDrawClipperImpl,iface);
90
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);
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     ICOM_THIS(IDirectDrawClipperImpl,iface);
117     TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
118
119     if (--This->ref == 0)
120     {
121         Main_DirectDrawClipper_Destroy(This);
122         return 0;
123     }
124     else return This->ref;
125 }
126
127 HRESULT WINAPI Main_DirectDrawClipper_GetClipList(
128     LPDIRECTDRAWCLIPPER iface,LPRECT prcClip,LPRGNDATA lprgn,LPDWORD pdwSize
129 ) {
130     ICOM_THIS(IDirectDrawClipperImpl,iface);
131     static int warned = 0;
132     if (warned++ < 10)
133         FIXME("(%p,%p,%p,%p),stub!\n",This,prcClip,lprgn,pdwSize);
134     if (pdwSize) *pdwSize=0;
135     return DDERR_NOCLIPLIST;
136 }
137
138 HRESULT WINAPI Main_DirectDrawClipper_SetClipList(
139     LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD pdwSize
140 ) {
141     ICOM_THIS(IDirectDrawClipperImpl,iface);
142     FIXME("(%p,%p,%ld),stub!\n",This,lprgn,pdwSize);
143     return DD_OK;
144 }
145
146 HRESULT WINAPI Main_DirectDrawClipper_QueryInterface(
147     LPDIRECTDRAWCLIPPER iface, REFIID riid, LPVOID* ppvObj
148 ) {
149     ICOM_THIS(IDirectDrawClipperImpl,iface);
150
151     if (IsEqualGUID(&IID_IUnknown, riid)
152         || IsEqualGUID(&IID_IDirectDrawClipper, riid))
153     {
154         *ppvObj = ICOM_INTERFACE(This, IDirectDrawClipper);
155         ++This->ref;
156         return S_OK;
157     }
158     else
159     {
160         return E_NOINTERFACE;
161     }
162 }
163
164 ULONG WINAPI Main_DirectDrawClipper_AddRef( LPDIRECTDRAWCLIPPER iface )
165 {
166     ICOM_THIS(IDirectDrawClipperImpl,iface);
167     TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
168     return ++This->ref;
169 }
170
171 HRESULT WINAPI Main_DirectDrawClipper_GetHWnd(
172     LPDIRECTDRAWCLIPPER iface, HWND* hWndPtr
173 ) {
174     ICOM_THIS(IDirectDrawClipperImpl,iface);
175     FIXME("(%p)->(%p),stub!\n",This,hWndPtr);
176
177     *hWndPtr = This->hWnd;
178
179     return DD_OK;
180 }
181
182 HRESULT WINAPI Main_DirectDrawClipper_Initialize(
183      LPDIRECTDRAWCLIPPER iface, LPDIRECTDRAW lpDD, DWORD dwFlags
184 ) {
185     IDirectDrawImpl* pOwner;
186     ICOM_THIS(IDirectDrawClipperImpl,iface);
187     FIXME("(%p)->(%p,0x%08lx),stub!\n",This,lpDD,dwFlags);
188
189     if (This->ddraw_owner != NULL) return DDERR_ALREADYINITIALIZED;
190
191     pOwner = ICOM_OBJECT(IDirectDrawImpl, IDirectDraw, lpDD);
192     This->ddraw_owner = pOwner;
193     Main_DirectDraw_AddClipper(pOwner, This);
194
195     return DD_OK;
196 }
197
198 HRESULT WINAPI Main_DirectDrawClipper_IsClipListChanged(
199     LPDIRECTDRAWCLIPPER iface, BOOL* lpbChanged
200 ) {
201     ICOM_THIS(IDirectDrawClipperImpl,iface);
202     FIXME("(%p)->(%p),stub!\n",This,lpbChanged);
203
204     /* XXX What is safest? */
205     *lpbChanged = FALSE;
206
207     return DD_OK;
208 }
209
210 static ICOM_VTABLE(IDirectDrawClipper) DDRAW_Clipper_VTable =
211 {
212     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
213     Main_DirectDrawClipper_QueryInterface,
214     Main_DirectDrawClipper_AddRef,
215     Main_DirectDrawClipper_Release,
216     Main_DirectDrawClipper_GetClipList,
217     Main_DirectDrawClipper_GetHWnd,
218     Main_DirectDrawClipper_Initialize,
219     Main_DirectDrawClipper_IsClipListChanged,
220     Main_DirectDrawClipper_SetClipList,
221     Main_DirectDrawClipper_SetHwnd
222 };