Implement ResetDC and PHYSICALOFFSET[X|Y] devcaps.
[wine] / dlls / quartz / fgraph.c
1 /*
2  * Implementation of CLSID_FilterGraph.
3  *
4  * Copyright (C) Hidenori TAKESHIMA <hidenori@a2.ctktv.ne.jp>
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 "windef.h"
24 #include "winbase.h"
25 #include "wingdi.h"
26 #include "winuser.h"
27 #include "winerror.h"
28 #include "strmif.h"
29 #include "control.h"
30 #include "uuids.h"
31
32 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
34
35 #include "quartz_private.h"
36 #include "fgraph.h"
37
38 /***************************************************************************
39  *
40  *      new/delete for CFilterGraph
41  *
42  */
43
44 /* can I use offsetof safely? - FIXME? */
45 static QUARTZ_IFEntry IFEntries[] =
46 {
47   { &IID_IPersist, offsetof(CFilterGraph,persist)-offsetof(CFilterGraph,unk) },
48   { &IID_IDispatch, offsetof(CFilterGraph,disp)-offsetof(CFilterGraph,unk) },
49   { &IID_IFilterGraph, offsetof(CFilterGraph,fgraph)-offsetof(CFilterGraph,unk) },
50   { &IID_IGraphBuilder, offsetof(CFilterGraph,fgraph)-offsetof(CFilterGraph,unk) },
51   { &IID_IFilterGraph2, offsetof(CFilterGraph,fgraph)-offsetof(CFilterGraph,unk) },
52   { &IID_IGraphVersion, offsetof(CFilterGraph,graphversion)-offsetof(CFilterGraph,unk) },
53   { &IID_IMediaControl, offsetof(CFilterGraph,mediacontrol)-offsetof(CFilterGraph,unk) },
54   { &IID_IMediaFilter, offsetof(CFilterGraph,mediafilter)-offsetof(CFilterGraph,unk) },
55   { &IID_IMediaEvent, offsetof(CFilterGraph,mediaevent)-offsetof(CFilterGraph,unk) },
56   { &IID_IMediaEventEx, offsetof(CFilterGraph,mediaevent)-offsetof(CFilterGraph,unk) },
57   { &IID_IMediaEventSink, offsetof(CFilterGraph,mediaeventsink)-offsetof(CFilterGraph,unk) },
58   { &IID_IMediaPosition, offsetof(CFilterGraph,mediaposition)-offsetof(CFilterGraph,unk) },
59   { &IID_IMediaSeeking, offsetof(CFilterGraph,mediaseeking)-offsetof(CFilterGraph,unk) },
60   { &IID_IBasicVideo, offsetof(CFilterGraph,basvid)-offsetof(CFilterGraph,unk) },
61   { &IID_IBasicAudio, offsetof(CFilterGraph,basaud)-offsetof(CFilterGraph,unk) },
62   { &IID_IVideoWindow, offsetof(CFilterGraph,vidwin)-offsetof(CFilterGraph,unk) },
63 };
64
65
66 struct FGInitEntry
67 {
68         HRESULT (*pInit)(CFilterGraph*);
69         void (*pUninit)(CFilterGraph*);
70 };
71
72 static const struct FGInitEntry FGRAPH_Init[] =
73 {
74         #define FGENT(a)        {&CFilterGraph_Init##a,&CFilterGraph_Uninit##a},
75
76         FGENT(IPersist)
77         FGENT(IDispatch)
78         FGENT(IFilterGraph2)
79         FGENT(IGraphVersion)
80         FGENT(IMediaControl)
81         FGENT(IMediaFilter)
82         FGENT(IMediaEventEx)
83         FGENT(IMediaEventSink)
84         FGENT(IMediaPosition)
85         FGENT(IMediaSeeking)
86         FGENT(IBasicVideo)
87         FGENT(IBasicAudio)
88         FGENT(IVideoWindow)
89
90         #undef  FGENT
91         { NULL, NULL },
92 };
93
94
95 static void QUARTZ_DestroyFilterGraph(IUnknown* punk)
96 {
97         CFilterGraph_THIS(punk,unk);
98         int     i;
99
100         TRACE( "(%p)\n", punk );
101
102         /* At first, call Stop. */
103         IMediaControl_Stop( CFilterGraph_IMediaControl(This) );
104         IMediaFilter_Stop( CFilterGraph_IMediaFilter(This) );
105
106         i = 0;
107         while ( FGRAPH_Init[i].pInit != NULL )
108         {
109                 FGRAPH_Init[i].pUninit( This );
110                 i++;
111         }
112
113         TRACE( "succeeded.\n" );
114 }
115
116 HRESULT QUARTZ_CreateFilterGraph(IUnknown* punkOuter,void** ppobj)
117 {
118         CFilterGraph*   pfg;
119         HRESULT hr;
120         int     i;
121
122         TRACE("(%p,%p)\n",punkOuter,ppobj);
123
124         pfg = (CFilterGraph*)QUARTZ_AllocObj( sizeof(CFilterGraph) );
125         if ( pfg == NULL )
126                 return E_OUTOFMEMORY;
127
128         QUARTZ_IUnkInit( &pfg->unk, punkOuter );
129
130         i = 0;
131         hr = NOERROR;
132         while ( FGRAPH_Init[i].pInit != NULL )
133         {
134                 hr = FGRAPH_Init[i].pInit( pfg );
135                 if ( FAILED(hr) )
136                         break;
137                 i++;
138         }
139
140         if ( FAILED(hr) )
141         {
142                 while ( --i >= 0 )
143                         FGRAPH_Init[i].pUninit( pfg );
144                 QUARTZ_FreeObj( pfg );
145                 return hr;
146         }
147
148         pfg->unk.pEntries = IFEntries;
149         pfg->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]);
150         pfg->unk.pOnFinalRelease = QUARTZ_DestroyFilterGraph;
151
152         *ppobj = (void*)(&pfg->unk);
153
154         return S_OK;
155 }
156
157
158 /***************************************************************************
159  *
160  *      CFilterGraph::IPersist
161  *
162  */
163
164 static HRESULT WINAPI
165 IPersist_fnQueryInterface(IPersist* iface,REFIID riid,void** ppobj)
166 {
167         CFilterGraph_THIS(iface,persist);
168
169         TRACE("(%p)->()\n",This);
170
171         return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
172 }
173
174 static ULONG WINAPI
175 IPersist_fnAddRef(IPersist* iface)
176 {
177         CFilterGraph_THIS(iface,persist);
178
179         TRACE("(%p)->()\n",This);
180
181         return IUnknown_AddRef(This->unk.punkControl);
182 }
183
184 static ULONG WINAPI
185 IPersist_fnRelease(IPersist* iface)
186 {
187         CFilterGraph_THIS(iface,persist);
188
189         TRACE("(%p)->()\n",This);
190
191         return IUnknown_Release(This->unk.punkControl);
192 }
193
194
195 static HRESULT WINAPI
196 IPersist_fnGetClassID(IPersist* iface,CLSID* pclsid)
197 {
198         CFilterGraph_THIS(iface,persist);
199
200         TRACE("(%p)->()\n",This);
201
202         if ( pclsid == NULL )
203                 return E_POINTER;
204         memcpy( pclsid, &CLSID_FilterGraph, sizeof(CLSID) );
205
206         return E_NOTIMPL;
207 }
208
209
210 static ICOM_VTABLE(IPersist) ipersist =
211 {
212         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
213         /* IUnknown fields */
214         IPersist_fnQueryInterface,
215         IPersist_fnAddRef,
216         IPersist_fnRelease,
217         /* IPersist fields */
218         IPersist_fnGetClassID,
219 };
220
221 HRESULT CFilterGraph_InitIPersist( CFilterGraph* pfg )
222 {
223         TRACE("(%p)\n",pfg);
224         ICOM_VTBL(&pfg->persist) = &ipersist;
225
226         return NOERROR;
227 }
228
229 void CFilterGraph_UninitIPersist( CFilterGraph* pfg )
230 {
231         TRACE("(%p)\n",pfg);
232 }
233
234 /***************************************************************************
235  *
236  *      CFilterGraph::IDispatch
237  *
238  */
239
240 static HRESULT WINAPI
241 IDispatch_fnQueryInterface(IDispatch* iface,REFIID riid,void** ppobj)
242 {
243         CFilterGraph_THIS(iface,disp);
244
245         TRACE("(%p)->()\n",This);
246
247         return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
248 }
249
250 static ULONG WINAPI
251 IDispatch_fnAddRef(IDispatch* iface)
252 {
253         CFilterGraph_THIS(iface,disp);
254
255         TRACE("(%p)->()\n",This);
256
257         return IUnknown_AddRef(This->unk.punkControl);
258 }
259
260 static ULONG WINAPI
261 IDispatch_fnRelease(IDispatch* iface)
262 {
263         CFilterGraph_THIS(iface,disp);
264
265         TRACE("(%p)->()\n",This);
266
267         return IUnknown_Release(This->unk.punkControl);
268 }
269
270 static HRESULT WINAPI
271 IDispatch_fnGetTypeInfoCount(IDispatch* iface,UINT* pcTypeInfo)
272 {
273         CFilterGraph_THIS(iface,disp);
274
275         FIXME("(%p)->()\n",This);
276
277         return E_NOTIMPL;
278 }
279
280 static HRESULT WINAPI
281 IDispatch_fnGetTypeInfo(IDispatch* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
282 {
283         CFilterGraph_THIS(iface,disp);
284
285         FIXME("(%p)->()\n",This);
286
287         return E_NOTIMPL;
288 }
289
290 static HRESULT WINAPI
291 IDispatch_fnGetIDsOfNames(IDispatch* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
292 {
293         CFilterGraph_THIS(iface,disp);
294
295         FIXME("(%p)->()\n",This);
296
297         return E_NOTIMPL;
298 }
299
300 static HRESULT WINAPI
301 IDispatch_fnInvoke(IDispatch* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr)
302 {
303         CFilterGraph_THIS(iface,disp);
304
305         FIXME("(%p)->()\n",This);
306
307         return E_NOTIMPL;
308 }
309
310
311
312 static ICOM_VTABLE(IDispatch) idispatch =
313 {
314         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
315         /* IUnknown fields */
316         IDispatch_fnQueryInterface,
317         IDispatch_fnAddRef,
318         IDispatch_fnRelease,
319         /* IDispatch fields */
320         IDispatch_fnGetTypeInfoCount,
321         IDispatch_fnGetTypeInfo,
322         IDispatch_fnGetIDsOfNames,
323         IDispatch_fnInvoke,
324 };
325
326
327 HRESULT CFilterGraph_InitIDispatch( CFilterGraph* pfg )
328 {
329         TRACE("(%p)\n",pfg);
330         ICOM_VTBL(&pfg->disp) = &idispatch;
331
332         return NOERROR;
333 }
334
335 void CFilterGraph_UninitIDispatch( CFilterGraph* pfg )
336 {
337         TRACE("(%p)\n",pfg);
338 }
339
340
341