ReactOS 0.4.17-dev-934-g091855f
graph.c
Go to the documentation of this file.
1/* IDirectMusicGraph
2 *
3 * Copyright (C) 2003-2004 Rok Mandeljc
4 *
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.
9 *
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.
14 *
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
18 */
19
20#include "dmime_private.h"
21
23
25{
26 struct list entry;
27 IDirectMusicTool *tool;
29};
30
31struct graph
32{
33 IDirectMusicGraph IDirectMusicGraph_iface;
36
37 struct list tools;
38};
39
40static inline struct graph *impl_from_IDirectMusicGraph(IDirectMusicGraph *iface)
41{
42 return CONTAINING_RECORD(iface, struct graph, IDirectMusicGraph_iface);
43}
44
45static inline struct graph *impl_from_IPersistStream(IPersistStream *iface)
46{
47 return CONTAINING_RECORD(iface, struct graph, dmobj.IPersistStream_iface);
48}
49
50static HRESULT WINAPI graph_QueryInterface(IDirectMusicGraph *iface, REFIID riid, void **ret_iface)
51{
52 struct graph *This = impl_from_IDirectMusicGraph(iface);
53
54 TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ret_iface);
55
56 *ret_iface = NULL;
57
59 IsEqualIID(riid, &IID_IDirectMusicGraph))
60 {
61 *ret_iface = &This->IDirectMusicGraph_iface;
62 }
63 else if (IsEqualIID(riid, &IID_IDirectMusicObject))
64 *ret_iface = &This->dmobj.IDirectMusicObject_iface;
66 *ret_iface = &This->dmobj.IPersistStream_iface;
67
68 if (*ret_iface)
69 {
71 return S_OK;
72 }
73
74 WARN("(%p, %s, %p): not found\n", This, debugstr_guid(riid), ret_iface);
75 return E_NOINTERFACE;
76}
77
78static ULONG WINAPI graph_AddRef(IDirectMusicGraph *iface)
79{
80 struct graph *This = impl_from_IDirectMusicGraph(iface);
82
83 TRACE("(%p): %ld\n", This, ref);
84
85 return ref;
86}
87
88static ULONG WINAPI graph_Release(IDirectMusicGraph *iface)
89{
90 struct graph *This = impl_from_IDirectMusicGraph(iface);
92
93 TRACE("(%p): %ld\n", This, ref);
94
95 if (!ref)
96 {
97 struct tool_entry *entry, *next;
98
100 {
101 list_remove(&entry->entry);
103 free(entry);
104 }
105
106 free(This);
107 }
108
109 return ref;
110}
111
112static HRESULT WINAPI graph_StampPMsg(IDirectMusicGraph *iface, DMUS_PMSG *msg)
113{
115 struct graph *This = impl_from_IDirectMusicGraph(iface);
116 struct tool_entry *entry, *next, *first;
117
118 TRACE("(%p, %p)\n", This, msg);
119
120 if (!msg) return E_POINTER;
121
122 first = LIST_ENTRY(This->tools.next, struct tool_entry, entry);
124 if (entry->tool == msg->pTool) break;
125 if (&entry->entry == &This->tools) next = first;
126
127 if (msg->pTool)
128 {
130 msg->pTool = NULL;
131 }
132
133 if (&next->entry == &This->tools) return DMUS_S_LAST_TOOL;
134
135 if (!msg->pGraph)
136 {
137 msg->pGraph = iface;
139 }
140
141 msg->pTool = next->tool;
143
144 msg->dwFlags &= ~delivery_flags;
145 msg->dwFlags |= next->delivery;
146
147 return S_OK;
148}
149
150static HRESULT WINAPI graph_InsertTool(IDirectMusicGraph *iface, IDirectMusicTool *tool,
151 DWORD *channels, DWORD channel_count, LONG index)
152{
153 struct graph *This = impl_from_IDirectMusicGraph(iface);
154 struct tool_entry *entry, *next;
155 HRESULT hr;
156
157 TRACE("(%p, %p, %p, %ld, %li)\n", This, tool, channels, channel_count, index);
158
159 if (!tool) return E_POINTER;
160
161 LIST_FOR_EACH_ENTRY(next, &This->tools, struct tool_entry, entry)
162 {
163 if (next->tool == tool) return DMUS_E_ALREADY_EXISTS;
164 if (index-- <= 0) break;
165 }
166
167 if (!(entry = calloc(1, sizeof(*entry)))) return E_OUTOFMEMORY;
168 entry->tool = tool;
172 {
173 WARN("Failed to get delivery type from tool %p, hr %#lx\n", tool, hr);
175 }
176 list_add_before(&next->entry, &entry->entry);
177
178 return S_OK;
179}
180
181static HRESULT WINAPI graph_GetTool(IDirectMusicGraph *iface, DWORD index, IDirectMusicTool **ret_tool)
182{
183 struct graph *This = impl_from_IDirectMusicGraph(iface);
184 struct tool_entry *entry;
185
186 TRACE("(%p, %ld, %p)\n", This, index, ret_tool);
187
188 if (!ret_tool) return E_POINTER;
189
191 {
192 if (!index--)
193 {
194 *ret_tool = entry->tool;
196 return S_OK;
197 }
198 }
199
200 return DMUS_E_NOT_FOUND;
201}
202
203static HRESULT WINAPI graph_RemoveTool(IDirectMusicGraph *iface, IDirectMusicTool *tool)
204{
205 struct graph *This = impl_from_IDirectMusicGraph(iface);
206 struct tool_entry *entry;
207
208 TRACE("(%p, %p)\n", This, tool);
209
210 if (!tool) return E_POINTER;
211
213 {
214 if (entry->tool == tool)
215 {
216 list_remove(&entry->entry);
218 free(entry);
219 return S_OK;
220 }
221 }
222
223 return DMUS_E_NOT_FOUND;
224}
225
226static const IDirectMusicGraphVtbl graph_vtbl =
227{
235};
236
239{
240 struct chunk_entry riff = {0};
241 HRESULT hr;
242
243 TRACE("(%p, %p, %p)\n", iface, stream, desc);
244
245 if (!stream)
246 return E_POINTER;
247 if (!desc || desc->dwSize != sizeof(*desc))
248 return E_INVALIDARG;
249
250 if ((hr = stream_get_chunk(stream, &riff)) != S_OK)
251 return hr;
252 if (riff.id != FOURCC_RIFF || riff.type != DMUS_FOURCC_TOOLGRAPH_FORM) {
253 TRACE("loading failed: unexpected %s\n", debugstr_chunk(&riff));
256 }
257
260 if (FAILED(hr))
261 return hr;
262
263 desc->guidClass = CLSID_DirectMusicGraph;
264 desc->dwValidData |= DMUS_OBJ_CLASS;
265
267 return S_OK;
268}
269
270static const IDirectMusicObjectVtbl dmobject_vtbl = {
277};
278
280{
281 struct graph *This = impl_from_IPersistStream(iface);
282
283 FIXME("(%p, %p): Loading not implemented yet\n", This, stream);
284
285 return IDirectMusicObject_ParseDescriptor(&This->dmobj.IDirectMusicObject_iface, stream,
286 &This->dmobj.desc);
287}
288
289static const IPersistStreamVtbl persiststream_vtbl = {
298};
299
300/* for ClassFactory */
302{
303 struct graph *obj;
304 HRESULT hr;
305
306 *ret_iface = NULL;
307 if (!(obj = calloc(1, sizeof(*obj)))) return E_OUTOFMEMORY;
308 obj->IDirectMusicGraph_iface.lpVtbl = &graph_vtbl;
309 obj->ref = 1;
310 dmobject_init(&obj->dmobj, &CLSID_DirectMusicGraph, (IUnknown *)&obj->IDirectMusicGraph_iface);
311 obj->dmobj.IDirectMusicObject_iface.lpVtbl = &dmobject_vtbl;
312 obj->dmobj.IPersistStream_iface.lpVtbl = &persiststream_vtbl;
313 list_init(&obj->tools);
314
315 hr = IDirectMusicGraph_QueryInterface(&obj->IDirectMusicGraph_iface, riid, ret_iface);
316 IDirectMusicGraph_Release(&obj->IDirectMusicGraph_iface);
317
318 return hr;
319}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
unsigned int channels
Definition: audiorecord.c:89
#define msg(x)
Definition: auth_time.c:54
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static void list_init(struct list_entry *head)
Definition: list.h:51
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
const GUID IID_IUnknown
Definition: list.h:39
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define free
Definition: debug_ros.c:5
HRESULT hr
Definition: delayimp.cpp:582
#define NULL
Definition: types.h:112
static HRESULT WINAPI graph_StampPMsg(IDirectMusicGraph *iface, DMUS_PMSG *msg)
Definition: graph.c:112
static ULONG WINAPI graph_Release(IDirectMusicGraph *iface)
Definition: graph.c:88
static HRESULT WINAPI graph_IPersistStream_Load(IPersistStream *iface, IStream *stream)
Definition: graph.c:279
static struct graph * impl_from_IPersistStream(IPersistStream *iface)
Definition: graph.c:45
static const IDirectMusicObjectVtbl dmobject_vtbl
Definition: graph.c:270
static const IDirectMusicGraphVtbl graph_vtbl
Definition: graph.c:226
static const IPersistStreamVtbl persiststream_vtbl
Definition: graph.c:289
static HRESULT WINAPI graph_RemoveTool(IDirectMusicGraph *iface, IDirectMusicTool *tool)
Definition: graph.c:203
static HRESULT WINAPI graph_IDirectMusicObject_ParseDescriptor(IDirectMusicObject *iface, IStream *stream, DMUS_OBJECTDESC *desc)
Definition: graph.c:237
static ULONG WINAPI graph_AddRef(IDirectMusicGraph *iface)
Definition: graph.c:78
static HRESULT WINAPI graph_GetTool(IDirectMusicGraph *iface, DWORD index, IDirectMusicTool **ret_tool)
Definition: graph.c:181
static HRESULT WINAPI graph_InsertTool(IDirectMusicGraph *iface, IDirectMusicTool *tool, DWORD *channels, DWORD channel_count, LONG index)
Definition: graph.c:150
static struct graph * impl_from_IDirectMusicGraph(IDirectMusicGraph *iface)
Definition: graph.c:40
HRESULT create_dmgraph(REFIID riid, void **ret_iface)
Definition: graph.c:301
static HRESULT WINAPI graph_QueryInterface(IDirectMusicGraph *iface, REFIID riid, void **ret_iface)
Definition: graph.c:50
#define DMUS_S_LAST_TOOL
Definition: dmerror.h:46
#define DMUS_E_ALREADY_EXISTS
Definition: dmerror.h:125
#define DMUS_E_NOT_FOUND
Definition: dmerror.h:109
#define DMUS_E_CHUNKNOTFOUND
Definition: dmerror.h:66
HRESULT WINAPI dmobj_IDirectMusicObject_GetDescriptor(IDirectMusicObject *iface, DMUS_OBJECTDESC *desc)
Definition: dmobject.c:503
void dmobject_init(struct dmobject *dmobj, const GUID *class, IUnknown *outer_unk)
Definition: dmobject.c:749
ULONG WINAPI dmobj_IPersistStream_Release(IPersistStream *iface)
Definition: dmobject.c:702
ULONG WINAPI dmobj_IDirectMusicObject_Release(IDirectMusicObject *iface)
Definition: dmobject.c:497
HRESULT dmobj_parsedescriptor(IStream *stream, const struct chunk_entry *riff, DMUS_OBJECTDESC *desc, DWORD supported)
Definition: dmobject.c:591
HRESULT WINAPI dmobj_IDirectMusicObject_QueryInterface(IDirectMusicObject *iface, REFIID riid, void **ret_iface)
Definition: dmobject.c:484
HRESULT WINAPI unimpl_IPersistStream_GetSizeMax(IPersistStream *iface, ULARGE_INTEGER *size)
Definition: dmobject.c:742
HRESULT WINAPI dmobj_IDirectMusicObject_SetDescriptor(IDirectMusicObject *iface, DMUS_OBJECTDESC *desc)
Definition: dmobject.c:518
void dump_DMUS_OBJECTDESC(DMUS_OBJECTDESC *desc)
Definition: dmobject.c:222
const char * debugstr_chunk(const struct chunk_entry *chunk)
Definition: dmobject.c:279
HRESULT WINAPI dmobj_IPersistStream_GetClassID(IPersistStream *iface, CLSID *class)
Definition: dmobject.c:708
ULONG WINAPI dmobj_IPersistStream_AddRef(IPersistStream *iface)
Definition: dmobject.c:696
HRESULT WINAPI dmobj_IPersistStream_QueryInterface(IPersistStream *iface, REFIID riid, void **ret_iface)
Definition: dmobject.c:689
ULONG WINAPI dmobj_IDirectMusicObject_AddRef(IDirectMusicObject *iface)
Definition: dmobject.c:491
HRESULT stream_skip_chunk(IStream *stream, const struct chunk_entry *chunk)
Definition: dmobject.c:351
HRESULT stream_get_chunk(IStream *stream, struct chunk_entry *chunk)
Definition: dmobject.c:307
HRESULT WINAPI unimpl_IPersistStream_IsDirty(IPersistStream *iface)
Definition: dmobject.c:729
HRESULT WINAPI unimpl_IPersistStream_Save(IPersistStream *iface, IStream *stream, BOOL clear_dirty)
Definition: dmobject.c:735
#define IDirectMusicTool_AddRef(p)
Definition: dmplugin.h:147
#define IDirectMusicTool_Release(p)
Definition: dmplugin.h:148
#define IDirectMusicTool_Init(p, a)
Definition: dmplugin.h:150
#define IDirectMusicTool_GetMsgDeliveryType(p, a)
Definition: dmplugin.h:151
#define DMUS_FOURCC_TOOLGRAPH_FORM
Definition: dmusicf.h:138
#define IDirectMusicObject_ParseDescriptor(p, a, b)
Definition: dmusici.h:848
#define IDirectMusicGraph_QueryInterface(p, a, b)
Definition: dmusici.h:1470
#define DMUS_OBJ_NAME
Definition: dmusici.h:267
@ DMUS_PMSGF_TOOL_ATTIME
Definition: dmusici.h:449
@ DMUS_PMSGF_TOOL_IMMEDIATE
Definition: dmusici.h:447
@ DMUS_PMSGF_TOOL_QUEUE
Definition: dmusici.h:448
#define DMUS_OBJ_CLASS
Definition: dmusici.h:266
#define IDirectMusicGraph_Release(p)
Definition: dmusici.h:1472
#define DMUS_OBJ_VERSION
Definition: dmusici.h:272
#define IDirectMusicGraph_AddRef(p)
Definition: dmusici.h:1471
#define DMUS_OBJ_CATEGORY
Definition: dmusici.h:268
#define DMUS_OBJ_OBJECT
Definition: dmusici.h:265
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint index
Definition: glext.h:6031
const GLint * first
Definition: glext.h:5794
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
uint32_t entry
Definition: isohybrid.c:63
#define debugstr_guid
Definition: kernel32.h:35
#define FOURCC_RIFF
Definition: mmsystem.h:564
D3D11_SHADER_VARIABLE_DESC desc
Definition: reflection.c:1683
long LONG
Definition: pedump.c:60
const GUID IID_IPersistStream
Definition: proxy.cpp:13
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
static unsigned __int64 next
Definition: rand_nt.c:6
#define calloc
Definition: rosglue.h:14
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:236
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:242
__WINE_SERVER_LIST_INLINE void list_add_before(struct list *elem, struct list *to_add)
Definition: list.h:89
#define TRACE(s)
Definition: solgame.cpp:4
Definition: dmobject.h:26
FOURCC id
Definition: dmobject.h:27
FOURCC type
Definition: dmobject.h:29
Definition: graph.c:32
struct dmobject dmobj
Definition: graph.c:34
LONG ref
Definition: graph.c:35
IDirectMusicGraph IDirectMusicGraph_iface
Definition: graph.c:33
struct list tools
Definition: graph.c:37
Definition: send.c:48
Definition: parse.h:23
Definition: graph.c:25
DWORD delivery
Definition: graph.c:28
IDirectMusicTool * tool
Definition: graph.c:27
struct list entry
Definition: graph.c:26
#define LIST_ENTRY(type)
Definition: queue.h:175
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define WINAPI
Definition: msvc.h:6
#define E_NOINTERFACE
Definition: winerror.h:3479
#define E_POINTER
Definition: winerror.h:3480