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