ReactOS 0.4.17-dev-923-g4c9a150
segtriggertrack.c
Go to the documentation of this file.
1/* IDirectMusicSegTriggerTrack Implementation
2 *
3 * Copyright (C) 2003-2004 Rok Mandeljc
4 * Copyright (C) 2003-2004 Raphael Junqueira
5 *
6 * This program 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 program 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 program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include "dmime_private.h"
22
24
25/*****************************************************************************
26 * IDirectMusicSegTriggerTrack implementation
27 */
29 struct list entry;
31 IDirectMusicObject *dmobj;
33};
34
36 IDirectMusicTrack8 IDirectMusicTrack8_iface;
37 struct dmobject dmobj;/* IPersistStream only */
39 struct list Items;
41
42/* IDirectMusicSegTriggerTrack IDirectMusicTrack8 part: */
43static inline IDirectMusicSegTriggerTrack *impl_from_IDirectMusicTrack8(IDirectMusicTrack8 *iface)
44{
45 return CONTAINING_RECORD(iface, IDirectMusicSegTriggerTrack, IDirectMusicTrack8_iface);
46}
47
48static HRESULT WINAPI segment_track_QueryInterface(IDirectMusicTrack8 *iface, REFIID riid,
49 void **ret_iface)
50{
52
53 TRACE("(%p, %s, %p)\n", This, debugstr_dmguid(riid), ret_iface);
54
55 *ret_iface = NULL;
56
57 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDirectMusicTrack) ||
58 IsEqualIID(riid, &IID_IDirectMusicTrack8))
59 *ret_iface = iface;
61 *ret_iface = &This->dmobj.IPersistStream_iface;
62 else {
63 WARN("(%p, %s, %p): not found\n", This, debugstr_dmguid(riid), ret_iface);
64 return E_NOINTERFACE;
65 }
66
67 IUnknown_AddRef((IUnknown*)*ret_iface);
68 return S_OK;
69}
70
71static ULONG WINAPI segment_track_AddRef(IDirectMusicTrack8 *iface)
72{
75
76 TRACE("(%p) ref=%ld\n", This, ref);
77
78 return ref;
79}
80
81static ULONG WINAPI segment_track_Release(IDirectMusicTrack8 *iface)
82{
85
86 TRACE("(%p) ref=%ld\n", This, ref);
87
88 if (!ref) {
89 struct list *cursor, *cursor2;
90 struct segment_item *item;
91
92 LIST_FOR_EACH_SAFE(cursor, cursor2, &This->Items) {
95
96 if (item->dmobj)
98 free(item);
99 }
100
101 free(This);
102 }
103
104 return ref;
105}
106
107static HRESULT WINAPI segment_track_Init(IDirectMusicTrack8 *iface, IDirectMusicSegment *pSegment)
108{
110 FIXME("(%p, %p): stub\n", This, pSegment);
111 return S_OK;
112}
113
114static HRESULT WINAPI segment_track_InitPlay(IDirectMusicTrack8 *iface,
115 IDirectMusicSegmentState *pSegmentState, IDirectMusicPerformance *pPerformance,
116 void **ppStateData, DWORD dwVirtualTrack8ID, DWORD dwFlags)
117{
119 FIXME("(%p, %p, %p, %p, %ld, %ld): stub\n", This, pSegmentState, pPerformance, ppStateData, dwVirtualTrack8ID, dwFlags);
120 return S_OK;
121}
122
123static HRESULT WINAPI segment_track_EndPlay(IDirectMusicTrack8 *iface, void *pStateData)
124{
126 FIXME("(%p, %p): stub\n", This, pStateData);
127 return S_OK;
128}
129
130static HRESULT WINAPI segment_track_Play(IDirectMusicTrack8 *iface, void *pStateData,
131 MUSIC_TIME mtStart, MUSIC_TIME mtEnd, MUSIC_TIME mtOffset, DWORD dwFlags,
132 IDirectMusicPerformance *pPerf, IDirectMusicSegmentState *pSegSt, DWORD dwVirtualID)
133{
135 FIXME("(%p, %p, %ld, %ld, %ld, %ld, %p, %p, %ld): stub\n", This, pStateData, mtStart, mtEnd, mtOffset, dwFlags, pPerf, pSegSt, dwVirtualID);
136 return S_OK;
137}
138
139static HRESULT WINAPI segment_track_GetParam(IDirectMusicTrack8 *iface, REFGUID type,
141{
143
144 TRACE("(%p, %s, %ld, %p, %p): not supported\n", This, debugstr_dmguid(type), time, next, param);
146}
147
148static HRESULT WINAPI segment_track_SetParam(IDirectMusicTrack8 *iface, REFGUID type,
149 MUSIC_TIME time, void *param)
150{
152
153 TRACE("(%p, %s, %ld, %p): not supported\n", This, debugstr_dmguid(type), time, param);
154 return S_OK;
155}
156
157static HRESULT WINAPI segment_track_IsParamSupported(IDirectMusicTrack8 *iface, REFGUID type)
158{
160
161 TRACE("(%p, %s)\n", This, debugstr_dmguid(type));
162 return S_OK;
163}
164
165static HRESULT WINAPI segment_track_AddNotificationType(IDirectMusicTrack8 *iface,
166 REFGUID notiftype)
167{
169
170 TRACE("(%p, %s): method not implemented\n", This, debugstr_dmguid(notiftype));
171 return E_NOTIMPL;
172}
173
174static HRESULT WINAPI segment_track_RemoveNotificationType(IDirectMusicTrack8 *iface,
175 REFGUID notiftype)
176{
178
179 TRACE("(%p, %s): method not implemented\n", This, debugstr_dmguid(notiftype));
180 return E_NOTIMPL;
181}
182
183static HRESULT WINAPI segment_track_Clone(IDirectMusicTrack8 *iface, MUSIC_TIME mtStart,
184 MUSIC_TIME mtEnd, IDirectMusicTrack **ppTrack)
185{
187 FIXME("(%p, %ld, %ld, %p): stub\n", This, mtStart, mtEnd, ppTrack);
188 return S_OK;
189}
190
191static HRESULT WINAPI segment_track_PlayEx(IDirectMusicTrack8 *iface, void *pStateData,
192 REFERENCE_TIME rtStart, REFERENCE_TIME rtEnd, REFERENCE_TIME rtOffset, DWORD dwFlags,
193 IDirectMusicPerformance *pPerf, IDirectMusicSegmentState *pSegSt, DWORD dwVirtualID)
194{
196 FIXME("(%p, %p, 0x%s, 0x%s, 0x%s, %ld, %p, %p, %ld): stub\n", This, pStateData, wine_dbgstr_longlong(rtStart),
197 wine_dbgstr_longlong(rtEnd), wine_dbgstr_longlong(rtOffset), dwFlags, pPerf, pSegSt, dwVirtualID);
198 return S_OK;
199}
200
201static HRESULT WINAPI segment_track_GetParamEx(IDirectMusicTrack8 *iface, REFGUID rguidType,
202 REFERENCE_TIME rtTime, REFERENCE_TIME *prtNext, void *pParam, void *pStateData,
204{
206 FIXME("(%p, %s, 0x%s, %p, %p, %p, %ld): stub\n", This, debugstr_dmguid(rguidType),
207 wine_dbgstr_longlong(rtTime), prtNext, pParam, pStateData, dwFlags);
208 return S_OK;
209}
210
211static HRESULT WINAPI segment_track_SetParamEx(IDirectMusicTrack8 *iface, REFGUID rguidType,
212 REFERENCE_TIME rtTime, void *pParam, void *pStateData, DWORD dwFlags)
213{
215 FIXME("(%p, %s, 0x%s, %p, %p, %ld): stub\n", This, debugstr_dmguid(rguidType),
216 wine_dbgstr_longlong(rtTime), pParam, pStateData, dwFlags);
217 return S_OK;
218}
219
220static HRESULT WINAPI segment_track_Compose(IDirectMusicTrack8 *iface, IUnknown *context,
221 DWORD trackgroup, IDirectMusicTrack **track)
222{
224
225 TRACE("(%p, %p, %ld, %p): method not implemented\n", This, context, trackgroup, track);
226 return E_NOTIMPL;
227}
228
229static HRESULT WINAPI segment_track_Join(IDirectMusicTrack8 *iface, IDirectMusicTrack *newtrack,
230 MUSIC_TIME join, IUnknown *context, DWORD trackgroup, IDirectMusicTrack **resulttrack)
231{
233 TRACE("(%p, %p, %ld, %p, %ld, %p): method not implemented\n", This, newtrack, join, context,
234 trackgroup, resulttrack);
235 return E_NOTIMPL;
236}
237
238static const IDirectMusicTrack8Vtbl dmtrack8_vtbl = {
257};
258
260{
261 return CONTAINING_RECORD(iface, IDirectMusicSegTriggerTrack, dmobj.IPersistStream_iface);
262}
263
265 const struct chunk_entry *lseg)
266{
267 struct chunk_entry chunk = {.parent = lseg};
268 struct segment_item *item;
269 HRESULT hr;
270
271 /* First chunk is a header */
274 if (!(item = calloc(1, sizeof(*item)))) return E_OUTOFMEMORY;
276 if (FAILED(hr))
277 goto error;
278
279 TRACE("Found DMUS_IO_SEGMENT_ITEM_HEADER\n");
280 TRACE("\tlTimePhysical: %lu\n", item->header.lTimeLogical);
281 TRACE("\tlTimePhysical: %lu\n", item->header.lTimePhysical);
282 TRACE("\tdwPlayFlags: %#08lx\n", item->header.dwPlayFlags);
283 TRACE("\tdwFlags: %#08lx\n", item->header.dwFlags);
284
285 /* Second chunk is a reference list */
286 if (stream_next_chunk(stream, &chunk) != S_OK || chunk.id != FOURCC_LIST ||
287 chunk.type != DMUS_FOURCC_REF_LIST) {
289 goto error;
290 }
291 if (FAILED(hr = dmobj_parsereference(stream, &chunk, &item->dmobj)))
292 goto error;
293
294 /* Optional third chunk if the reference is a motif */
295 if (item->header.dwFlags & DMUS_SEGMENTTRACKF_MOTIF) {
297 goto error;
300 goto error;
301
302 TRACE("Found motif name: %s\n", debugstr_w(item->name));
303 }
304
305 list_add_tail(&This->Items, &item->entry);
306
307 return S_OK;
308
309error:
310 free(item);
311 return hr;
312}
313
315 const struct chunk_entry *lsgl)
316{
317 struct chunk_entry chunk = {.parent = lsgl};
318 HRESULT hr;
319
320 TRACE("Parsing segment list in %p: %s\n", stream, debugstr_chunk(lsgl));
321
322 while ((hr = stream_next_chunk(stream, &chunk)) == S_OK)
323 if (chunk.id == FOURCC_LIST && chunk.type == DMUS_FOURCC_SEGMENT_LIST)
325 break;
326
327 return SUCCEEDED(hr) ? S_OK : hr;
328}
329
331{
333 struct chunk_entry segt = {0};
334 struct chunk_entry chunk = {.parent = &segt};
336 HRESULT hr;
337
338 TRACE("(%p, %p): Loading\n", This, stream);
339
340 if (!stream)
341 return E_POINTER;
342
343 if (stream_get_chunk(stream, &segt) != S_OK || segt.id != FOURCC_LIST ||
346
347 if ((hr = stream_get_chunk(stream, &chunk)) != S_OK)
349
350 /* Optional and useless header chunk */
353 if (FAILED(hr))
354 return hr;
355 if (header.dwFlags)
356 WARN("Got flags %#lx; must be zero\n", header.dwFlags);
357
358 if ((hr = stream_get_chunk(stream, &chunk)) != S_OK)
360 }
361
364
366}
367
368static const IPersistStreamVtbl persiststream_vtbl = {
377};
378
379/* for ClassFactory */
381{
383 HRESULT hr;
384
385 *ppobj = NULL;
386 if (!(track = calloc(1, sizeof(*track)))) return E_OUTOFMEMORY;
388 track->ref = 1;
389 dmobject_init(&track->dmobj, &CLSID_DirectMusicSegTriggerTrack,
391 track->dmobj.IPersistStream_iface.lpVtbl = &persiststream_vtbl;
392 list_init(&track->Items);
393
396
397 return hr;
398}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#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_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
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_NOTIMPL
Definition: ddrawi.h:99
#define free
Definition: debug_ros.c:5
HRESULT hr
Definition: delayimp.cpp:582
#define NULL
Definition: types.h:112
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
#define DMUS_E_GET_UNSUPPORTED
Definition: dmerror.h:72
#define DMUS_E_TRACK_HDR_NOT_FIRST_CK
Definition: dmerror.h:103
#define DMUS_E_INVALID_SEGMENTTRIGGERTRACK
Definition: dmerror.h:146
void dmobject_init(struct dmobject *dmobj, const GUID *class, IUnknown *outer_unk)
Definition: dmobject.c:749
HRESULT stream_chunk_get_data(IStream *stream, const struct chunk_entry *chunk, void *data, ULONG size)
Definition: dmobject.c:417
HRESULT stream_next_chunk(IStream *stream, struct chunk_entry *chunk)
Definition: dmobject.c:360
ULONG WINAPI dmobj_IPersistStream_Release(IPersistStream *iface)
Definition: dmobject.c:702
HRESULT WINAPI unimpl_IPersistStream_GetSizeMax(IPersistStream *iface, ULARGE_INTEGER *size)
Definition: dmobject.c:742
HRESULT stream_chunk_get_wstr(IStream *stream, const struct chunk_entry *chunk, WCHAR *str, ULONG size)
Definition: dmobject.c:429
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
const char * debugstr_dmguid(const GUID *id)
Definition: dmobject.c:36
HRESULT dmobj_parsereference(IStream *stream, const struct chunk_entry *list, IDirectMusicObject **dmobj)
Definition: dmobject.c:654
HRESULT WINAPI dmobj_IPersistStream_QueryInterface(IPersistStream *iface, REFIID riid, void **ret_iface)
Definition: dmobject.c:689
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 IDirectMusicTrack8_Release(p)
Definition: dmplugin.h:275
LONG MUSIC_TIME
Definition: dmplugin.h:95
#define IDirectMusicTrack8_QueryInterface(p, a, b)
Definition: dmplugin.h:273
#define DMUS_FOURCC_SEGTRACK_LIST
Definition: dmusicf.h:189
#define DMUS_FOURCC_SEGMENTITEMNAME_CHUNK
Definition: dmusicf.h:194
#define DMUS_FOURCC_SEGTRACK_CHUNK
Definition: dmusicf.h:190
#define DMUS_SEGMENTTRACKF_MOTIF
Definition: dmusicf.h:273
#define DMUS_FOURCC_REF_LIST
Definition: dmusicf.h:102
#define DMUS_FOURCC_SEGMENTS_LIST
Definition: dmusicf.h:191
#define DMUS_FOURCC_SEGMENT_LIST
Definition: dmusicf.h:192
#define DMUS_FOURCC_SEGMENTITEM_CHUNK
Definition: dmusicf.h:193
#define IDirectMusicObject_Release(p)
Definition: dmusici.h:844
#define DMUS_MAX_NAME
Definition: dmusici.h:245
LONGLONG REFERENCE_TIME
Definition: dmusicks.h:9
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLfloat param
Definition: glext.h:5796
const char cursor[]
Definition: icontest.c:13
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
uint32_t entry
Definition: isohybrid.c:63
#define debugstr_w
Definition: kernel32.h:32
__u16 time
Definition: mkdosfs.c:8
#define error(str)
Definition: mkdosfs.c:1605
LOCAL int join(int *aux, int a, int b)
Definition: match.c:560
#define FOURCC_LIST
Definition: mmsystem.h:565
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
short WCHAR
Definition: pedump.c:58
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_SAFE(cursor, cursor2, list)
Definition: list.h:230
static IDirectMusicSegTriggerTrack * impl_from_IDirectMusicTrack8(IDirectMusicTrack8 *iface)
static HRESULT WINAPI segment_track_IsParamSupported(IDirectMusicTrack8 *iface, REFGUID type)
static HRESULT parse_segment_item(IDirectMusicSegTriggerTrack *This, IStream *stream, const struct chunk_entry *lseg)
static HRESULT parse_segments_list(IDirectMusicSegTriggerTrack *This, IStream *stream, const struct chunk_entry *lsgl)
static HRESULT WINAPI segment_track_Play(IDirectMusicTrack8 *iface, void *pStateData, MUSIC_TIME mtStart, MUSIC_TIME mtEnd, MUSIC_TIME mtOffset, DWORD dwFlags, IDirectMusicPerformance *pPerf, IDirectMusicSegmentState *pSegSt, DWORD dwVirtualID)
static ULONG WINAPI segment_track_AddRef(IDirectMusicTrack8 *iface)
static HRESULT WINAPI segment_track_RemoveNotificationType(IDirectMusicTrack8 *iface, REFGUID notiftype)
static HRESULT WINAPI segment_track_SetParam(IDirectMusicTrack8 *iface, REFGUID type, MUSIC_TIME time, void *param)
static HRESULT WINAPI segment_track_InitPlay(IDirectMusicTrack8 *iface, IDirectMusicSegmentState *pSegmentState, IDirectMusicPerformance *pPerformance, void **ppStateData, DWORD dwVirtualTrack8ID, DWORD dwFlags)
static IDirectMusicSegTriggerTrack * impl_from_IPersistStream(IPersistStream *iface)
static HRESULT WINAPI segment_track_AddNotificationType(IDirectMusicTrack8 *iface, REFGUID notiftype)
static HRESULT WINAPI segment_track_EndPlay(IDirectMusicTrack8 *iface, void *pStateData)
static HRESULT WINAPI segment_track_PlayEx(IDirectMusicTrack8 *iface, void *pStateData, REFERENCE_TIME rtStart, REFERENCE_TIME rtEnd, REFERENCE_TIME rtOffset, DWORD dwFlags, IDirectMusicPerformance *pPerf, IDirectMusicSegmentState *pSegSt, DWORD dwVirtualID)
static HRESULT WINAPI segment_track_Compose(IDirectMusicTrack8 *iface, IUnknown *context, DWORD trackgroup, IDirectMusicTrack **track)
static HRESULT WINAPI segment_track_Init(IDirectMusicTrack8 *iface, IDirectMusicSegment *pSegment)
static HRESULT WINAPI segment_track_SetParamEx(IDirectMusicTrack8 *iface, REFGUID rguidType, REFERENCE_TIME rtTime, void *pParam, void *pStateData, DWORD dwFlags)
static const IPersistStreamVtbl persiststream_vtbl
static HRESULT WINAPI segment_track_GetParamEx(IDirectMusicTrack8 *iface, REFGUID rguidType, REFERENCE_TIME rtTime, REFERENCE_TIME *prtNext, void *pParam, void *pStateData, DWORD dwFlags)
static const IDirectMusicTrack8Vtbl dmtrack8_vtbl
static ULONG WINAPI segment_track_Release(IDirectMusicTrack8 *iface)
static HRESULT WINAPI trigger_IPersistStream_Load(IPersistStream *iface, IStream *stream)
static HRESULT WINAPI segment_track_Clone(IDirectMusicTrack8 *iface, MUSIC_TIME mtStart, MUSIC_TIME mtEnd, IDirectMusicTrack **ppTrack)
static HRESULT WINAPI segment_track_QueryInterface(IDirectMusicTrack8 *iface, REFIID riid, void **ret_iface)
HRESULT create_dmsegtriggertrack(REFIID lpcGUID, void **ppobj)
static HRESULT WINAPI segment_track_Join(IDirectMusicTrack8 *iface, IDirectMusicTrack *newtrack, MUSIC_TIME join, IUnknown *context, DWORD trackgroup, IDirectMusicTrack **resulttrack)
static HRESULT WINAPI segment_track_GetParam(IDirectMusicTrack8 *iface, REFGUID type, MUSIC_TIME time, MUSIC_TIME *next, void *param)
#define TRACE(s)
Definition: solgame.cpp:4
IDirectMusicTrack8 IDirectMusicTrack8_iface
Definition: scsiwmi.h:51
Definition: dmobject.h:26
FOURCC id
Definition: dmobject.h:27
FOURCC type
Definition: dmobject.h:29
Definition: http.c:7252
Definition: name.c:39
Definition: send.c:48
DMUS_IO_SEGMENT_ITEM_HEADER header
struct list entry
IDirectMusicObject * dmobj
Definition: parse.h:23
#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