Update shell xxxAW wrapper prototypes for fixed SHLWAPI functions.
[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   { &IID_IAMStats, offsetof(CFilterGraph,amstats)-offsetof(CFilterGraph,unk) },
66 };
67
68
69 struct FGInitEntry
70 {
71         HRESULT (*pInit)(CFilterGraph*);
72         void (*pUninit)(CFilterGraph*);
73 };
74
75 static const struct FGInitEntry FGRAPH_Init[] =
76 {
77         #define FGENT(a)        {&CFilterGraph_Init##a,&CFilterGraph_Uninit##a},
78
79         FGENT(IPersist)
80         FGENT(IDispatch)
81         FGENT(IFilterGraph2)
82         FGENT(IGraphVersion)
83         FGENT(IGraphConfig)
84         FGENT(IMediaControl)
85         FGENT(IMediaFilter)
86         FGENT(IMediaEventEx)
87         FGENT(IMediaEventSink)
88         FGENT(IMediaPosition)
89         FGENT(IMediaSeeking)
90         FGENT(IBasicVideo2)
91         FGENT(IBasicAudio)
92         FGENT(IVideoWindow)
93         FGENT(IAMStats)
94
95         #undef  FGENT
96         { NULL, NULL },
97 };
98
99
100 static void QUARTZ_DestroyFilterGraph(IUnknown* punk)
101 {
102         CFilterGraph_THIS(punk,unk);
103         int     i;
104
105         TRACE( "(%p)\n", punk );
106
107         /* At first, call Stop. */
108         IMediaControl_Stop( CFilterGraph_IMediaControl(This) );
109         IMediaFilter_Stop( CFilterGraph_IMediaFilter(This) );
110
111         i = 0;
112         while ( FGRAPH_Init[i].pInit != NULL )
113         {
114                 FGRAPH_Init[i].pUninit( This );
115                 i++;
116         }
117
118         TRACE( "succeeded.\n" );
119 }
120
121 HRESULT QUARTZ_CreateFilterGraph(IUnknown* punkOuter,void** ppobj)
122 {
123         CFilterGraph*   pfg;
124         HRESULT hr;
125         int     i;
126
127         TRACE("(%p,%p)\n",punkOuter,ppobj);
128
129         pfg = (CFilterGraph*)QUARTZ_AllocObj( sizeof(CFilterGraph) );
130         if ( pfg == NULL )
131                 return E_OUTOFMEMORY;
132
133         QUARTZ_IUnkInit( &pfg->unk, punkOuter );
134
135         i = 0;
136         hr = NOERROR;
137         while ( FGRAPH_Init[i].pInit != NULL )
138         {
139                 hr = FGRAPH_Init[i].pInit( pfg );
140                 if ( FAILED(hr) )
141                         break;
142                 i++;
143         }
144
145         if ( FAILED(hr) )
146         {
147                 while ( --i >= 0 )
148                         FGRAPH_Init[i].pUninit( pfg );
149                 QUARTZ_FreeObj( pfg );
150                 return hr;
151         }
152
153         pfg->unk.pEntries = IFEntries;
154         pfg->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]);
155         pfg->unk.pOnFinalRelease = QUARTZ_DestroyFilterGraph;
156
157         *ppobj = (void*)(&pfg->unk);
158
159         return S_OK;
160 }
161
162
163 /***************************************************************************
164  *
165  *      CFilterGraph::IPersist
166  *
167  */
168
169 static HRESULT WINAPI
170 IPersist_fnQueryInterface(IPersist* iface,REFIID riid,void** ppobj)
171 {
172         CFilterGraph_THIS(iface,persist);
173
174         TRACE("(%p)->()\n",This);
175
176         return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
177 }
178
179 static ULONG WINAPI
180 IPersist_fnAddRef(IPersist* iface)
181 {
182         CFilterGraph_THIS(iface,persist);
183
184         TRACE("(%p)->()\n",This);
185
186         return IUnknown_AddRef(This->unk.punkControl);
187 }
188
189 static ULONG WINAPI
190 IPersist_fnRelease(IPersist* iface)
191 {
192         CFilterGraph_THIS(iface,persist);
193
194         TRACE("(%p)->()\n",This);
195
196         return IUnknown_Release(This->unk.punkControl);
197 }
198
199
200 static HRESULT WINAPI
201 IPersist_fnGetClassID(IPersist* iface,CLSID* pclsid)
202 {
203         CFilterGraph_THIS(iface,persist);
204
205         TRACE("(%p)->()\n",This);
206
207         if ( pclsid == NULL )
208                 return E_POINTER;
209         memcpy( pclsid, &CLSID_FilterGraph, sizeof(CLSID) );
210
211         return E_NOTIMPL;
212 }
213
214
215 static ICOM_VTABLE(IPersist) ipersist =
216 {
217         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
218         /* IUnknown fields */
219         IPersist_fnQueryInterface,
220         IPersist_fnAddRef,
221         IPersist_fnRelease,
222         /* IPersist fields */
223         IPersist_fnGetClassID,
224 };
225
226 HRESULT CFilterGraph_InitIPersist( CFilterGraph* pfg )
227 {
228         TRACE("(%p)\n",pfg);
229         ICOM_VTBL(&pfg->persist) = &ipersist;
230
231         return NOERROR;
232 }
233
234 void CFilterGraph_UninitIPersist( CFilterGraph* pfg )
235 {
236         TRACE("(%p)\n",pfg);
237 }
238
239 /***************************************************************************
240  *
241  *      CFilterGraph::IDispatch
242  *
243  */
244
245 static HRESULT WINAPI
246 IDispatch_fnQueryInterface(IDispatch* iface,REFIID riid,void** ppobj)
247 {
248         CFilterGraph_THIS(iface,disp);
249
250         TRACE("(%p)->()\n",This);
251
252         return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
253 }
254
255 static ULONG WINAPI
256 IDispatch_fnAddRef(IDispatch* iface)
257 {
258         CFilterGraph_THIS(iface,disp);
259
260         TRACE("(%p)->()\n",This);
261
262         return IUnknown_AddRef(This->unk.punkControl);
263 }
264
265 static ULONG WINAPI
266 IDispatch_fnRelease(IDispatch* iface)
267 {
268         CFilterGraph_THIS(iface,disp);
269
270         TRACE("(%p)->()\n",This);
271
272         return IUnknown_Release(This->unk.punkControl);
273 }
274
275 static HRESULT WINAPI
276 IDispatch_fnGetTypeInfoCount(IDispatch* iface,UINT* pcTypeInfo)
277 {
278         CFilterGraph_THIS(iface,disp);
279
280         FIXME("(%p)->()\n",This);
281
282         return E_NOTIMPL;
283 }
284
285 static HRESULT WINAPI
286 IDispatch_fnGetTypeInfo(IDispatch* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
287 {
288         CFilterGraph_THIS(iface,disp);
289
290         FIXME("(%p)->()\n",This);
291
292         return E_NOTIMPL;
293 }
294
295 static HRESULT WINAPI
296 IDispatch_fnGetIDsOfNames(IDispatch* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
297 {
298         CFilterGraph_THIS(iface,disp);
299
300         FIXME("(%p)->()\n",This);
301
302         return E_NOTIMPL;
303 }
304
305 static HRESULT WINAPI
306 IDispatch_fnInvoke(IDispatch* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr)
307 {
308         CFilterGraph_THIS(iface,disp);
309
310         FIXME("(%p)->()\n",This);
311
312         return E_NOTIMPL;
313 }
314
315
316
317 static ICOM_VTABLE(IDispatch) idispatch =
318 {
319         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
320         /* IUnknown fields */
321         IDispatch_fnQueryInterface,
322         IDispatch_fnAddRef,
323         IDispatch_fnRelease,
324         /* IDispatch fields */
325         IDispatch_fnGetTypeInfoCount,
326         IDispatch_fnGetTypeInfo,
327         IDispatch_fnGetIDsOfNames,
328         IDispatch_fnInvoke,
329 };
330
331
332 HRESULT CFilterGraph_InitIDispatch( CFilterGraph* pfg )
333 {
334         TRACE("(%p)\n",pfg);
335         ICOM_VTBL(&pfg->disp) = &idispatch;
336
337         return NOERROR;
338 }
339
340 void CFilterGraph_UninitIDispatch( CFilterGraph* pfg )
341 {
342         TRACE("(%p)\n",pfg);
343 }
344
345 /***************************************************************************
346  *
347  *      CFilterGraph::IAMStats
348  *
349  */
350
351 static HRESULT WINAPI
352 IAMStats_fnQueryInterface(IAMStats* iface,REFIID riid,void** ppobj)
353 {
354         CFilterGraph_THIS(iface,amstats);
355
356         TRACE("(%p)->()\n",This);
357
358         return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
359 }
360
361 static ULONG WINAPI
362 IAMStats_fnAddRef(IAMStats* iface)
363 {
364         CFilterGraph_THIS(iface,amstats);
365
366         TRACE("(%p)->()\n",This);
367
368         return IUnknown_AddRef(This->unk.punkControl);
369 }
370
371 static ULONG WINAPI
372 IAMStats_fnRelease(IAMStats* iface)
373 {
374         CFilterGraph_THIS(iface,amstats);
375
376         TRACE("(%p)->()\n",This);
377
378         return IUnknown_Release(This->unk.punkControl);
379 }
380
381 static HRESULT WINAPI
382 IAMStats_fnGetTypeInfoCount(IAMStats* iface,UINT* pcTypeInfo)
383 {
384         CFilterGraph_THIS(iface,amstats);
385
386         FIXME("(%p)->()\n",This);
387
388         return E_NOTIMPL;
389 }
390
391 static HRESULT WINAPI
392 IAMStats_fnGetTypeInfo(IAMStats* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
393 {
394         CFilterGraph_THIS(iface,amstats);
395
396         FIXME("(%p)->()\n",This);
397
398         return E_NOTIMPL;
399 }
400
401 static HRESULT WINAPI
402 IAMStats_fnGetIDsOfNames(IAMStats* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
403 {
404         CFilterGraph_THIS(iface,amstats);
405
406         FIXME("(%p)->()\n",This);
407
408         return E_NOTIMPL;
409 }
410
411 static HRESULT WINAPI
412 IAMStats_fnInvoke(IAMStats* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr)
413 {
414         CFilterGraph_THIS(iface,amstats);
415
416         FIXME("(%p)->()\n",This);
417
418         return E_NOTIMPL;
419 }
420
421 static HRESULT WINAPI
422 IAMStats_fnReset(IAMStats* iface)
423 {
424         CFilterGraph_THIS(iface,amstats);
425
426         FIXME("(%p) stub\n",This);
427         return E_NOTIMPL;
428 }
429
430 static HRESULT WINAPI
431 IAMStats_fnget_Count(IAMStats* iface,long* plCount)
432 {
433         CFilterGraph_THIS(iface,amstats);
434
435         FIXME("(%p,%p) stub\n",This,plCount);
436
437         if ( plCount == NULL )
438                 return E_POINTER;
439         *plCount = 0;
440
441         return E_NOTIMPL;
442 }
443
444 static HRESULT WINAPI
445 IAMStats_fnGetValueByIndex(IAMStats* iface,long lIndex,BSTR* pbstrName,long* lCount,double* pdblLast,double* pdblAverage,double* pdblStdDev,double* pdblMin,double* pdblMax)
446 {
447         CFilterGraph_THIS(iface,amstats);
448
449         FIXME("(%p) stub\n",This);
450         return E_NOTIMPL;
451 }
452
453 static HRESULT WINAPI
454 IAMStats_fnGetValueByName(IAMStats* iface,BSTR bstrName,long* plIndex,long* plCount,double* pdblLast,double* pdblAverage,double* pdblStdDev,double* pdblMin,double* pdblMax)
455 {
456         CFilterGraph_THIS(iface,amstats);
457
458         FIXME("(%p) stub\n",This);
459         return E_NOTIMPL;
460 }
461
462 static HRESULT WINAPI
463 IAMStats_fnGetIndex(IAMStats* iface,BSTR bstrName,long lCreate,long* plIndex)
464 {
465         CFilterGraph_THIS(iface,amstats);
466
467         FIXME("(%p) stub\n",This);
468         return E_NOTIMPL;
469 }
470
471 static HRESULT WINAPI
472 IAMStats_fnAddValue(IAMStats* iface,long lIndex,double dValue)
473 {
474         CFilterGraph_THIS(iface,amstats);
475
476         FIXME("(%p) stub\n",This);
477         return E_NOTIMPL;
478 }
479
480
481 static ICOM_VTABLE(IAMStats) iamstats =
482 {
483         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
484         /* IUnknown fields */
485         IAMStats_fnQueryInterface,
486         IAMStats_fnAddRef,
487         IAMStats_fnRelease,
488         /* IDispatch fields */
489         IAMStats_fnGetTypeInfoCount,
490         IAMStats_fnGetTypeInfo,
491         IAMStats_fnGetIDsOfNames,
492         IAMStats_fnInvoke,
493         /* IAMStats fields */
494         IAMStats_fnReset,
495         IAMStats_fnget_Count,
496         IAMStats_fnGetValueByIndex,
497         IAMStats_fnGetValueByName,
498         IAMStats_fnGetIndex,
499         IAMStats_fnAddValue,
500 };
501
502 HRESULT CFilterGraph_InitIAMStats( CFilterGraph* pfg )
503 {
504         TRACE("(%p)\n",pfg);
505         ICOM_VTBL(&pfg->amstats) = &iamstats;
506
507         return NOERROR;
508 }
509
510 void CFilterGraph_UninitIAMStats( CFilterGraph* pfg )
511 {
512         TRACE("(%p)\n",pfg);
513 }
514
515
516