xmllite/writer: Implement WriteNodeShallow().
[wine.git] / dlls / dmime / tempotrack.c
blob0e8d5bcab48d37df4c003315c8b24f754695d582
1 /* IDirectMusicTempoTrack Implementation
3 * Copyright (C) 2003-2004 Rok Mandeljc
4 * Copyright (C) 2004 Raphael Junqueira
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.
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.
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
21 #include "dmime_private.h"
22 #include "dmobject.h"
24 #include "wine/heap.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(dmime);
27 WINE_DECLARE_DEBUG_CHANNEL(dmfile);
29 /*****************************************************************************
30 * IDirectMusicTempoTrack implementation
33 typedef struct IDirectMusicTempoTrack {
34 IDirectMusicTrack8 IDirectMusicTrack8_iface;
35 struct dmobject dmobj; /* IPersistStream only */
36 LONG ref;
37 DMUS_IO_TEMPO_ITEM *items;
38 unsigned int count;
39 } IDirectMusicTempoTrack;
41 /* IDirectMusicTempoTrack IDirectMusicTrack8 part: */
42 static inline IDirectMusicTempoTrack *impl_from_IDirectMusicTrack8(IDirectMusicTrack8 *iface)
44 return CONTAINING_RECORD(iface, IDirectMusicTempoTrack, IDirectMusicTrack8_iface);
47 static HRESULT WINAPI tempo_track_QueryInterface(IDirectMusicTrack8 *iface, REFIID riid,
48 void **ret_iface)
50 IDirectMusicTempoTrack *This = impl_from_IDirectMusicTrack8(iface);
52 TRACE("(%p, %s, %p)\n", This, debugstr_dmguid(riid), ret_iface);
54 *ret_iface = NULL;
56 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDirectMusicTrack) ||
57 IsEqualIID(riid, &IID_IDirectMusicTrack8))
58 *ret_iface = iface;
59 else if (IsEqualIID(riid, &IID_IPersistStream))
60 *ret_iface = &This->dmobj.IPersistStream_iface;
61 else {
62 WARN("(%p, %s, %p): not found\n", This, debugstr_dmguid(riid), ret_iface);
63 return E_NOINTERFACE;
66 IUnknown_AddRef((IUnknown*)*ret_iface);
67 return S_OK;
70 static ULONG WINAPI tempo_track_AddRef(IDirectMusicTrack8 *iface)
72 IDirectMusicTempoTrack *This = impl_from_IDirectMusicTrack8(iface);
73 LONG ref = InterlockedIncrement(&This->ref);
75 TRACE("(%p) ref=%ld\n", This, ref);
77 return ref;
80 static ULONG WINAPI tempo_track_Release(IDirectMusicTrack8 *iface)
82 IDirectMusicTempoTrack *This = impl_from_IDirectMusicTrack8(iface);
83 LONG ref = InterlockedDecrement(&This->ref);
85 TRACE("(%p) ref=%ld\n", This, ref);
87 if (!ref) {
88 heap_free(This->items);
89 heap_free(This);
90 DMIME_UnlockModule();
93 return ref;
96 static HRESULT WINAPI tempo_track_Init(IDirectMusicTrack8 *iface, IDirectMusicSegment *pSegment)
98 IDirectMusicTempoTrack *This = impl_from_IDirectMusicTrack8(iface);
99 TRACE("(%p, %p): nothing to do here\n", This, pSegment);
100 return S_OK;
103 static HRESULT WINAPI tempo_track_InitPlay(IDirectMusicTrack8 *iface,
104 IDirectMusicSegmentState *pSegmentState, IDirectMusicPerformance *pPerformance,
105 void **ppStateData, DWORD dwVirtualTrack8ID, DWORD dwFlags)
107 IDirectMusicTempoTrack *This = impl_from_IDirectMusicTrack8(iface);
109 LPDMUS_PRIVATE_TEMPO_PLAY_STATE pState = NULL;
111 FIXME("(%p, %p, %p, %p, %ld, %ld): semi-stub\n", This, pSegmentState, pPerformance, ppStateData, dwVirtualTrack8ID, dwFlags);
113 pState = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DMUS_PRIVATE_TEMPO_PLAY_STATE));
114 if (NULL == pState)
115 return E_OUTOFMEMORY;
117 /** TODO real fill useful data */
118 pState->dummy = 0;
119 *ppStateData = pState;
120 return S_OK;
123 static HRESULT WINAPI tempo_track_EndPlay(IDirectMusicTrack8 *iface, void *pStateData)
125 IDirectMusicTempoTrack *This = impl_from_IDirectMusicTrack8(iface);
127 LPDMUS_PRIVATE_TEMPO_PLAY_STATE pState = pStateData;
129 FIXME("(%p, %p): semi-stub\n", This, pStateData);
131 if (NULL == pStateData) {
132 return E_POINTER;
134 /** TODO real clean up */
135 HeapFree(GetProcessHeap(), 0, pState);
136 return S_OK;
139 static HRESULT WINAPI tempo_track_Play(IDirectMusicTrack8 *iface, void *pStateData,
140 MUSIC_TIME mtStart, MUSIC_TIME mtEnd, MUSIC_TIME mtOffset, DWORD dwFlags,
141 IDirectMusicPerformance *pPerf, IDirectMusicSegmentState *pSegSt, DWORD dwVirtualID)
143 IDirectMusicTempoTrack *This = impl_from_IDirectMusicTrack8(iface);
144 FIXME("(%p, %p, %ld, %ld, %ld, %ld, %p, %p, %ld): stub\n", This, pStateData, mtStart, mtEnd, mtOffset, dwFlags, pPerf, pSegSt, dwVirtualID);
145 /** should use IDirectMusicPerformance_SendPMsg here */
146 return S_OK;
149 static HRESULT WINAPI tempo_track_GetParam(IDirectMusicTrack8 *iface, REFGUID type, MUSIC_TIME time,
150 MUSIC_TIME *next, void *param)
152 IDirectMusicTempoTrack *This = impl_from_IDirectMusicTrack8(iface);
153 DMUS_TEMPO_PARAM *prm = param;
154 unsigned int i;
156 TRACE("(%p, %s, %ld, %p, %p)\n", This, debugstr_dmguid(type), time, next, param);
158 if (!param)
159 return E_POINTER;
160 if (!IsEqualGUID(type, &GUID_TempoParam))
161 return DMUS_E_GET_UNSUPPORTED;
163 FIXME("Partial support for GUID_TempoParam\n");
165 if (next)
166 *next = 0;
167 prm->mtTime = 0;
168 prm->dblTempo = 0.123456;
170 for (i = 0; i < This->count; i++) {
171 if (This->items[i].lTime <= time) {
172 MUSIC_TIME ofs = This->items[i].lTime - time;
173 if (ofs > prm->mtTime) {
174 prm->mtTime = ofs;
175 prm->dblTempo = This->items[i].dblTempo;
177 if (next && This->items[i].lTime > time && This->items[i].lTime < *next)
178 *next = This->items[i].lTime;
182 if (0.123456 == prm->dblTempo)
183 return DMUS_E_NOT_FOUND;
185 return S_OK;
188 static HRESULT WINAPI tempo_track_SetParam(IDirectMusicTrack8 *iface, REFGUID type, MUSIC_TIME time,
189 void *param)
191 IDirectMusicTempoTrack *This = impl_from_IDirectMusicTrack8(iface);
193 TRACE("(%p, %s, %ld, %p)\n", This, debugstr_dmguid(type), time, param);
195 if (IsEqualGUID(type, &GUID_DisableTempo)) {
196 if (!param)
197 return DMUS_E_TYPE_DISABLED;
198 FIXME("GUID_DisableTempo not handled yet\n");
199 return S_OK;
201 if (IsEqualGUID(type, &GUID_EnableTempo)) {
202 if (!param)
203 return DMUS_E_TYPE_DISABLED;
204 FIXME("GUID_EnableTempo not handled yet\n");
205 return S_OK;
207 if (IsEqualGUID(type, &GUID_TempoParam)) {
208 if (!param)
209 return E_POINTER;
210 FIXME("GUID_TempoParam not handled yet\n");
211 return S_OK;
214 return DMUS_E_SET_UNSUPPORTED;
217 static HRESULT WINAPI tempo_track_IsParamSupported(IDirectMusicTrack8 *iface, REFGUID rguidType)
219 IDirectMusicTempoTrack *This = impl_from_IDirectMusicTrack8(iface);
221 TRACE("(%p, %s)\n", This, debugstr_dmguid(rguidType));
222 if (IsEqualGUID (rguidType, &GUID_DisableTempo)
223 || IsEqualGUID (rguidType, &GUID_EnableTempo)
224 || IsEqualGUID (rguidType, &GUID_TempoParam)) {
225 TRACE("param supported\n");
226 return S_OK;
228 TRACE("param unsupported\n");
229 return DMUS_E_TYPE_UNSUPPORTED;
232 static HRESULT WINAPI tempo_track_AddNotificationType(IDirectMusicTrack8 *iface, REFGUID notiftype)
234 IDirectMusicTempoTrack *This = impl_from_IDirectMusicTrack8(iface);
236 TRACE("(%p, %s): method not implemented\n", This, debugstr_dmguid(notiftype));
237 return E_NOTIMPL;
240 static HRESULT WINAPI tempo_track_RemoveNotificationType(IDirectMusicTrack8 *iface,
241 REFGUID notiftype)
243 IDirectMusicTempoTrack *This = impl_from_IDirectMusicTrack8(iface);
245 TRACE("(%p, %s): method not implemented\n", This, debugstr_dmguid(notiftype));
246 return E_NOTIMPL;
249 static HRESULT WINAPI tempo_track_Clone(IDirectMusicTrack8 *iface, MUSIC_TIME mtStart,
250 MUSIC_TIME mtEnd, IDirectMusicTrack **ppTrack)
252 IDirectMusicTempoTrack *This = impl_from_IDirectMusicTrack8(iface);
253 FIXME("(%p, %ld, %ld, %p): stub\n", This, mtStart, mtEnd, ppTrack);
254 return S_OK;
257 static HRESULT WINAPI tempo_track_PlayEx(IDirectMusicTrack8 *iface, void *pStateData,
258 REFERENCE_TIME rtStart, REFERENCE_TIME rtEnd, REFERENCE_TIME rtOffset, DWORD dwFlags,
259 IDirectMusicPerformance *pPerf, IDirectMusicSegmentState *pSegSt, DWORD dwVirtualID)
261 IDirectMusicTempoTrack *This = impl_from_IDirectMusicTrack8(iface);
262 FIXME("(%p, %p, 0x%s, 0x%s, 0x%s, %ld, %p, %p, %ld): stub\n", This, pStateData, wine_dbgstr_longlong(rtStart),
263 wine_dbgstr_longlong(rtEnd), wine_dbgstr_longlong(rtOffset), dwFlags, pPerf, pSegSt, dwVirtualID);
264 return S_OK;
267 static HRESULT WINAPI tempo_track_GetParamEx(IDirectMusicTrack8 *iface, REFGUID rguidType,
268 REFERENCE_TIME rtTime, REFERENCE_TIME *prtNext, void *pParam, void *pStateData,
269 DWORD dwFlags)
271 IDirectMusicTempoTrack *This = impl_from_IDirectMusicTrack8(iface);
272 FIXME("(%p, %s, 0x%s, %p, %p, %p, %ld): stub\n", This, debugstr_dmguid(rguidType),
273 wine_dbgstr_longlong(rtTime), prtNext, pParam, pStateData, dwFlags);
274 return S_OK;
277 static HRESULT WINAPI tempo_track_SetParamEx(IDirectMusicTrack8 *iface, REFGUID rguidType,
278 REFERENCE_TIME rtTime, void *pParam, void *pStateData, DWORD dwFlags)
280 IDirectMusicTempoTrack *This = impl_from_IDirectMusicTrack8(iface);
281 FIXME("(%p, %s, 0x%s, %p, %p, %ld): stub\n", This, debugstr_dmguid(rguidType),
282 wine_dbgstr_longlong(rtTime), pParam, pStateData, dwFlags);
283 return S_OK;
286 static HRESULT WINAPI tempo_track_Compose(IDirectMusicTrack8 *iface, IUnknown *context,
287 DWORD trackgroup, IDirectMusicTrack **track)
289 IDirectMusicTempoTrack *This = impl_from_IDirectMusicTrack8(iface);
291 TRACE("(%p, %p, %ld, %p): method not implemented\n", This, context, trackgroup, track);
292 return E_NOTIMPL;
295 static HRESULT WINAPI tempo_track_Join(IDirectMusicTrack8 *iface, IDirectMusicTrack *pNewTrack,
296 MUSIC_TIME mtJoin, IUnknown *pContext, DWORD dwTrackGroup,
297 IDirectMusicTrack **ppResultTrack)
299 IDirectMusicTempoTrack *This = impl_from_IDirectMusicTrack8(iface);
300 FIXME("(%p, %p, %ld, %p, %ld, %p): stub\n", This, pNewTrack, mtJoin, pContext, dwTrackGroup, ppResultTrack);
301 return S_OK;
304 static const IDirectMusicTrack8Vtbl dmtrack8_vtbl = {
305 tempo_track_QueryInterface,
306 tempo_track_AddRef,
307 tempo_track_Release,
308 tempo_track_Init,
309 tempo_track_InitPlay,
310 tempo_track_EndPlay,
311 tempo_track_Play,
312 tempo_track_GetParam,
313 tempo_track_SetParam,
314 tempo_track_IsParamSupported,
315 tempo_track_AddNotificationType,
316 tempo_track_RemoveNotificationType,
317 tempo_track_Clone,
318 tempo_track_PlayEx,
319 tempo_track_GetParamEx,
320 tempo_track_SetParamEx,
321 tempo_track_Compose,
322 tempo_track_Join
325 static inline IDirectMusicTempoTrack *impl_from_IPersistStream(IPersistStream *iface)
327 return CONTAINING_RECORD(iface, IDirectMusicTempoTrack, dmobj.IPersistStream_iface);
330 static HRESULT WINAPI tempo_IPersistStream_Load(IPersistStream *iface, IStream *stream)
332 IDirectMusicTempoTrack *This = impl_from_IPersistStream(iface);
333 struct chunk_entry chunk = {0};
334 unsigned int i;
335 HRESULT hr;
337 TRACE("%p, %p\n", This, stream);
339 if (!stream)
340 return E_POINTER;
342 if ((hr = stream_get_chunk(stream, &chunk)) != S_OK)
343 return hr;
344 if (chunk.id != DMUS_FOURCC_TEMPO_TRACK)
345 return DMUS_E_UNSUPPORTED_STREAM;
347 hr = stream_chunk_get_array(stream, &chunk, (void **)&This->items, &This->count,
348 sizeof(DMUS_IO_TEMPO_ITEM));
349 if (FAILED(hr))
350 return hr;
352 for (i = 0; i < This->count; i++) {
353 TRACE_(dmfile)("DMUS_IO_TEMPO_ITEM #%u\n", i);
354 TRACE_(dmfile)(" - lTime = %lu\n", This->items[i].lTime);
355 TRACE_(dmfile)(" - dblTempo = %g\n", This->items[i].dblTempo);
358 return S_OK;
361 static const IPersistStreamVtbl persiststream_vtbl = {
362 dmobj_IPersistStream_QueryInterface,
363 dmobj_IPersistStream_AddRef,
364 dmobj_IPersistStream_Release,
365 dmobj_IPersistStream_GetClassID,
366 unimpl_IPersistStream_IsDirty,
367 tempo_IPersistStream_Load,
368 unimpl_IPersistStream_Save,
369 unimpl_IPersistStream_GetSizeMax
372 /* for ClassFactory */
373 HRESULT WINAPI create_dmtempotrack(REFIID lpcGUID, void **ppobj)
375 IDirectMusicTempoTrack *track;
376 HRESULT hr;
378 track = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*track));
379 if (!track) {
380 *ppobj = NULL;
381 return E_OUTOFMEMORY;
383 track->IDirectMusicTrack8_iface.lpVtbl = &dmtrack8_vtbl;
384 track->ref = 1;
385 dmobject_init(&track->dmobj, &CLSID_DirectMusicTempoTrack,
386 (IUnknown *)&track->IDirectMusicTrack8_iface);
387 track->dmobj.IPersistStream_iface.lpVtbl = &persiststream_vtbl;
389 DMIME_LockModule();
390 hr = IDirectMusicTrack8_QueryInterface(&track->IDirectMusicTrack8_iface, lpcGUID, ppobj);
391 IDirectMusicTrack8_Release(&track->IDirectMusicTrack8_iface);
393 return hr;