Merged some C sources.
[wine] / dlls / quartz / fgraph.c
1 /*
2  * Implementation of CLSID_FilterGraph.
3  *
4  * hidenori@a2.ctktv.ne.jp
5  */
6
7 #include "config.h"
8
9 #include "windef.h"
10 #include "winbase.h"
11 #include "wingdi.h"
12 #include "winuser.h"
13 #include "winerror.h"
14 #include "wine/obj_base.h"
15 #include "wine/obj_oleaut.h"
16 #include "strmif.h"
17 #include "control.h"
18 #include "uuids.h"
19
20 #include "debugtools.h"
21 DEFAULT_DEBUG_CHANNEL(quartz);
22
23 #include "quartz_private.h"
24 #include "fgraph.h"
25
26 /***************************************************************************
27  *
28  *      new/delete for CFilterGraph
29  *
30  */
31
32 /* can I use offsetof safely? - FIXME? */
33 static QUARTZ_IFEntry IFEntries[] =
34 {
35   { &IID_IPersist, offsetof(CFilterGraph,persist)-offsetof(CFilterGraph,unk) },
36   { &IID_IDispatch, offsetof(CFilterGraph,disp)-offsetof(CFilterGraph,unk) },
37   { &IID_IFilterGraph, offsetof(CFilterGraph,fgraph)-offsetof(CFilterGraph,unk) },
38   { &IID_IGraphBuilder, offsetof(CFilterGraph,fgraph)-offsetof(CFilterGraph,unk) },
39   { &IID_IFilterGraph2, offsetof(CFilterGraph,fgraph)-offsetof(CFilterGraph,unk) },
40   { &IID_IGraphVersion, offsetof(CFilterGraph,graphversion)-offsetof(CFilterGraph,unk) },
41   { &IID_IGraphConfig, offsetof(CFilterGraph,grphconf)-offsetof(CFilterGraph,unk) },
42   { &IID_IMediaControl, offsetof(CFilterGraph,mediacontrol)-offsetof(CFilterGraph,unk) },
43   { &IID_IMediaFilter, offsetof(CFilterGraph,mediafilter)-offsetof(CFilterGraph,unk) },
44   { &IID_IMediaEvent, offsetof(CFilterGraph,mediaevent)-offsetof(CFilterGraph,unk) },
45   { &IID_IMediaEventEx, offsetof(CFilterGraph,mediaevent)-offsetof(CFilterGraph,unk) },
46   { &IID_IMediaEventSink, offsetof(CFilterGraph,mediaeventsink)-offsetof(CFilterGraph,unk) },
47   { &IID_IMediaPosition, offsetof(CFilterGraph,mediaposition)-offsetof(CFilterGraph,unk) },
48   { &IID_IMediaSeeking, offsetof(CFilterGraph,mediaseeking)-offsetof(CFilterGraph,unk) },
49   { &IID_IBasicVideo, offsetof(CFilterGraph,basvid)-offsetof(CFilterGraph,unk) },
50   { &IID_IBasicVideo2, offsetof(CFilterGraph,basvid)-offsetof(CFilterGraph,unk) },
51   { &IID_IBasicAudio, offsetof(CFilterGraph,basaud)-offsetof(CFilterGraph,unk) },
52   { &IID_IVideoWindow, offsetof(CFilterGraph,vidwin)-offsetof(CFilterGraph,unk) },
53 };
54
55
56 struct FGInitEntry
57 {
58         HRESULT (*pInit)(CFilterGraph*);
59         void (*pUninit)(CFilterGraph*);
60 };
61
62 static const struct FGInitEntry FGRAPH_Init[] =
63 {
64         #define FGENT(a)        {&CFilterGraph_Init##a,&CFilterGraph_Uninit##a},
65
66         FGENT(IPersist)
67         FGENT(IDispatch)
68         FGENT(IFilterGraph2)
69         FGENT(IGraphVersion)
70         FGENT(IGraphConfig)
71         FGENT(IMediaControl)
72         FGENT(IMediaFilter)
73         FGENT(IMediaEventEx)
74         FGENT(IMediaEventSink)
75         FGENT(IMediaPosition)
76         FGENT(IMediaSeeking)
77         FGENT(IBasicVideo2)
78         FGENT(IBasicAudio)
79         FGENT(IVideoWindow)
80
81         #undef  FGENT
82         { NULL, NULL },
83 };
84
85
86 static void QUARTZ_DestroyFilterGraph(IUnknown* punk)
87 {
88         CFilterGraph_THIS(punk,unk);
89         int     i;
90
91         TRACE( "(%p)\n", punk );
92
93         /* At first, call Stop. */
94         IMediaControl_Stop( CFilterGraph_IMediaControl(This) );
95         IMediaFilter_Stop( CFilterGraph_IMediaFilter(This) );
96
97         i = 0;
98         while ( FGRAPH_Init[i].pInit != NULL )
99         {
100                 FGRAPH_Init[i].pUninit( This );
101                 i++;
102         }
103
104         TRACE( "succeeded.\n" );
105 }
106
107 HRESULT QUARTZ_CreateFilterGraph(IUnknown* punkOuter,void** ppobj)
108 {
109         CFilterGraph*   pfg;
110         HRESULT hr;
111         int     i;
112
113         TRACE("(%p,%p)\n",punkOuter,ppobj);
114
115         pfg = (CFilterGraph*)QUARTZ_AllocObj( sizeof(CFilterGraph) );
116         if ( pfg == NULL )
117                 return E_OUTOFMEMORY;
118
119         QUARTZ_IUnkInit( &pfg->unk, punkOuter );
120
121         i = 0;
122         hr = NOERROR;
123         while ( FGRAPH_Init[i].pInit != NULL )
124         {
125                 hr = FGRAPH_Init[i].pInit( pfg );
126                 if ( FAILED(hr) )
127                         break;
128                 i++;
129         }
130
131         if ( FAILED(hr) )
132         {
133                 while ( --i >= 0 )
134                         FGRAPH_Init[i].pUninit( pfg );
135                 QUARTZ_FreeObj( pfg );
136                 return hr;
137         }
138
139         pfg->unk.pEntries = IFEntries;
140         pfg->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]);
141         pfg->unk.pOnFinalRelease = QUARTZ_DestroyFilterGraph;
142
143         *ppobj = (void*)(&pfg->unk);
144
145         return S_OK;
146 }
147
148
149 /***************************************************************************
150  *
151  *      CFilterGraph::IPersist
152  *
153  */
154
155 static HRESULT WINAPI
156 IPersist_fnQueryInterface(IPersist* iface,REFIID riid,void** ppobj)
157 {
158         CFilterGraph_THIS(iface,persist);
159
160         TRACE("(%p)->()\n",This);
161
162         return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
163 }
164
165 static ULONG WINAPI
166 IPersist_fnAddRef(IPersist* iface)
167 {
168         CFilterGraph_THIS(iface,persist);
169
170         TRACE("(%p)->()\n",This);
171
172         return IUnknown_AddRef(This->unk.punkControl);
173 }
174
175 static ULONG WINAPI
176 IPersist_fnRelease(IPersist* iface)
177 {
178         CFilterGraph_THIS(iface,persist);
179
180         TRACE("(%p)->()\n",This);
181
182         return IUnknown_Release(This->unk.punkControl);
183 }
184
185
186 static HRESULT WINAPI
187 IPersist_fnGetClassID(IPersist* iface,CLSID* pclsid)
188 {
189         CFilterGraph_THIS(iface,persist);
190
191         TRACE("(%p)->()\n",This);
192
193         if ( pclsid == NULL )
194                 return E_POINTER;
195         memcpy( pclsid, &CLSID_FilterGraph, sizeof(CLSID) );
196
197         return E_NOTIMPL;
198 }
199
200
201 static ICOM_VTABLE(IPersist) ipersist =
202 {
203         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
204         /* IUnknown fields */
205         IPersist_fnQueryInterface,
206         IPersist_fnAddRef,
207         IPersist_fnRelease,
208         /* IPersist fields */
209         IPersist_fnGetClassID,
210 };
211
212 HRESULT CFilterGraph_InitIPersist( CFilterGraph* pfg )
213 {
214         TRACE("(%p)\n",pfg);
215         ICOM_VTBL(&pfg->persist) = &ipersist;
216
217         return NOERROR;
218 }
219
220 void CFilterGraph_UninitIPersist( CFilterGraph* pfg )
221 {
222         TRACE("(%p)\n",pfg);
223 }