3 * Copyright (C) 2003-2004 Rok Mandeljc
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "dmime_private.h"
23 WINE_DEFAULT_DEBUG_CHANNEL(dmime
);
25 struct IDirectMusicGraphImpl
{
26 IDirectMusicGraph IDirectMusicGraph_iface
;
27 struct dmobject dmobj
;
33 static inline IDirectMusicGraphImpl
*impl_from_IDirectMusicGraph(IDirectMusicGraph
*iface
)
35 return CONTAINING_RECORD(iface
, IDirectMusicGraphImpl
, IDirectMusicGraph_iface
);
38 static inline IDirectMusicGraphImpl
*impl_from_IDirectMusicObject(IDirectMusicObject
*iface
)
40 return CONTAINING_RECORD(iface
, IDirectMusicGraphImpl
, dmobj
.IDirectMusicObject_iface
);
43 static inline IDirectMusicGraphImpl
*impl_from_IPersistStream(IPersistStream
*iface
)
45 return CONTAINING_RECORD(iface
, IDirectMusicGraphImpl
, dmobj
.IPersistStream_iface
);
48 static HRESULT WINAPI
DirectMusicGraph_QueryInterface(IDirectMusicGraph
*iface
, REFIID riid
, void **ret_iface
)
50 IDirectMusicGraphImpl
*This
= impl_from_IDirectMusicGraph(iface
);
52 TRACE("(%p, %s, %p)\n", This
, debugstr_guid(riid
), ret_iface
);
56 if (IsEqualIID(riid
, &IID_IUnknown
) ||
57 IsEqualIID(riid
, &IID_IDirectMusicGraph
))
59 *ret_iface
= &This
->IDirectMusicGraph_iface
;
61 else if (IsEqualIID(riid
, &IID_IDirectMusicObject
))
62 *ret_iface
= &This
->dmobj
.IDirectMusicObject_iface
;
63 else if (IsEqualIID(riid
, &IID_IPersistStream
))
64 *ret_iface
= &This
->dmobj
.IPersistStream_iface
;
68 IDirectMusicGraph_AddRef(iface
);
72 WARN("(%p, %s, %p): not found\n", This
, debugstr_guid(riid
), ret_iface
);
76 static ULONG WINAPI
DirectMusicGraph_AddRef(IDirectMusicGraph
*iface
)
78 IDirectMusicGraphImpl
*This
= impl_from_IDirectMusicGraph(iface
);
79 ULONG ref
= InterlockedIncrement(&This
->ref
);
81 TRACE("(%p): %d\n", This
, ref
);
87 static ULONG WINAPI
DirectMusicGraph_Release(IDirectMusicGraph
*iface
)
89 IDirectMusicGraphImpl
*This
= impl_from_IDirectMusicGraph(iface
);
90 ULONG ref
= InterlockedDecrement(&This
->ref
);
92 TRACE("(%p): %d\n", This
, ref
);
95 HeapFree(GetProcessHeap(), 0, This
);
101 static HRESULT WINAPI
DirectMusicGraph_StampPMsg(IDirectMusicGraph
*iface
, DMUS_PMSG
*msg
)
103 IDirectMusicGraphImpl
*This
= impl_from_IDirectMusicGraph(iface
);
104 FIXME("(%p, %p): stub\n", This
, msg
);
108 static HRESULT WINAPI
DirectMusicGraph_InsertTool(IDirectMusicGraph
*iface
, IDirectMusicTool
* pTool
, DWORD
* pdwPChannels
, DWORD cPChannels
, LONG lIndex
)
110 IDirectMusicGraphImpl
*This
= impl_from_IDirectMusicGraph(iface
);
111 struct list
* pEntry
= NULL
;
112 struct list
* pPrevEntry
= NULL
;
113 LPDMUS_PRIVATE_GRAPH_TOOL pIt
= NULL
;
114 LPDMUS_PRIVATE_GRAPH_TOOL pNewTool
= NULL
;
116 FIXME("(%p, %p, %p, %d, %i): use of pdwPChannels\n", This
, pTool
, pdwPChannels
, cPChannels
, lIndex
);
122 lIndex
= This
->num_tools
+ lIndex
;
124 pPrevEntry
= &This
->Tools
;
125 LIST_FOR_EACH(pEntry
, &This
->Tools
)
127 pIt
= LIST_ENTRY(pEntry
, DMUS_PRIVATE_GRAPH_TOOL
, entry
);
128 if (pIt
->dwIndex
== lIndex
)
129 return DMUS_E_ALREADY_EXISTS
;
131 if (pIt
->dwIndex
> lIndex
)
137 pNewTool
= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
, sizeof(DMUS_PRIVATE_GRAPH_TOOL
));
138 pNewTool
->pTool
= pTool
;
139 pNewTool
->dwIndex
= lIndex
;
140 IDirectMusicTool8_AddRef(pTool
);
141 IDirectMusicTool8_Init(pTool
, iface
);
142 list_add_tail (pPrevEntry
->next
, &pNewTool
->entry
);
146 IDirectMusicTool8_GetMediaTypes(pTool
, &dwNum
);
152 static HRESULT WINAPI
DirectMusicGraph_GetTool(IDirectMusicGraph
*iface
, DWORD dwIndex
, IDirectMusicTool
** ppTool
)
154 IDirectMusicGraphImpl
*This
= impl_from_IDirectMusicGraph(iface
);
155 struct list
* pEntry
= NULL
;
156 LPDMUS_PRIVATE_GRAPH_TOOL pIt
= NULL
;
158 FIXME("(%p, %d, %p): stub\n", This
, dwIndex
, ppTool
);
160 LIST_FOR_EACH (pEntry
, &This
->Tools
)
162 pIt
= LIST_ENTRY(pEntry
, DMUS_PRIVATE_GRAPH_TOOL
, entry
);
163 if (pIt
->dwIndex
== dwIndex
)
165 *ppTool
= pIt
->pTool
;
167 IDirectMusicTool_AddRef(*ppTool
);
170 if (pIt
->dwIndex
> dwIndex
)
174 return DMUS_E_NOT_FOUND
;
177 static HRESULT WINAPI
DirectMusicGraph_RemoveTool(IDirectMusicGraph
*iface
, IDirectMusicTool
* pTool
)
179 IDirectMusicGraphImpl
*This
= impl_from_IDirectMusicGraph(iface
);
180 FIXME("(%p, %p): stub\n", This
, pTool
);
184 static const IDirectMusicGraphVtbl DirectMusicGraphVtbl
=
186 DirectMusicGraph_QueryInterface
,
187 DirectMusicGraph_AddRef
,
188 DirectMusicGraph_Release
,
189 DirectMusicGraph_StampPMsg
,
190 DirectMusicGraph_InsertTool
,
191 DirectMusicGraph_GetTool
,
192 DirectMusicGraph_RemoveTool
195 static HRESULT WINAPI
graph_IDirectMusicObject_ParseDescriptor(IDirectMusicObject
*iface
,
196 IStream
*stream
, DMUS_OBJECTDESC
*desc
)
198 struct chunk_entry riff
= {0};
201 TRACE("(%p, %p, %p)\n", iface
, stream
, desc
);
205 if (!desc
|| desc
->dwSize
!= sizeof(*desc
))
208 if ((hr
= stream_get_chunk(stream
, &riff
)) != S_OK
)
210 if (riff
.id
!= FOURCC_RIFF
|| riff
.type
!= DMUS_FOURCC_TOOLGRAPH_FORM
) {
211 TRACE("loading failed: unexpected %s\n", debugstr_chunk(&riff
));
212 stream_skip_chunk(stream
, &riff
);
213 return DMUS_E_CHUNKNOTFOUND
;
216 hr
= dmobj_parsedescriptor(stream
, &riff
, desc
,
217 DMUS_OBJ_OBJECT
|DMUS_OBJ_NAME
|DMUS_OBJ_CATEGORY
|DMUS_OBJ_VERSION
);
221 desc
->guidClass
= CLSID_DirectMusicGraph
;
222 desc
->dwValidData
|= DMUS_OBJ_CLASS
;
224 TRACE("returning descriptor:\n%s\n", debugstr_DMUS_OBJECTDESC (desc
));
228 static const IDirectMusicObjectVtbl dmobject_vtbl
= {
229 dmobj_IDirectMusicObject_QueryInterface
,
230 dmobj_IDirectMusicObject_AddRef
,
231 dmobj_IDirectMusicObject_Release
,
232 dmobj_IDirectMusicObject_GetDescriptor
,
233 dmobj_IDirectMusicObject_SetDescriptor
,
234 graph_IDirectMusicObject_ParseDescriptor
237 static HRESULT WINAPI
graph_IPersistStream_Load(IPersistStream
*iface
, IStream
*stream
)
239 IDirectMusicGraphImpl
*This
= impl_from_IPersistStream(iface
);
241 FIXME("(%p, %p): Loading not implemented yet\n", This
, stream
);
243 return IDirectMusicObject_ParseDescriptor(&This
->dmobj
.IDirectMusicObject_iface
, stream
,
247 static const IPersistStreamVtbl persiststream_vtbl
= {
248 dmobj_IPersistStream_QueryInterface
,
249 dmobj_IPersistStream_AddRef
,
250 dmobj_IPersistStream_Release
,
251 dmobj_IPersistStream_GetClassID
,
252 unimpl_IPersistStream_IsDirty
,
253 graph_IPersistStream_Load
,
254 unimpl_IPersistStream_Save
,
255 unimpl_IPersistStream_GetSizeMax
258 /* for ClassFactory */
259 HRESULT WINAPI
create_dmgraph(REFIID riid
, void **ret_iface
)
261 IDirectMusicGraphImpl
* obj
;
266 obj
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectMusicGraphImpl
));
268 return E_OUTOFMEMORY
;
270 obj
->IDirectMusicGraph_iface
.lpVtbl
= &DirectMusicGraphVtbl
;
272 dmobject_init(&obj
->dmobj
, &CLSID_DirectMusicGraph
, (IUnknown
*)&obj
->IDirectMusicGraph_iface
);
273 obj
->dmobj
.IDirectMusicObject_iface
.lpVtbl
= &dmobject_vtbl
;
274 obj
->dmobj
.IPersistStream_iface
.lpVtbl
= &persiststream_vtbl
;
275 list_init(&obj
->Tools
);
277 hr
= IDirectMusicGraph_QueryInterface(&obj
->IDirectMusicGraph_iface
, riid
, ret_iface
);
278 IDirectMusicGraph_Release(&obj
->IDirectMusicGraph_iface
);