]> git.saurik.com Git - wxWidgets.git/blame - src/msw/mediactrl.cpp
Build fix.
[wxWidgets.git] / src / msw / mediactrl.cpp
CommitLineData
1a680109
RN
1/////////////////////////////////////////////////////////////////////////////
2// Name: msw/mediactrl.cpp
ff4aedc5 3// Purpose: Built-in Media Backends for Windows
1a680109 4// Author: Ryan Norton <wxprojects@comcast.net>
72259e00 5// Modified by:
1a680109
RN
6// Created: 11/07/04
7// RCS-ID: $Id$
8// Copyright: (c) Ryan Norton
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
ff4aedc5
RN
12//===========================================================================
13// DECLARATIONS
14//===========================================================================
15
1a680109 16//---------------------------------------------------------------------------
ff4aedc5 17// Pre-compiled header stuff
1a680109
RN
18//---------------------------------------------------------------------------
19
ff4aedc5
RN
20#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
21#pragma implementation "mediactrl.h"
22#endif
1a680109
RN
23
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
28#pragma hdrstop
29#endif
30
ff4aedc5
RN
31//---------------------------------------------------------------------------
32// Includes
33//---------------------------------------------------------------------------
1a680109
RN
34#include "wx/mediactrl.h"
35
ff4aedc5
RN
36//---------------------------------------------------------------------------
37// Compilation guard
38//---------------------------------------------------------------------------
1a680109
RN
39#if wxUSE_MEDIACTRL
40
1a680109 41//---------------------------------------------------------------------------
ff4aedc5 42// Externals (somewhere in src/msw/app.cpp)
1a680109 43//---------------------------------------------------------------------------
ff4aedc5
RN
44extern "C" WXDLLIMPEXP_BASE HINSTANCE wxGetInstance(void);
45#ifdef __WXWINCE__
7a4d2469 46extern WXDLLIMPEXP_CORE wxChar *wxCanvasClassName;
ff4aedc5 47#else
316d19ac 48extern WXDLLIMPEXP_CORE const wxChar *wxCanvasClassName;
ff4aedc5 49#endif
1a680109 50
ff4aedc5
RN
51//===========================================================================
52// BACKEND DECLARATIONS
53//===========================================================================
1a680109
RN
54
55//---------------------------------------------------------------------------
ff4aedc5
RN
56//
57// wxAMMediaBackend
58//
1a680109
RN
59//---------------------------------------------------------------------------
60
ff4aedc5 61//---------------------------------------------------------------------------
a2a444e3
RN
62// COM includes
63//---------------------------------------------------------------------------
64#include "wx/msw/ole/oleutils.h" //wxBasicString, IID etc.
65#include "wx/msw/ole/uuid.h" //IID etc..
66
67//---------------------------------------------------------------------------
68// IIDS - used by CoCreateInstance and IUnknown::QueryInterface
69//---------------------------------------------------------------------------
70const IID LIBID_QuartzTypeLib = {0x56A868B0,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
71const IID IID_IAMCollection = {0x56A868B9,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
72const IID IID_IMediaControl = {0x56A868B1,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
73const IID IID_IMediaEvent = {0x56A868B6,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
74const IID IID_IMediaEventEx = {0x56A868C0,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
75const IID IID_IMediaPosition = {0x56A868B2,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
76const IID IID_IBasicAudio = {0x56A868B3,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
77const IID IID_IVideoWindow = {0x56A868B4,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
78const IID IID_IBasicVideo = {0x56A868B5,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
79const IID IID_IBasicVideo2 = {0x329BB360,0xF6EA,0x11D1,{0x90,0x38,0x00,0xA0,0xC9,0x69,0x72,0x98}};
80const IID IID_IDeferredCommand = {0x56A868B8,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
81const IID IID_IQueueCommand = {0x56A868B7,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
82const IID IID_IFilterInfo = {0x56A868BA,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
83const IID IID_IRegFilterInfo = {0x56A868BB,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
84const IID IID_IMediaTypeInfo = {0x56A868BC,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
85const IID IID_IPinInfo = {0x56A868BD,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
86const IID IID_IAMStats = {0xBC9BCF80,0xDCD2,0x11D2,{0xAB,0xF6,0x00,0xA0,0xC9,0x05,0xF3,0x75}};
87
88//TODO: These 4 lines needed?
89#ifndef CLSID_DEFINED
90#define CLSID_DEFINED
91typedef IID CLSID;
92#endif // CLSID_DEFINED
93
94//COM Class Factory
95const CLSID CLSID_FilgraphManager = {0xE436EBB3,0x524F,0x11CE,{0x9F,0x53,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
96
97//---------------------------------------------------------------------------
98// COM INTERFACES (dumped from midl from quartz.idl from MSVC COM Browser)
99//---------------------------------------------------------------------------
100MIDL_INTERFACE("56A868B9-0AD4-11CE-B03A-0020AF0BA770")
101IAMCollection : public IDispatch
102{
103public:
104 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Count(
105 /* [retval][out] */ long __RPC_FAR *plCount) = 0;
106
107 virtual /* [id] */ HRESULT STDMETHODCALLTYPE Item(
108 /* [in] */ long lItem,
109 /* [out] */ IUnknown __RPC_FAR *__RPC_FAR *ppUnk) = 0;
110
111 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get__NewEnum(
112 /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppUnk) = 0;
113
114};
115
116MIDL_INTERFACE("56A868B1-0AD4-11CE-B03A-0020AF0BA770")
117IMediaControl : public IDispatch
118{
119public:
120 virtual /* [id] */ HRESULT STDMETHODCALLTYPE Run( void) = 0;
121
122 virtual /* [id] */ HRESULT STDMETHODCALLTYPE Pause( void) = 0;
123
124 virtual /* [id] */ HRESULT STDMETHODCALLTYPE Stop( void) = 0;
125
126 virtual /* [id] */ HRESULT STDMETHODCALLTYPE GetState(
127 /* [in] */ long msTimeout,
128 /* [out] */ long __RPC_FAR *pfs) = 0;
129
130 virtual /* [id] */ HRESULT STDMETHODCALLTYPE RenderFile(
131 /* [in] */ BSTR strFilename) = 0;
132
133 virtual /* [id] */ HRESULT STDMETHODCALLTYPE AddSourceFilter(
134 /* [in] */ BSTR strFilename,
135 /* [out] */ IDispatch __RPC_FAR *__RPC_FAR *ppUnk) = 0;
136
137 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_FilterCollection(
138 /* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *ppUnk) = 0;
139
140 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_RegFilterCollection(
141 /* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *ppUnk) = 0;
142
143 virtual /* [id] */ HRESULT STDMETHODCALLTYPE StopWhenReady( void) = 0;
144
145};
146
147MIDL_INTERFACE("56A868B6-0AD4-11CE-B03A-0020AF0BA770")
148IMediaEvent : public IDispatch
149{
150public:
151 virtual /* [id] */ HRESULT STDMETHODCALLTYPE GetEventHandle(
152 /* [out] */ LONG_PTR __RPC_FAR *hEvent) = 0;
153
154 virtual /* [id] */ HRESULT STDMETHODCALLTYPE GetEvent(
155 /* [out] */ long __RPC_FAR *lEventCode,
156 /* [out] */ LONG_PTR __RPC_FAR *lParam1,
157 /* [out] */ LONG_PTR __RPC_FAR *lParam2,
158 /* [in] */ long msTimeout) = 0;
159
160 virtual /* [id] */ HRESULT STDMETHODCALLTYPE WaitForCompletion(
161 /* [in] */ long msTimeout,
162 /* [out] */ long __RPC_FAR *pEvCode) = 0;
163
164 virtual /* [id] */ HRESULT STDMETHODCALLTYPE CancelDefaultHandling(
165 /* [in] */ long lEvCode) = 0;
166
167 virtual /* [id] */ HRESULT STDMETHODCALLTYPE RestoreDefaultHandling(
168 /* [in] */ long lEvCode) = 0;
169
170 virtual /* [id] */ HRESULT STDMETHODCALLTYPE FreeEventParams(
171 /* [in] */ long lEvCode,
172 /* [in] */ LONG_PTR lParam1,
173 /* [in] */ LONG_PTR lParam2) = 0;
174
175};
176
177MIDL_INTERFACE("56A868C0-0AD4-11CE-B03A-0020AF0BA770")
178IMediaEventEx : public IMediaEvent
179{
180public:
181 virtual HRESULT __stdcall SetNotifyWindow(
182 /* [in] */ LONG_PTR hwnd,
183 /* [in] */ long lMsg,
184 /* [in] */ LONG_PTR lInstanceData) = 0;
185
186 virtual HRESULT __stdcall SetNotifyFlags(
187 /* [in] */ long lNoNotifyFlags) = 0;
188
189 virtual HRESULT __stdcall GetNotifyFlags(
190 /* [out] */ long __RPC_FAR *lplNoNotifyFlags) = 0;
191
192};
193
194MIDL_INTERFACE("56A868B2-0AD4-11CE-B03A-0020AF0BA770")
195IMediaPosition : public IDispatch
196{
197public:
198 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Duration(
199 /* [retval][out] */ double __RPC_FAR *plength) = 0;
200
201 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_CurrentPosition(
202 /* [in] */ double pllTime) = 0;
203
204 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_CurrentPosition(
205 /* [retval][out] */ double __RPC_FAR *pllTime) = 0;
206
207 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_StopTime(
208 /* [retval][out] */ double __RPC_FAR *pllTime) = 0;
209
210 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_StopTime(
211 /* [in] */ double pllTime) = 0;
212
213 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_PrerollTime(
214 /* [retval][out] */ double __RPC_FAR *pllTime) = 0;
215
216 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_PrerollTime(
217 /* [in] */ double pllTime) = 0;
218
219 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_Rate(
220 /* [in] */ double pdRate) = 0;
221
222 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Rate(
223 /* [retval][out] */ double __RPC_FAR *pdRate) = 0;
224
225 virtual /* [id] */ HRESULT STDMETHODCALLTYPE CanSeekForward(
226 /* [retval][out] */ long __RPC_FAR *pCanSeekForward) = 0;
227
228 virtual /* [id] */ HRESULT STDMETHODCALLTYPE CanSeekBackward(
229 /* [retval][out] */ long __RPC_FAR *pCanSeekBackward) = 0;
230
231};
232
233MIDL_INTERFACE("56A868B3-0AD4-11CE-B03A-0020AF0BA770")
234IBasicAudio : public IDispatch
235{
236public:
237 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_Volume(
238 /* [in] */ long plVolume) = 0;
239
240 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Volume(
241 /* [retval][out] */ long __RPC_FAR *plVolume) = 0;
242
243 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_Balance(
244 /* [in] */ long plBalance) = 0;
245
246 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Balance(
247 /* [retval][out] */ long __RPC_FAR *plBalance) = 0;
248
249};
250
251MIDL_INTERFACE("56A868B4-0AD4-11CE-B03A-0020AF0BA770")
252IVideoWindow : public IDispatch
253{
254public:
255 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_Caption(
256 /* [in] */ BSTR strCaption) = 0;
257
258 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Caption(
259 /* [retval][out] */ BSTR __RPC_FAR *strCaption) = 0;
260
261 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_WindowStyle(
262 /* [in] */ long WindowStyle) = 0;
263
264 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_WindowStyle(
265 /* [retval][out] */ long __RPC_FAR *WindowStyle) = 0;
266
267 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_WindowStyleEx(
268 /* [in] */ long WindowStyleEx) = 0;
269
270 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_WindowStyleEx(
271 /* [retval][out] */ long __RPC_FAR *WindowStyleEx) = 0;
272
273 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_AutoShow(
274 /* [in] */ long AutoShow) = 0;
275
276 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_AutoShow(
277 /* [retval][out] */ long __RPC_FAR *AutoShow) = 0;
278
279 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_WindowState(
280 /* [in] */ long WindowState) = 0;
281
282 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_WindowState(
283 /* [retval][out] */ long __RPC_FAR *WindowState) = 0;
284
285 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_BackgroundPalette(
286 /* [in] */ long pBackgroundPalette) = 0;
287
288 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_BackgroundPalette(
289 /* [retval][out] */ long __RPC_FAR *pBackgroundPalette) = 0;
290
291 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_Visible(
292 /* [in] */ long pVisible) = 0;
293
294 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Visible(
295 /* [retval][out] */ long __RPC_FAR *pVisible) = 0;
296
297 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_Left(
298 /* [in] */ long pLeft) = 0;
299
300 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Left(
301 /* [retval][out] */ long __RPC_FAR *pLeft) = 0;
302
303 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_Width(
304 /* [in] */ long pWidth) = 0;
305
306 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Width(
307 /* [retval][out] */ long __RPC_FAR *pWidth) = 0;
308
309 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_Top(
310 /* [in] */ long pTop) = 0;
311
312 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Top(
313 /* [retval][out] */ long __RPC_FAR *pTop) = 0;
314
315 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_Height(
316 /* [in] */ long pHeight) = 0;
317
318 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Height(
319 /* [retval][out] */ long __RPC_FAR *pHeight) = 0;
320
321 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_Owner(
322 /* [in] */ LONG_PTR Owner) = 0;
323
324 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Owner(
325 /* [retval][out] */ LONG_PTR __RPC_FAR *Owner) = 0;
326
327 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_MessageDrain(
328 /* [in] */ LONG_PTR Drain) = 0;
329
330 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_MessageDrain(
331 /* [retval][out] */ LONG_PTR __RPC_FAR *Drain) = 0;
332
333 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_BorderColor(
334 /* [retval][out] */ long __RPC_FAR *Color) = 0;
335
336 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_BorderColor(
337 /* [in] */ long Color) = 0;
338
339 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_FullScreenMode(
340 /* [retval][out] */ long __RPC_FAR *FullScreenMode) = 0;
341
342 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_FullScreenMode(
343 /* [in] */ long FullScreenMode) = 0;
344
345 virtual /* [id] */ HRESULT STDMETHODCALLTYPE SetWindowForeground(
346 /* [in] */ long Focus) = 0;
347
348 virtual /* [id] */ HRESULT STDMETHODCALLTYPE NotifyOwnerMessage(
349 /* [in] */ LONG_PTR hwnd,
350 /* [in] */ long uMsg,
351 /* [in] */ LONG_PTR wParam,
352 /* [in] */ LONG_PTR lParam) = 0;
353
354 virtual /* [id] */ HRESULT STDMETHODCALLTYPE SetWindowPosition(
355 /* [in] */ long Left,
356 /* [in] */ long Top,
357 /* [in] */ long Width,
358 /* [in] */ long Height) = 0;
359
360 virtual /* [id] */ HRESULT STDMETHODCALLTYPE GetWindowPosition(
361 /* [out] */ long __RPC_FAR *pLeft,
362 /* [out] */ long __RPC_FAR *pTop,
363 /* [out] */ long __RPC_FAR *pWidth,
364 /* [out] */ long __RPC_FAR *pHeight) = 0;
365
366 virtual /* [id] */ HRESULT STDMETHODCALLTYPE GetMinIdealImageSize(
367 /* [out] */ long __RPC_FAR *pWidth,
368 /* [out] */ long __RPC_FAR *pHeight) = 0;
369
370 virtual /* [id] */ HRESULT STDMETHODCALLTYPE GetMaxIdealImageSize(
371 /* [out] */ long __RPC_FAR *pWidth,
372 /* [out] */ long __RPC_FAR *pHeight) = 0;
373
374 virtual /* [id] */ HRESULT STDMETHODCALLTYPE GetRestorePosition(
375 /* [out] */ long __RPC_FAR *pLeft,
376 /* [out] */ long __RPC_FAR *pTop,
377 /* [out] */ long __RPC_FAR *pWidth,
378 /* [out] */ long __RPC_FAR *pHeight) = 0;
379
380 virtual /* [id] */ HRESULT STDMETHODCALLTYPE HideCursor(
381 /* [in] */ long HideCursor) = 0;
382
383 virtual /* [id] */ HRESULT STDMETHODCALLTYPE IsCursorHidden(
384 /* [out] */ long __RPC_FAR *CursorHidden) = 0;
385
386};
1a680109 387
a2a444e3
RN
388MIDL_INTERFACE("56A868B5-0AD4-11CE-B03A-0020AF0BA770")
389IBasicVideo : public IDispatch
390{
391public:
392 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_AvgTimePerFrame(
393 /* [retval][out] */ double __RPC_FAR *pAvgTimePerFrame) = 0;
394
395 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_BitRate(
396 /* [retval][out] */ long __RPC_FAR *pBitRate) = 0;
397
398 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_BitErrorRate(
399 /* [retval][out] */ long __RPC_FAR *pBitErrorRate) = 0;
400
401 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_VideoWidth(
402 /* [retval][out] */ long __RPC_FAR *pVideoWidth) = 0;
403
404 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_VideoHeight(
405 /* [retval][out] */ long __RPC_FAR *pVideoHeight) = 0;
406
407 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_SourceLeft(
408 /* [in] */ long pSourceLeft) = 0;
409
410 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_SourceLeft(
411 /* [retval][out] */ long __RPC_FAR *pSourceLeft) = 0;
412
413 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_SourceWidth(
414 /* [in] */ long pSourceWidth) = 0;
415
416 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_SourceWidth(
417 /* [retval][out] */ long __RPC_FAR *pSourceWidth) = 0;
418
419 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_SourceTop(
420 /* [in] */ long pSourceTop) = 0;
421
422 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_SourceTop(
423 /* [retval][out] */ long __RPC_FAR *pSourceTop) = 0;
424
425 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_SourceHeight(
426 /* [in] */ long pSourceHeight) = 0;
427
428 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_SourceHeight(
429 /* [retval][out] */ long __RPC_FAR *pSourceHeight) = 0;
430
431 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_DestinationLeft(
432 /* [in] */ long pDestinationLeft) = 0;
433
434 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_DestinationLeft(
435 /* [retval][out] */ long __RPC_FAR *pDestinationLeft) = 0;
436
437 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_DestinationWidth(
438 /* [in] */ long pDestinationWidth) = 0;
439
440 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_DestinationWidth(
441 /* [retval][out] */ long __RPC_FAR *pDestinationWidth) = 0;
442
443 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_DestinationTop(
444 /* [in] */ long pDestinationTop) = 0;
445
446 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_DestinationTop(
447 /* [retval][out] */ long __RPC_FAR *pDestinationTop) = 0;
448
449 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_DestinationHeight(
450 /* [in] */ long pDestinationHeight) = 0;
451
452 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_DestinationHeight(
453 /* [retval][out] */ long __RPC_FAR *pDestinationHeight) = 0;
454
455 virtual /* [id] */ HRESULT STDMETHODCALLTYPE SetSourcePosition(
456 /* [in] */ long Left,
457 /* [in] */ long Top,
458 /* [in] */ long Width,
459 /* [in] */ long Height) = 0;
460
461 virtual /* [id] */ HRESULT STDMETHODCALLTYPE GetSourcePosition(
462 /* [out] */ long __RPC_FAR *pLeft,
463 /* [out] */ long __RPC_FAR *pTop,
464 /* [out] */ long __RPC_FAR *pWidth,
465 /* [out] */ long __RPC_FAR *pHeight) = 0;
466
467 virtual /* [id] */ HRESULT STDMETHODCALLTYPE SetDefaultSourcePosition( void) = 0;
468
469 virtual /* [id] */ HRESULT STDMETHODCALLTYPE SetDestinationPosition(
470 /* [in] */ long Left,
471 /* [in] */ long Top,
472 /* [in] */ long Width,
473 /* [in] */ long Height) = 0;
474
475 virtual /* [id] */ HRESULT STDMETHODCALLTYPE GetDestinationPosition(
476 /* [out] */ long __RPC_FAR *pLeft,
477 /* [out] */ long __RPC_FAR *pTop,
478 /* [out] */ long __RPC_FAR *pWidth,
479 /* [out] */ long __RPC_FAR *pHeight) = 0;
480
481 virtual /* [id] */ HRESULT STDMETHODCALLTYPE SetDefaultDestinationPosition( void) = 0;
482
483 virtual /* [id] */ HRESULT STDMETHODCALLTYPE GetVideoSize(
484 /* [out] */ long __RPC_FAR *pWidth,
485 /* [out] */ long __RPC_FAR *pHeight) = 0;
486
487 virtual /* [id] */ HRESULT STDMETHODCALLTYPE GetVideoPaletteEntries(
488 /* [in] */ long StartIndex,
489 /* [in] */ long Entries,
490 /* [out] */ long __RPC_FAR *pRetrieved,
491 /* [out] */ long __RPC_FAR *pPalette) = 0;
492
493 virtual /* [id] */ HRESULT STDMETHODCALLTYPE GetCurrentImage(
494 /* [out][in] */ long __RPC_FAR *pBufferSize,
495 /* [out] */ long __RPC_FAR *pDIBImage) = 0;
496
497 virtual /* [id] */ HRESULT STDMETHODCALLTYPE IsUsingDefaultSource( void) = 0;
498
499 virtual /* [id] */ HRESULT STDMETHODCALLTYPE IsUsingDefaultDestination( void) = 0;
500
501};
502
503MIDL_INTERFACE("329BB360-F6EA-11D1-9038-00A0C9697298")
504IBasicVideo2 : public IBasicVideo
505{
506public:
507 virtual HRESULT __stdcall GetPreferredAspectRatio(
508 /* [out] */ long __RPC_FAR *plAspectX,
509 /* [out] */ long __RPC_FAR *plAspectY) = 0;
510
511};
512
513MIDL_INTERFACE("56A868B8-0AD4-11CE-B03A-0020AF0BA770")
514IDeferredCommand : public IUnknown
515{
516public:
517 virtual HRESULT __stdcall Cancel( void) = 0;
518
519 virtual HRESULT __stdcall Confidence(
520 /* [out] */ long __RPC_FAR *pConfidence) = 0;
521
522 virtual HRESULT __stdcall Postpone(
523 /* [in] */ double newtime) = 0;
524
525 virtual HRESULT __stdcall GetHResult(
526 /* [out] */ HRESULT __RPC_FAR *phrResult) = 0;
527
528};
529
530MIDL_INTERFACE("56A868B7-0AD4-11CE-B03A-0020AF0BA770")
531IQueueCommand : public IUnknown
532{
533public:
534 virtual HRESULT __stdcall InvokeAtStreamTime(
535 /* [out] */ IDeferredCommand __RPC_FAR *__RPC_FAR *pCmd,
536 /* [in] */ double time,
537 /* [in] */ GUID __RPC_FAR *iid,
538 /* [in] */ long dispidMethod,
539 /* [in] */ short wFlags,
540 /* [in] */ long cArgs,
541 /* [in] */ VARIANT __RPC_FAR *pDispParams,
542 /* [out][in] */ VARIANT __RPC_FAR *pvarResult,
543 /* [out] */ short __RPC_FAR *puArgErr) = 0;
544
545 virtual HRESULT __stdcall InvokeAtPresentationTime(
546 /* [out] */ IDeferredCommand __RPC_FAR *__RPC_FAR *pCmd,
547 /* [in] */ double time,
548 /* [in] */ GUID __RPC_FAR *iid,
549 /* [in] */ long dispidMethod,
550 /* [in] */ short wFlags,
551 /* [in] */ long cArgs,
552 /* [in] */ VARIANT __RPC_FAR *pDispParams,
553 /* [out][in] */ VARIANT __RPC_FAR *pvarResult,
554 /* [out] */ short __RPC_FAR *puArgErr) = 0;
555
556};
557
558MIDL_INTERFACE("56A868BA-0AD4-11CE-B03A-0020AF0BA770")
559IFilterInfo : public IDispatch
560{
561public:
562 virtual /* [id] */ HRESULT STDMETHODCALLTYPE FindPin(
563 /* [in] */ BSTR strPinID,
564 /* [out] */ IDispatch __RPC_FAR *__RPC_FAR *ppUnk) = 0;
565
566 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Name(
567 /* [retval][out] */ BSTR __RPC_FAR *strName) = 0;
568
569 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_VendorInfo(
570 /* [retval][out] */ BSTR __RPC_FAR *strVendorInfo) = 0;
571
572 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Filter(
573 /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppUnk) = 0;
574
575 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Pins(
576 /* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *ppUnk) = 0;
577
578 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_IsFileSource(
579 /* [retval][out] */ long __RPC_FAR *pbIsSource) = 0;
580
581 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Filename(
582 /* [retval][out] */ BSTR __RPC_FAR *pstrFilename) = 0;
583
584 virtual /* [propput][id] */ HRESULT STDMETHODCALLTYPE put_Filename(
585 /* [in] */ BSTR pstrFilename) = 0;
586
587};
588
589MIDL_INTERFACE("56A868BB-0AD4-11CE-B03A-0020AF0BA770")
590IRegFilterInfo : public IDispatch
591{
592public:
593 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Name(
594 /* [retval][out] */ BSTR __RPC_FAR *strName) = 0;
595
596 virtual /* [id] */ HRESULT STDMETHODCALLTYPE Filter(
597 /* [out] */ IDispatch __RPC_FAR *__RPC_FAR *ppUnk) = 0;
598
599};
600
601MIDL_INTERFACE("56A868BC-0AD4-11CE-B03A-0020AF0BA770")
602IMediaTypeInfo : public IDispatch
603{
604public:
605 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Type(
606 /* [retval][out] */ BSTR __RPC_FAR *strType) = 0;
607
608 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Subtype(
609 /* [retval][out] */ BSTR __RPC_FAR *strType) = 0;
610
611};
612
613MIDL_INTERFACE("56A868BD-0AD4-11CE-B03A-0020AF0BA770")
614IPinInfo : public IDispatch
615{
616public:
617 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Pin(
618 /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppUnk) = 0;
619
620 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_ConnectedTo(
621 /* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *ppUnk) = 0;
622
623 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_ConnectionMediaType(
624 /* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *ppUnk) = 0;
625
626 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_FilterInfo(
627 /* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *ppUnk) = 0;
628
629 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Name(
630 /* [retval][out] */ BSTR __RPC_FAR *ppUnk) = 0;
631
632 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Direction(
633 /* [retval][out] */ long __RPC_FAR *ppDirection) = 0;
634
635 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_PinID(
636 /* [retval][out] */ BSTR __RPC_FAR *strPinID) = 0;
637
638 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_MediaTypes(
639 /* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *ppUnk) = 0;
640
641 virtual /* [id] */ HRESULT STDMETHODCALLTYPE Connect(
642 /* [in] */ IUnknown __RPC_FAR *pPin) = 0;
643
644 virtual /* [id] */ HRESULT STDMETHODCALLTYPE ConnectDirect(
645 /* [in] */ IUnknown __RPC_FAR *pPin) = 0;
646
647 virtual /* [id] */ HRESULT STDMETHODCALLTYPE ConnectWithType(
648 /* [in] */ IUnknown __RPC_FAR *pPin,
649 /* [in] */ IDispatch __RPC_FAR *pMediaType) = 0;
650
651 virtual /* [id] */ HRESULT STDMETHODCALLTYPE Disconnect( void) = 0;
652
653 virtual /* [id] */ HRESULT STDMETHODCALLTYPE Render( void) = 0;
654
655};
656
657MIDL_INTERFACE("BC9BCF80-DCD2-11D2-ABF6-00A0C905F375")
658IAMStats : public IDispatch
659{
660public:
661 virtual /* [id] */ HRESULT STDMETHODCALLTYPE Reset( void) = 0;
662
663 virtual /* [propget][id] */ HRESULT STDMETHODCALLTYPE get_Count(
664 /* [retval][out] */ long __RPC_FAR *plCount) = 0;
665
666 virtual /* [id] */ HRESULT STDMETHODCALLTYPE GetValueByIndex(
667 /* [in] */ long lIndex,
668 /* [out] */ BSTR __RPC_FAR *szName,
669 /* [out] */ long __RPC_FAR *lCount,
670 /* [out] */ double __RPC_FAR *dLast,
671 /* [out] */ double __RPC_FAR *dAverage,
672 /* [out] */ double __RPC_FAR *dStdDev,
673 /* [out] */ double __RPC_FAR *dMin,
674 /* [out] */ double __RPC_FAR *dMax) = 0;
675
676 virtual /* [id] */ HRESULT STDMETHODCALLTYPE GetValueByName(
677 /* [in] */ BSTR szName,
678 /* [out] */ long __RPC_FAR *lIndex,
679 /* [out] */ long __RPC_FAR *lCount,
680 /* [out] */ double __RPC_FAR *dLast,
681 /* [out] */ double __RPC_FAR *dAverage,
682 /* [out] */ double __RPC_FAR *dStdDev,
683 /* [out] */ double __RPC_FAR *dMin,
684 /* [out] */ double __RPC_FAR *dMax) = 0;
685
686 virtual /* [id] */ HRESULT STDMETHODCALLTYPE GetIndex(
687 /* [in] */ BSTR szName,
688 /* [in] */ long lCreate,
689 /* [out] */ long __RPC_FAR *plIndex) = 0;
690
691 virtual /* [id] */ HRESULT STDMETHODCALLTYPE AddValue(
692 /* [in] */ long lIndex,
693 /* [in] */ double dValue) = 0;
694
695};
696
697//------------------------------------------------------------------
698// wxAMMediaBackend (Active Movie)
699//------------------------------------------------------------------
ff2b312f 700class WXDLLIMPEXP_MEDIA wxAMMediaBackend : public wxMediaBackend
1a680109
RN
701{
702public:
ff4aedc5 703 wxAMMediaBackend();
1a680109 704
ff4aedc5 705 virtual ~wxAMMediaBackend();
1a680109 706
226ec5a7 707 virtual bool CreateControl(wxControl* ctrl, wxWindow* parent,
ff4aedc5 708 wxWindowID id,
226ec5a7 709 const wxPoint& pos,
ff4aedc5 710 const wxSize& size,
226ec5a7 711 long style,
ff4aedc5
RN
712 const wxValidator& validator,
713 const wxString& name);
1a680109
RN
714
715 virtual bool Play();
716 virtual bool Pause();
717 virtual bool Stop();
718
719 virtual bool Load(const wxString& fileName);
720 virtual bool Load(const wxURI& location);
721
722 virtual wxMediaState GetState();
723
ff4aedc5
RN
724 virtual bool SetPosition(wxLongLong where);
725 virtual wxLongLong GetPosition();
726 virtual wxLongLong GetDuration();
1a680109 727
ff4aedc5
RN
728 virtual void Move(int x, int y, int w, int h);
729 wxSize GetVideoSize() const;
1a680109
RN
730
731 virtual double GetPlaybackRate();
732 virtual bool SetPlaybackRate(double);
733
6f8c67e7
JS
734 virtual double GetVolume();
735 virtual bool SetVolume(double);
736
1a680109
RN
737 void Cleanup();
738
739 bool m_bVideo;
740
226ec5a7 741 static LRESULT CALLBACK NotifyWndProc(HWND hWnd, UINT nMsg,
ff4aedc5 742 WPARAM wParam, LPARAM lParam);
226ec5a7
WS
743
744 LRESULT CALLBACK OnNotifyWndProc(HWND hWnd, UINT nMsg,
ff4aedc5 745 WPARAM wParam, LPARAM lParam);
1a680109 746
ff4aedc5 747 wxControl* m_ctrl;
1a680109 748
a2a444e3
RN
749 IBasicAudio* m_pBA;
750 IBasicVideo* m_pBV;
1a680109
RN
751 IMediaControl* m_pMC;
752 IMediaEventEx* m_pME;
a2a444e3 753 IMediaPosition* m_pMS;
1a680109 754 IVideoWindow* m_pVW;
1a680109 755
ff4aedc5 756 HWND m_hNotifyWnd;
1a680109 757 wxSize m_bestSize;
ff4aedc5
RN
758
759 DECLARE_DYNAMIC_CLASS(wxAMMediaBackend);
1a680109
RN
760};
761
1a680109 762//---------------------------------------------------------------------------
ff4aedc5
RN
763//
764// wxMCIMediaBackend
765//
1a680109
RN
766//---------------------------------------------------------------------------
767
ff4aedc5
RN
768//---------------------------------------------------------------------------
769// MCI Includes
770//---------------------------------------------------------------------------
1a680109 771#include <mmsystem.h>
1a680109 772
ff2b312f 773class WXDLLIMPEXP_MEDIA wxMCIMediaBackend : public wxMediaBackend
1a680109
RN
774{
775public:
3f9a3bf9 776
ff4aedc5
RN
777 wxMCIMediaBackend();
778 ~wxMCIMediaBackend();
1a680109 779
226ec5a7 780 virtual bool CreateControl(wxControl* ctrl, wxWindow* parent,
ff4aedc5 781 wxWindowID id,
226ec5a7 782 const wxPoint& pos,
ff4aedc5 783 const wxSize& size,
226ec5a7 784 long style,
ff4aedc5
RN
785 const wxValidator& validator,
786 const wxString& name);
1a680109
RN
787
788 virtual bool Play();
789 virtual bool Pause();
790 virtual bool Stop();
791
792 virtual bool Load(const wxString& fileName);
793 virtual bool Load(const wxURI& location);
794
795 virtual wxMediaState GetState();
796
ff4aedc5
RN
797 virtual bool SetPosition(wxLongLong where);
798 virtual wxLongLong GetPosition();
799 virtual wxLongLong GetDuration();
1a680109 800
ff4aedc5
RN
801 virtual void Move(int x, int y, int w, int h);
802 wxSize GetVideoSize() const;
1a680109
RN
803
804 virtual double GetPlaybackRate();
ff4aedc5 805 virtual bool SetPlaybackRate(double dRate);
3f9a3bf9 806
6f8c67e7
JS
807 virtual double GetVolume();
808 virtual bool SetVolume(double);
809
226ec5a7 810 static LRESULT CALLBACK NotifyWndProc(HWND hWnd, UINT nMsg,
ff4aedc5 811 WPARAM wParam, LPARAM lParam);
5987f174 812
226ec5a7 813 LRESULT CALLBACK OnNotifyWndProc(HWND hWnd, UINT nMsg,
ff4aedc5 814 WPARAM wParam, LPARAM lParam);
1a680109 815
ff4aedc5
RN
816 MCIDEVICEID m_hDev; //Our MCI Device ID/Handler
817 wxControl* m_ctrl; //Parent control
818 HWND m_hNotifyWnd; //Window to use for MCI events
819 bool m_bVideo; //Whether or not we have video
820
3839f37e 821 DECLARE_DYNAMIC_CLASS(wxMCIMediaBackend)
ff4aedc5 822};
1a680109
RN
823
824//---------------------------------------------------------------------------
825//
ff4aedc5 826// wxQTMediaBackend
1a680109
RN
827//
828//---------------------------------------------------------------------------
829
ff4aedc5
RN
830//---------------------------------------------------------------------------
831// QT Includes
832//---------------------------------------------------------------------------
d7a9c895
RN
833//#include <qtml.h> //Windoze QT include
834//#include <QuickTimeComponents.h> //Standard QT stuff
835#include "wx/dynlib.h"
836
837//---------------------------------------------------------------------------
838// QT Types
839//---------------------------------------------------------------------------
840typedef struct MovieRecord* Movie;
841typedef wxInt16 OSErr;
842typedef wxInt32 OSStatus;
843#define noErr 0
844#define fsRdPerm 1
845typedef unsigned char Str255[256];
846#define StringPtr unsigned char*
847#define newMovieActive 1
848#define Ptr char*
849#define Handle Ptr*
850#define Fixed long
851#define OSType unsigned long
852#define CGrafPtr struct GrafPort *
853#define TimeScale long
854#define TimeBase struct TimeBaseRecord *
855
856struct FSSpec {
857 short vRefNum;
858 long parID;
859 Str255 name; /*Str63 on mac, Str255 on msw */
860};
861
862struct Rect {
863 short top;
864 short left;
865 short bottom;
866 short right;
867};
868
869struct wide {
870 wxInt32 hi;
871 wxUint32 lo;
872};
873
874struct TimeRecord {
875 wide value; /* units */
876 TimeScale scale; /* units per second */
877 TimeBase base;
878};
879
880//---------------------------------------------------------------------------
881// QT Library
882//---------------------------------------------------------------------------
883#define wxDL_METHOD_DEFINE( rettype, name, args, shortargs, defret ) \
884 typedef rettype (* name ## Type) args ; \
885 name ## Type pfn_ ## name; \
886 rettype name args \
887 { if (m_ok) return pfn_ ## name shortargs ; return defret; }
888
889#define wxDL_VOIDMETHOD_DEFINE( name, args, shortargs ) \
890 typedef void (* name ## Type) args ; \
891 name ## Type pfn_ ## name; \
892 void name args \
893 { if (m_ok) pfn_ ## name shortargs ; }
894
895#define wxDL_METHOD_LOAD( lib, name, success ) \
896 pfn_ ## name = (name ## Type) lib.GetSymbol( wxT(#name), &success ); \
897 if (!success) return false;
898
899//Class that utilizes Robert Roeblings Dynamic Library Macros
900class wxQuickTimeLibrary
901{
902public:
903 ~wxQuickTimeLibrary()
904 {
905 if(m_dll.IsLoaded())
906 m_dll.Unload();
907 }
908
909 bool Initialize();
910 bool IsOk() const {return m_ok;}
911
912protected:
913 wxDynamicLibrary m_dll;
914 bool m_ok;
915
916public:
917 wxDL_VOIDMETHOD_DEFINE( StartMovie, (Movie m), (m) );
918 wxDL_VOIDMETHOD_DEFINE( StopMovie, (Movie m), (m) );
919 wxDL_METHOD_DEFINE( bool, IsMovieDone, (Movie m), (m), false);
920 wxDL_VOIDMETHOD_DEFINE( GoToBeginningOfMovie, (Movie m), (m) );
921 wxDL_METHOD_DEFINE( OSErr, GetMoviesError, (), (), -1);
922 wxDL_METHOD_DEFINE( OSErr, EnterMovies, (), (), -1);
923 wxDL_VOIDMETHOD_DEFINE( ExitMovies, (), () );
924 wxDL_METHOD_DEFINE( OSErr, InitializeQTML, (long flags), (flags), -1);
925 wxDL_VOIDMETHOD_DEFINE( TerminateQTML, (), () );
926
927 wxDL_METHOD_DEFINE( OSErr, NativePathNameToFSSpec,
928 (char* inName, FSSpec* outFile, long flags),
929 (inName, outFile, flags), -1);
930
931 wxDL_METHOD_DEFINE( OSErr, OpenMovieFile,
932 (const FSSpec * fileSpec, short * resRefNum, wxInt8 permission),
933 (fileSpec, resRefNum, permission), -1 );
934
935 wxDL_METHOD_DEFINE( OSErr, CloseMovieFile,
936 (short resRefNum), (resRefNum), -1);
937
938 wxDL_METHOD_DEFINE( OSErr, NewMovieFromFile,
939 (Movie * theMovie, short resRefNum, short * resId,
940 StringPtr resName, short newMovieFlags,
941 bool * dataRefWasChanged),
942 (theMovie, resRefNum, resId, resName, newMovieFlags,
943 dataRefWasChanged), -1);
944
945 wxDL_VOIDMETHOD_DEFINE( SetMovieRate, (Movie m, Fixed rate), (m, rate) );
946 wxDL_METHOD_DEFINE( Fixed, GetMovieRate, (Movie m), (m), 0);
947 wxDL_VOIDMETHOD_DEFINE( MoviesTask, (Movie m, long maxms), (m, maxms) );
948 wxDL_VOIDMETHOD_DEFINE( BlockMove,
949 (const char* p1, const char* p2, long s), (p1,p2,s) );
950 wxDL_METHOD_DEFINE( Handle, NewHandleClear, (long s), (s), NULL );
951
952 wxDL_METHOD_DEFINE( OSErr, NewMovieFromDataRef,
953 (Movie * m, short flags, short * id,
954 Handle dataRef, OSType dataRefType),
955 (m,flags,id,dataRef,dataRefType), -1 );
956
957 wxDL_VOIDMETHOD_DEFINE( DisposeHandle, (Handle h), (h) );
958 wxDL_VOIDMETHOD_DEFINE( GetMovieNaturalBoundsRect, (Movie m, Rect* r), (m,r) );
959 wxDL_METHOD_DEFINE( void*, GetMovieIndTrackType,
960 (Movie m, long index, OSType type, long flags),
961 (m,index,type,flags), NULL );
962 wxDL_VOIDMETHOD_DEFINE( CreatePortAssociation,
963 (void* hWnd, void* junk, long morejunk), (hWnd, junk, morejunk) );
964 wxDL_METHOD_DEFINE(void*, GetNativeWindowPort, (void* hWnd), (hWnd), NULL);
965 wxDL_VOIDMETHOD_DEFINE(SetMovieGWorld, (Movie m, CGrafPtr port, void* whatever),
966 (m, port, whatever) );
967 wxDL_VOIDMETHOD_DEFINE(DisposeMovie, (Movie m), (m) );
968 wxDL_VOIDMETHOD_DEFINE(SetMovieBox, (Movie m, Rect* r), (m,r));
969 wxDL_VOIDMETHOD_DEFINE(SetMovieTimeScale, (Movie m, long s), (m,s));
970 wxDL_METHOD_DEFINE(long, GetMovieDuration, (Movie m), (m), 0);
971 wxDL_METHOD_DEFINE(TimeBase, GetMovieTimeBase, (Movie m), (m), 0);
972 wxDL_METHOD_DEFINE(TimeScale, GetMovieTimeScale, (Movie m), (m), 0);
973 wxDL_METHOD_DEFINE(long, GetMovieTime, (Movie m, void* cruft), (m,cruft), 0);
974 wxDL_VOIDMETHOD_DEFINE(SetMovieTime, (Movie m, TimeRecord* tr), (m,tr) );
6f8c67e7
JS
975 wxDL_METHOD_DEFINE(short, GetMovieVolume, (Movie m), (m), 0);
976 wxDL_VOIDMETHOD_DEFINE(SetMovieVolume, (Movie m, short sVolume), (m,sVolume) );
d7a9c895
RN
977};
978
979bool wxQuickTimeLibrary::Initialize()
980{
981 m_ok = false;
982
983 if(!m_dll.Load(wxT("qtmlClient.dll")))
984 return false;
985
986 bool bOk;
987
988 wxDL_METHOD_LOAD( m_dll, StartMovie, bOk );
989 wxDL_METHOD_LOAD( m_dll, StopMovie, bOk );
990 wxDL_METHOD_LOAD( m_dll, IsMovieDone, bOk );
991 wxDL_METHOD_LOAD( m_dll, GoToBeginningOfMovie, bOk );
992 wxDL_METHOD_LOAD( m_dll, GetMoviesError, bOk );
993 wxDL_METHOD_LOAD( m_dll, EnterMovies, bOk );
994 wxDL_METHOD_LOAD( m_dll, ExitMovies, bOk );
995 wxDL_METHOD_LOAD( m_dll, InitializeQTML, bOk );
996 wxDL_METHOD_LOAD( m_dll, TerminateQTML, bOk );
997 wxDL_METHOD_LOAD( m_dll, NativePathNameToFSSpec, bOk );
998 wxDL_METHOD_LOAD( m_dll, OpenMovieFile, bOk );
999 wxDL_METHOD_LOAD( m_dll, CloseMovieFile, bOk );
1000 wxDL_METHOD_LOAD( m_dll, NewMovieFromFile, bOk );
1001 wxDL_METHOD_LOAD( m_dll, GetMovieRate, bOk );
1002 wxDL_METHOD_LOAD( m_dll, SetMovieRate, bOk );
1003 wxDL_METHOD_LOAD( m_dll, MoviesTask, bOk );
1004 wxDL_METHOD_LOAD( m_dll, BlockMove, bOk );
1005 wxDL_METHOD_LOAD( m_dll, NewHandleClear, bOk );
1006 wxDL_METHOD_LOAD( m_dll, NewMovieFromDataRef, bOk );
1007 wxDL_METHOD_LOAD( m_dll, DisposeHandle, bOk );
1008 wxDL_METHOD_LOAD( m_dll, GetMovieNaturalBoundsRect, bOk );
1009 wxDL_METHOD_LOAD( m_dll, GetMovieIndTrackType, bOk );
1010 wxDL_METHOD_LOAD( m_dll, CreatePortAssociation, bOk );
1011 wxDL_METHOD_LOAD( m_dll, GetNativeWindowPort, bOk );
1012 wxDL_METHOD_LOAD( m_dll, SetMovieGWorld, bOk );
1013 wxDL_METHOD_LOAD( m_dll, DisposeMovie, bOk );
1014 wxDL_METHOD_LOAD( m_dll, SetMovieBox, bOk );
1015 wxDL_METHOD_LOAD( m_dll, SetMovieTimeScale, bOk );
1016 wxDL_METHOD_LOAD( m_dll, GetMovieDuration, bOk );
1017 wxDL_METHOD_LOAD( m_dll, GetMovieTimeBase, bOk );
1018 wxDL_METHOD_LOAD( m_dll, GetMovieTimeScale, bOk );
1019 wxDL_METHOD_LOAD( m_dll, GetMovieTime, bOk );
1020 wxDL_METHOD_LOAD( m_dll, SetMovieTime, bOk );
6f8c67e7
JS
1021 wxDL_METHOD_LOAD( m_dll, GetMovieVolume, bOk );
1022 wxDL_METHOD_LOAD( m_dll, SetMovieVolume, bOk );
d7a9c895
RN
1023
1024 m_ok = true;
1025
1026 return true;
1027}
1a680109 1028
ff2b312f 1029class WXDLLIMPEXP_MEDIA wxQTMediaBackend : public wxMediaBackend
ff4aedc5
RN
1030{
1031public:
1a680109 1032
ff4aedc5
RN
1033 wxQTMediaBackend();
1034 ~wxQTMediaBackend();
1a680109 1035
226ec5a7 1036 virtual bool CreateControl(wxControl* ctrl, wxWindow* parent,
ff4aedc5 1037 wxWindowID id,
226ec5a7 1038 const wxPoint& pos,
ff4aedc5 1039 const wxSize& size,
226ec5a7 1040 long style,
ff4aedc5
RN
1041 const wxValidator& validator,
1042 const wxString& name);
1a680109 1043
ff4aedc5
RN
1044 virtual bool Play();
1045 virtual bool Pause();
1046 virtual bool Stop();
1a680109 1047
ff4aedc5
RN
1048 virtual bool Load(const wxString& fileName);
1049 virtual bool Load(const wxURI& location);
1a680109 1050
ff4aedc5 1051 virtual wxMediaState GetState();
1a680109 1052
ff4aedc5
RN
1053 virtual bool SetPosition(wxLongLong where);
1054 virtual wxLongLong GetPosition();
1055 virtual wxLongLong GetDuration();
1a680109 1056
ff4aedc5
RN
1057 virtual void Move(int x, int y, int w, int h);
1058 wxSize GetVideoSize() const;
1a680109 1059
ff4aedc5
RN
1060 virtual double GetPlaybackRate();
1061 virtual bool SetPlaybackRate(double dRate);
1a680109 1062
6f8c67e7
JS
1063 virtual double GetVolume();
1064 virtual bool SetVolume(double);
1065
ff4aedc5
RN
1066 void Cleanup();
1067 void FinishLoad();
1a680109 1068
ff4aedc5 1069 wxSize m_bestSize; //Original movie size
d7a9c895 1070 Movie m_movie; //QT Movie handle/instance
ff4aedc5
RN
1071 wxControl* m_ctrl; //Parent control
1072 bool m_bVideo; //Whether or not we have video
1073 class _wxQTTimer* m_timer; //Timer for streaming the movie
d7a9c895
RN
1074 wxQuickTimeLibrary m_lib;
1075
1a680109 1076
ff4aedc5
RN
1077 DECLARE_DYNAMIC_CLASS(wxQTMediaBackend);
1078};
1a680109 1079
1a680109 1080
ff4aedc5
RN
1081//===========================================================================
1082// IMPLEMENTATION
1083//===========================================================================
1a680109 1084
ff4aedc5
RN
1085//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1086//
1087// wxAMMediaBackend
1088//
1089//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1a680109 1090
ff4aedc5 1091IMPLEMENT_DYNAMIC_CLASS(wxAMMediaBackend, wxMediaBackend);
1a680109 1092
ff4aedc5
RN
1093// Numerical value for when the graph reaches the stop position
1094#define WM_GRAPHNOTIFY WM_USER+13
1a680109 1095
ff4aedc5
RN
1096//---------------------------------------------------------------------------
1097// Usual debugging macros
1098//---------------------------------------------------------------------------
1099#ifdef __WXDEBUG__
1100#define wxAMVERIFY(x) \
1101{ \
1102 HRESULT hrdsv = (x); \
1103 if ( FAILED(hrdsv) ) \
1104 { \
1105 /*TCHAR szError[MAX_ERROR_TEXT_LEN];*/ \
1106 /*if( AMGetErrorText(hrdsv, szError, MAX_ERROR_TEXT_LEN) == 0)*/ \
1107 /*{*/ \
1108 /*wxFAIL_MSG( wxString::Format(wxT("DirectShow error \"%s\" ")*/\
1109 /*wxT("occured at line %i in ")*/ \
1110 /*wxT("mediactrl.cpp"),*/ \
1111 /*szError, __LINE__) );*/ \
1112 /*}*/ \
1113 /*else*/ \
1114 wxFAIL_MSG( wxString::Format(wxT("Unknown error (%i) ") \
1115 wxT("occured at") \
1116 wxT(" line %i in mediactrl.cpp."), \
1117 (int)hrdsv, __LINE__) ); \
1118 } \
1a680109 1119}
ff4aedc5
RN
1120#define wxVERIFY(x) wxASSERT((x))
1121#else
1122#define wxAMVERIFY(x) (x)
1123#define wxVERIFY(x) (x)
1124#endif
1a680109 1125
ff4aedc5
RN
1126//---------------------------------------------------------------------------
1127// Standard macros for ease of use
1128//---------------------------------------------------------------------------
1129#define SAFE_RELEASE(x) { if (x) x->Release(); x = NULL; }
1a680109 1130
ff4aedc5
RN
1131//---------------------------------------------------------------------------
1132// wxAMMediaBackend Constructor
1133//
1134// Sets m_hNotifyWnd to NULL to signify that we haven't loaded anything yet
226ec5a7 1135//---------------------------------------------------------------------------
ff4aedc5 1136wxAMMediaBackend::wxAMMediaBackend() : m_hNotifyWnd(NULL)
1a680109 1137{
1a680109
RN
1138}
1139
ff4aedc5
RN
1140//---------------------------------------------------------------------------
1141// wxAMMediaBackend Destructor
1142//
226ec5a7
WS
1143// Cleans up everything
1144//---------------------------------------------------------------------------
ff4aedc5 1145wxAMMediaBackend::~wxAMMediaBackend()
1a680109 1146{
ff4aedc5
RN
1147 if (m_hNotifyWnd)
1148 Cleanup();
1a680109
RN
1149}
1150
1a680109 1151//---------------------------------------------------------------------------
ff4aedc5 1152// wxAMMediaBackend::CreateControl
1a680109 1153//
ff4aedc5 1154// ActiveMovie does not really have any native control to speak of,
e163773d 1155// so we just create a normal control.
1a680109 1156//
ff4aedc5 1157// We also check to see if ActiveMovie is installed
226ec5a7
WS
1158//---------------------------------------------------------------------------
1159bool wxAMMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent,
ff4aedc5 1160 wxWindowID id,
226ec5a7 1161 const wxPoint& pos,
ff4aedc5 1162 const wxSize& size,
226ec5a7 1163 long style,
ff4aedc5
RN
1164 const wxValidator& validator,
1165 const wxString& name)
226ec5a7 1166{
a2a444e3
RN
1167 //create our filter graph - the beuty of COM is that it loads
1168 //quartz.dll for us :)
1169 HRESULT hr = CoCreateInstance(CLSID_FilgraphManager, NULL, CLSCTX_INPROC_SERVER,
1170 IID_IMediaControl, (void**)&m_pMC);
1a680109
RN
1171
1172 //directshow not installed?
1173 if ( FAILED(hr) )
1174 return false;
1175
ff4aedc5 1176 //release the filter graph - we don't need it yet
a2a444e3
RN
1177 m_pMC->Release();
1178 m_pMC = NULL;
ff4aedc5
RN
1179
1180 //
1181 // Create window
1182 // By default wxWindow(s) is created with a border -
1183 // so we need to get rid of those, and create with
1184 // wxCLIP_CHILDREN, so that if the driver/backend
1185 // is a child window, it refereshes properly
1186 //
1187 if ( !ctrl->wxControl::Create(parent, id, pos, size,
11085e4b 1188 (style & ~wxBORDER_MASK) | wxBORDER_NONE | wxCLIP_CHILDREN,
ff4aedc5
RN
1189 validator, name) )
1190 return false;
1a680109 1191
ff4aedc5 1192 m_ctrl = ctrl;
1a680109
RN
1193 return true;
1194}
1195
1a680109 1196
ff4aedc5
RN
1197//---------------------------------------------------------------------------
1198// wxAMMediaBackend::Load (file version)
1199//
1200// Creates an Active Movie filter graph from a file or url
226ec5a7 1201//---------------------------------------------------------------------------
ff4aedc5 1202bool wxAMMediaBackend::Load(const wxString& fileName)
1a680109 1203{
a2a444e3 1204 //if previously loaded cleanup
ff4aedc5 1205 if(m_hNotifyWnd)
72259e00
RL
1206 Cleanup();
1207
a2a444e3
RN
1208 //We already checked for success in CreateControl
1209 CoCreateInstance(CLSID_FilgraphManager, NULL, CLSCTX_INPROC_SERVER,
1210 IID_IMediaControl, (void**)&m_pMC);
1a680109 1211
72259e00 1212 //load the graph & render
a2a444e3 1213 if( FAILED(m_pMC->RenderFile(wxBasicString(fileName).Get())) )
1a680109
RN
1214 return false;
1215
1216 //get the interfaces, all of them
a2a444e3
RN
1217 wxAMVERIFY( m_pMC->QueryInterface(IID_IMediaEventEx, (void**)&m_pME) );
1218 wxAMVERIFY( m_pMC->QueryInterface(IID_IMediaPosition, (void**)&m_pMS) );
1219 wxAMVERIFY( m_pMC->QueryInterface(IID_IVideoWindow, (void**)&m_pVW) );
1220 wxAMVERIFY( m_pMC->QueryInterface(IID_IBasicAudio, (void**)&m_pBA) );
1221 wxAMVERIFY( m_pMC->QueryInterface(IID_IBasicVideo, (void**)&m_pBV) );
ff4aedc5 1222
226ec5a7 1223 //We could tell if the media has audio or not by
ff4aedc5
RN
1224 //something like
1225 //-----
1a680109 1226 //long lVolume;
ff4aedc5
RN
1227 //pBA->get_Volume(&lVolume) == E_NOTIMPL
1228 //-----
1229 //here...
1230
1231 //
1232 //Obtain the _actual_ size of the movie & remember it
1233 //
226ec5a7 1234 long nX,
ff4aedc5
RN
1235 nY;
1236
1237 m_bestSize.x = m_bestSize.y = 0;
1238
226ec5a7 1239 m_bVideo = SUCCEEDED( m_pVW->GetWindowPosition( &nX,
ff4aedc5
RN
1240 &nY,
1241 (long*)&m_bestSize.x,
1242 (long*)&m_bestSize.y) );
1243
1244 //
1245 //If we have video in the media - set it up so that
1246 //its a child window of the control, its visible,
1247 //and that the control is the owner of the video window
1248 //
1249 if (m_bVideo)
1a680109 1250 {
a2a444e3 1251 wxAMVERIFY( m_pVW->put_Owner((LONG_PTR)m_ctrl->GetHandle()) );
ff4aedc5 1252 wxAMVERIFY( m_pVW->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS) );
a2a444e3 1253 wxAMVERIFY( m_pVW->put_Visible(-1) ); //OATRUE == -1
1a680109
RN
1254 }
1255
ff4aedc5
RN
1256 //
1257 // Create a hidden window and register to handle
1258 // directshow events for this graph
226ec5a7 1259 // Note that wxCanvasClassName is already registered
ff4aedc5 1260 // and used by all wxWindows and normal wxControls
226ec5a7 1261 //
ff4aedc5
RN
1262 m_hNotifyWnd = ::CreateWindow
1263 (
1264 wxCanvasClassName,
1265 NULL,
1266 0, 0, 0, 0,
1267 0,
1268 (HWND) NULL,
1269 (HMENU)NULL,
1270 wxGetInstance(),
1271 (LPVOID) NULL
1272 );
1273
1274 if(!m_hNotifyWnd)
1a680109 1275 {
ff4aedc5
RN
1276 wxLogSysError( wxT("Could not create hidden needed for ")
1277 wxT("registering for DirectShow events!") );
1a680109 1278
ff4aedc5
RN
1279 return false;
1280 }
226ec5a7 1281
1146983c
JS
1282 wxSetWindowProc(m_hNotifyWnd, wxAMMediaBackend::NotifyWndProc);
1283 wxSetWindowUserData(m_hNotifyWnd, (void*)this);
1a680109 1284
1a680109 1285
a2a444e3 1286 wxAMVERIFY( m_pME->SetNotifyWindow((LONG_PTR)m_hNotifyWnd,
ff4aedc5 1287 WM_GRAPHNOTIFY, 0) );
3f9a3bf9 1288
ff4aedc5
RN
1289 //
1290 // Force the parent window of this control to recalculate
1291 // the size of this if sizers are being used
1292 // and render the results immediately
1293 //
3f9a3bf9
RN
1294 m_ctrl->InvalidateBestSize();
1295 m_ctrl->GetParent()->Layout();
1a680109
RN
1296 m_ctrl->GetParent()->Refresh();
1297 m_ctrl->GetParent()->Update();
7c4a4505 1298 m_ctrl->SetSize(m_ctrl->GetSize());
1a680109 1299
1a680109
RN
1300 return true;
1301}
1302
ff4aedc5
RN
1303//---------------------------------------------------------------------------
1304// wxAMMediaBackend::Load (URL Version)
1305//
1306// Loads media from a URL. Interestingly enough DirectShow
1307// appears (?) to escape the URL for us, at least on normal
1308// files
226ec5a7 1309//---------------------------------------------------------------------------
ff4aedc5 1310bool wxAMMediaBackend::Load(const wxURI& location)
1a680109
RN
1311{
1312 return Load(location.BuildUnescapedURI());
1313}
1314
ff4aedc5
RN
1315//---------------------------------------------------------------------------
1316// wxAMMediaBackend::Play
1317//
1318// Plays the stream. If it is non-seekable, it will restart it.
226ec5a7 1319//---------------------------------------------------------------------------
ff4aedc5 1320bool wxAMMediaBackend::Play()
1a680109
RN
1321{
1322 return SUCCEEDED( m_pMC->Run() );
1323}
1324
ff4aedc5
RN
1325//---------------------------------------------------------------------------
1326// wxAMMediaBackend::Pause
1327//
1328// Pauses the stream.
226ec5a7 1329//---------------------------------------------------------------------------
ff4aedc5 1330bool wxAMMediaBackend::Pause()
1a680109
RN
1331{
1332 return SUCCEEDED( m_pMC->Pause() );
1333}
1334
ff4aedc5
RN
1335//---------------------------------------------------------------------------
1336// wxAMMediaBackend::Stop
1337//
1338// Stops the stream.
226ec5a7 1339//---------------------------------------------------------------------------
ff4aedc5 1340bool wxAMMediaBackend::Stop()
1a680109 1341{
e4b12a53
RN
1342 bool bOK = SUCCEEDED( m_pMC->Stop() );
1343
1344 //We don't care if it can't get to the beginning in directshow -
1345 //it could be a non-seeking filter (wince midi) in which case playing
1346 //starts all over again
1347 SetPosition(0);
1348 return bOK;
1a680109
RN
1349}
1350
ff4aedc5
RN
1351//---------------------------------------------------------------------------
1352// wxAMMediaBackend::SetPosition
1353//
226ec5a7 1354// 1) Translates the current position's time to directshow time,
a2a444e3 1355// which is in a scale of 1 second (in a double)
ff4aedc5
RN
1356// 2) Sets the play position of the IMediaSeeking interface -
1357// passing NULL as the stop position means to keep the old
1358// stop position
226ec5a7 1359//---------------------------------------------------------------------------
ff4aedc5 1360bool wxAMMediaBackend::SetPosition(wxLongLong where)
1a680109 1361{
a2a444e3
RN
1362 return SUCCEEDED( m_pMS->put_CurrentPosition(
1363 ((LONGLONG)where.GetValue()) / 1000
1364 )
1365 );
1a680109
RN
1366}
1367
ff4aedc5
RN
1368//---------------------------------------------------------------------------
1369// wxAMMediaBackend::GetPosition
1370//
1371// 1) Obtains the current play and stop positions from IMediaSeeking
1372// 2) Returns the play position translated to our time base
226ec5a7 1373//---------------------------------------------------------------------------
ff4aedc5 1374wxLongLong wxAMMediaBackend::GetPosition()
1a680109 1375{
a2a444e3
RN
1376 double outCur;
1377 wxAMVERIFY( m_pMS->get_CurrentPosition(&outCur) );
1a680109 1378
a2a444e3
RN
1379 //h,m,s,milli - outdur is in 1 second (double)
1380 return (outCur*1000);
1a680109
RN
1381}
1382
6f8c67e7
JS
1383//---------------------------------------------------------------------------
1384// wxAMMediaBackend::SetVolume
1385//
1386// Sets the volume through the IBasicAudio interface -
1387// value ranges from 0 (MAX volume) to -10000 (minimum volume).
1388// -100 per decibel.
1389//---------------------------------------------------------------------------
1390bool wxAMMediaBackend::SetVolume(double dVolume)
1391{
1392 return SUCCEEDED(m_pBA->put_Volume( (long) ((dVolume-1.0) * 10000.0) ));
1393}
1394
1395//---------------------------------------------------------------------------
1396// wxAMMediaBackend::GetVolume
1397//
1398// Gets the volume through the IBasicAudio interface -
1399// value ranges from 0 (MAX volume) to -10000 (minimum volume).
1400// -100 per decibel.
1401//---------------------------------------------------------------------------
1402double wxAMMediaBackend::GetVolume()
1403{
1404 long lVolume;
1405 if ( SUCCEEDED(m_pBA->get_Volume(&lVolume)) )
1406 return (((double)(lVolume + 10000)) / 10000.0);
1407 return 0.0;
1408}
1409
ff4aedc5
RN
1410//---------------------------------------------------------------------------
1411// wxAMMediaBackend::GetDuration
1412//
1413// 1) Obtains the duration of the media from the IMediaSeeking interface
1414// 2) Converts that value to our time base, and returns it
226ec5a7 1415//---------------------------------------------------------------------------
ff4aedc5 1416wxLongLong wxAMMediaBackend::GetDuration()
1a680109 1417{
a2a444e3
RN
1418 double outDuration;
1419 wxAMVERIFY( m_pMS->get_Duration(&outDuration) );
1a680109 1420
a2a444e3
RN
1421 //h,m,s,milli - outdur is in 1 second (double)
1422 return (outDuration*1000);
1a680109
RN
1423}
1424
ff4aedc5
RN
1425//---------------------------------------------------------------------------
1426// wxAMMediaBackend::GetState
1427//
1428// Obtains the state from the IMediaControl interface.
1429// Note that it's enumeration values for stopping/playing
1430// etc. are the same as ours, so we just do a straight cast.
226ec5a7 1431// TODO: MS recommends against INFINITE here for
ff4aedc5 1432// IMediaControl::GetState- do it in stages
226ec5a7 1433//---------------------------------------------------------------------------
ff4aedc5 1434wxMediaState wxAMMediaBackend::GetState()
1a680109 1435{
1a680109 1436 HRESULT hr;
a2a444e3 1437 long theState; //OAFilterState
1a680109 1438 hr = m_pMC->GetState(INFINITE, &theState);
72259e00 1439
1a680109
RN
1440 wxASSERT( SUCCEEDED(hr) );
1441
1442 //MSW state is the same as ours
1443 //State_Stopped = 0,
1444 //State_Paused = State_Stopped + 1,
1445 //State_Running = State_Paused + 1
1446
1447 return (wxMediaState) theState;
1448}
1449
ff4aedc5
RN
1450//---------------------------------------------------------------------------
1451// wxAMMediaBackend::GetPlaybackRate
1452//
1453// Pretty simple way of obtaining the playback rate from
1454// the IMediaSeeking interface
226ec5a7 1455//---------------------------------------------------------------------------
ff4aedc5 1456double wxAMMediaBackend::GetPlaybackRate()
1a680109
RN
1457{
1458 double dRate;
a2a444e3 1459 wxAMVERIFY( m_pMS->get_Rate(&dRate) );
1a680109
RN
1460 return dRate;
1461}
1462
ff4aedc5
RN
1463//---------------------------------------------------------------------------
1464// wxAMMediaBackend::SetPlaybackRate
1465//
1466// Sets the playback rate of the media - DirectShow is pretty good
1467// about this, actually
226ec5a7 1468//---------------------------------------------------------------------------
ff4aedc5 1469bool wxAMMediaBackend::SetPlaybackRate(double dRate)
1a680109 1470{
a2a444e3 1471 return SUCCEEDED( m_pMS->put_Rate(dRate) );
1a680109
RN
1472}
1473
ff4aedc5
RN
1474//---------------------------------------------------------------------------
1475// wxAMMediaBackend::NotifyWndProc
1476//
226ec5a7 1477// Here we check to see if DirectShow tells us we've reached the stop
ff4aedc5
RN
1478// position in our stream - if it has, it may not actually stop
1479// the stream - which we need to do...
226ec5a7
WS
1480//---------------------------------------------------------------------------
1481LRESULT CALLBACK wxAMMediaBackend::NotifyWndProc(HWND hWnd, UINT nMsg,
1482 WPARAM wParam,
ff4aedc5
RN
1483 LPARAM lParam)
1484{
1485 wxAMMediaBackend* backend = (wxAMMediaBackend*)
1486 ::GetWindowLong(hWnd, GWL_USERDATA);
1487
1488 return backend->OnNotifyWndProc(hWnd, nMsg, wParam, lParam);
1489}
1490
226ec5a7
WS
1491LRESULT CALLBACK wxAMMediaBackend::OnNotifyWndProc(HWND hWnd, UINT nMsg,
1492 WPARAM wParam,
ff4aedc5 1493 LPARAM lParam)
1a680109
RN
1494{
1495 if (nMsg == WM_GRAPHNOTIFY)
1496 {
226ec5a7
WS
1497 LONG evCode,
1498 evParam1,
ff4aedc5
RN
1499 evParam2;
1500
1501 //
1502 // DirectShow keeps a list of queued events, and we need
1503 // to go through them one by one, stopping at (Hopefully only one)
1504 // EC_COMPLETE message
1505 //
1a680109 1506 while(SUCCEEDED(m_pME->GetEvent(&evCode, (LONG_PTR *) &evParam1,
72259e00
RL
1507 (LONG_PTR *) &evParam2, 0)
1508 )
1a680109
RN
1509 )
1510 {
ff4aedc5
RN
1511 // Cleanup memory that GetEvent allocated
1512 wxAMVERIFY( m_pME->FreeEventParams(evCode, evParam1, evParam2) );
1a680109
RN
1513
1514 // If this is the end of the clip, notify handler
a2a444e3 1515 if(1 == evCode) //EC_COMPLETE
1a680109 1516 {
ff4aedc5
RN
1517 //send the event to our child
1518 wxMediaEvent theEvent(wxEVT_MEDIA_STOP, m_ctrl->GetId());
1519 m_ctrl->ProcessEvent(theEvent);
1520
1521 //if the user didn't veto it, stop the stream
1522 if (theEvent.IsAllowed())
1523 {
1524 //Interestingly enough, DirectShow does not actually stop
1525 //the filters - even when it reaches the end!
1526 wxVERIFY( Stop() );
226ec5a7 1527
ff4aedc5 1528 //send the event to our child
226ec5a7 1529 wxMediaEvent theEvent(wxEVT_MEDIA_FINISHED,
ff4aedc5
RN
1530 m_ctrl->GetId());
1531 m_ctrl->ProcessEvent(theEvent);
1532 }
1a680109 1533 }
72259e00 1534 }
1a680109 1535 }
ff4aedc5 1536 return DefWindowProc(hWnd, nMsg, wParam, lParam);
1a680109
RN
1537}
1538
ff4aedc5
RN
1539//---------------------------------------------------------------------------
1540// wxAMMediaBackend::Cleanup
1541//
226ec5a7 1542// 1) Hide/disowns the video window (MS says bad things will happen if
ff4aedc5
RN
1543// you don't)
1544// 2) Releases all the directshow interfaces we use
a2a444e3 1545// TODO: Maybe there's a way to redirect the IMediaControl each time
ff4aedc5
RN
1546// we load, rather then creating and destroying the interfaces
1547// each time?
226ec5a7 1548//---------------------------------------------------------------------------
ff4aedc5 1549void wxAMMediaBackend::Cleanup()
1a680109
RN
1550{
1551 // Hide then disown the window
1552 if(m_pVW)
1553 {
a2a444e3 1554 m_pVW->put_Visible(0); //OSFALSE == 0
1a680109
RN
1555 m_pVW->put_Owner(NULL);
1556 }
1557
1558 // Release and zero DirectShow interfaces
1559 SAFE_RELEASE(m_pME);
1560 SAFE_RELEASE(m_pMS);
1a680109
RN
1561 SAFE_RELEASE(m_pBA);
1562 SAFE_RELEASE(m_pBV);
1563 SAFE_RELEASE(m_pVW);
a2a444e3 1564 SAFE_RELEASE(m_pMC);
226ec5a7 1565
ff4aedc5
RN
1566 // Get rid of our hidden Window
1567 DestroyWindow(m_hNotifyWnd);
1568 m_hNotifyWnd = NULL;
1a680109
RN
1569}
1570
ff4aedc5
RN
1571
1572//---------------------------------------------------------------------------
1573// wxAMMediaBackend::GetVideoSize
1574//
1575// Obtains the cached original video size
226ec5a7 1576//---------------------------------------------------------------------------
ff4aedc5 1577wxSize wxAMMediaBackend::GetVideoSize() const
1a680109
RN
1578{
1579 return m_bestSize;
1580}
1581
ff4aedc5
RN
1582//---------------------------------------------------------------------------
1583// wxAMMediaBackend::Move
1584//
1585// Resizes the IVideoWindow to the size of the control window
226ec5a7 1586//---------------------------------------------------------------------------
a2a444e3 1587void wxAMMediaBackend::Move(int WXUNUSED(x), int WXUNUSED(y), int w, int h)
1a680109 1588{
ff4aedc5 1589 if(m_hNotifyWnd && m_bVideo)
1a680109 1590 {
ff4aedc5 1591 wxAMVERIFY( m_pVW->SetWindowPosition(0, 0, w, h) );
1a680109
RN
1592 }
1593}
1594
ff4aedc5
RN
1595//---------------------------------------------------------------------------
1596// End of wxAMMediaBackend
1597//---------------------------------------------------------------------------
1a680109 1598
ff4aedc5 1599//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1a680109 1600//
ff4aedc5 1601// wxMCIMediaBackend
226ec5a7 1602//
ff4aedc5
RN
1603//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1604
1605
1606IMPLEMENT_DYNAMIC_CLASS(wxMCIMediaBackend, wxMediaBackend);
1607
1608//---------------------------------------------------------------------------
1609// Usual debugging macros for MCI returns
1a680109
RN
1610//---------------------------------------------------------------------------
1611
ff4aedc5
RN
1612#ifdef __WXDEBUG__
1613#define wxMCIVERIFY(arg) \
1614{ \
1615 DWORD nRet; \
1616 if ( (nRet = (arg)) != 0) \
1617 { \
1618 TCHAR sz[5000]; \
1619 mciGetErrorString(nRet, sz, 5000); \
1620 wxFAIL_MSG(wxString::Format(_T("MCI Error:%s"), sz)); \
1621 } \
1622}
1623#else
1624#define wxMCIVERIFY(arg) (arg);
1625#endif
1626
1627//---------------------------------------------------------------------------
1628// Simulation for <digitalv.h>
33d8e2fc 1629//
ff4aedc5 1630// Mingw and possibly other compilers don't have the digitalv.h header
226ec5a7 1631// that is needed to have some essential features of mci work with
ff4aedc5
RN
1632// windows - so we provide the declarations for the types we use here
1633//---------------------------------------------------------------------------
33d8e2fc
RN
1634
1635typedef struct {
1636 DWORD_PTR dwCallback;
1637#ifdef MCI_USE_OFFEXT
1638 POINT ptOffset;
1639 POINT ptExtent;
226ec5a7 1640#else
33d8e2fc
RN
1641 RECT rc;
1642#endif
1643} MCI_DGV_RECT_PARMS;
1644
1645typedef struct {
1646 DWORD_PTR dwCallback;
1647 HWND hWnd;
1648#ifndef _WIN32
1649 WORD wReserved1;
1650#endif
1651 UINT nCmdShow;
1652#ifndef _WIN32
1653 WORD wReserved2;
1654#endif
ff4aedc5
RN
1655 wxChar* lpstrText;
1656} MCI_DGV_WINDOW_PARMS;
33d8e2fc
RN
1657
1658typedef struct {
226ec5a7
WS
1659 DWORD_PTR dwCallback;
1660 DWORD dwTimeFormat;
1661 DWORD dwAudio;
1662 DWORD dwFileFormat;
1663 DWORD dwSpeed;
1664} MCI_DGV_SET_PARMS;
33d8e2fc 1665
6f8c67e7
JS
1666typedef struct {
1667 DWORD_PTR dwCallback;
1668 DWORD dwItem;
1669 DWORD dwValue;
1670 DWORD dwOver;
1671 wxChar* lpstrAlgorithm;
1672 wxChar* lpstrQuality;
1673} MCI_DGV_SETAUDIO_PARMS;
1674
ff4aedc5
RN
1675//---------------------------------------------------------------------------
1676// wxMCIMediaBackend Constructor
1677//
1678// Here we don't need to do much except say we don't have any video :)
1679//---------------------------------------------------------------------------
1680wxMCIMediaBackend::wxMCIMediaBackend() : m_hNotifyWnd(NULL), m_bVideo(false)
1681{
3f9a3bf9
RN
1682}
1683
ff4aedc5
RN
1684//---------------------------------------------------------------------------
1685// wxMCIMediaBackend Destructor
1686//
1687// We close the mci device - note that there may not be an mci device here,
1688// or it may fail - but we don't really care, since we're destructing
1689//---------------------------------------------------------------------------
1690wxMCIMediaBackend::~wxMCIMediaBackend()
3f9a3bf9 1691{
ff4aedc5
RN
1692 if(m_hNotifyWnd)
1693 {
1694 mciSendCommand(m_hDev, MCI_CLOSE, 0, 0);
1695 DestroyWindow(m_hNotifyWnd);
1696 m_hNotifyWnd = NULL;
1697 }
3f9a3bf9
RN
1698}
1699
ff4aedc5
RN
1700//---------------------------------------------------------------------------
1701// wxMCIMediaBackend::Create
1702//
1703// Here we just tell wxMediaCtrl that mci does exist (which it does, on all
1704// msw systems, at least in some form dating back to win16 days)
1705//---------------------------------------------------------------------------
226ec5a7 1706bool wxMCIMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent,
ff4aedc5 1707 wxWindowID id,
226ec5a7 1708 const wxPoint& pos,
ff4aedc5 1709 const wxSize& size,
226ec5a7 1710 long style,
ff4aedc5
RN
1711 const wxValidator& validator,
1712 const wxString& name)
72259e00 1713{
ff4aedc5
RN
1714 //
1715 // Create window
1716 // By default wxWindow(s) is created with a border -
1717 // so we need to get rid of those, and create with
1718 // wxCLIP_CHILDREN, so that if the driver/backend
1719 // is a child window, it refereshes properly
1720 //
1721 if ( !ctrl->wxControl::Create(parent, id, pos, size,
11085e4b 1722 (style & ~wxBORDER_MASK) | wxBORDER_NONE | wxCLIP_CHILDREN,
ff4aedc5
RN
1723 validator, name) )
1724 return false;
1725
3f9a3bf9
RN
1726 m_ctrl = ctrl;
1727 return true;
1728}
1729
ff4aedc5
RN
1730//---------------------------------------------------------------------------
1731// wxMCIMediaBackend::Load (file version)
1732//
1733// Here we have MCI load a file and device, set the time format to our
1734// default (milliseconds), and set the video (if any) to play in the control
1735//---------------------------------------------------------------------------
1736bool wxMCIMediaBackend::Load(const wxString& fileName)
3f9a3bf9 1737{
ff4aedc5
RN
1738 //
1739 //if the user already called load close the previous MCI device
1740 //
1741 if(m_hNotifyWnd)
1742 {
3f9a3bf9 1743 mciSendCommand(m_hDev, MCI_CLOSE, 0, 0);
ff4aedc5
RN
1744 DestroyWindow(m_hNotifyWnd);
1745 m_hNotifyWnd = NULL;
1746 }
3f9a3bf9 1747
ff4aedc5
RN
1748 //
1749 //Opens a file and has MCI select a device. Normally you'd put
1750 //MCI_OPEN_TYPE in addition to MCI_OPEN_ELEMENT - however if you
226ec5a7 1751 //omit this it tells MCI to select the device instead. This is
ff4aedc5
RN
1752 //good because we have no reliable way of "enumerating" the devices
1753 //in MCI
1754 //
3f9a3bf9 1755 MCI_OPEN_PARMS openParms;
3f9a3bf9
RN
1756 openParms.lpstrElementName = (wxChar*) fileName.c_str();
1757
226ec5a7 1758 if ( mciSendCommand(0, MCI_OPEN, MCI_OPEN_ELEMENT,
ff4aedc5
RN
1759 (DWORD)(LPVOID)&openParms) != 0)
1760 return false;
3f9a3bf9
RN
1761
1762 m_hDev = openParms.wDeviceID;
1763
ff4aedc5
RN
1764 //
1765 //Now set the time format for the device to milliseconds
1766 //
1767 MCI_SET_PARMS setParms;
3f9a3bf9
RN
1768 setParms.dwCallback = 0;
1769 setParms.dwTimeFormat = MCI_FORMAT_MILLISECONDS;
1770
1771 if (mciSendCommand(m_hDev, MCI_SET, MCI_SET_TIME_FORMAT,
1772 (DWORD)(LPVOID)&setParms) != 0)
1773 return false;
1774
ff4aedc5
RN
1775 //
1776 //Now tell the MCI device to display the video in our wxMediaCtrl
1777 //
3f9a3bf9 1778 MCI_DGV_WINDOW_PARMS windowParms;
5987f174 1779 windowParms.hWnd = (HWND)m_ctrl->GetHandle();
3f9a3bf9 1780
226ec5a7 1781 m_bVideo = (mciSendCommand(m_hDev, MCI_WINDOW,
ff4aedc5
RN
1782 0x00010000L, //MCI_DGV_WINDOW_HWND
1783 (DWORD)(LPVOID)&windowParms) == 0);
1784
1785 //
1786 // Create a hidden window and register to handle
1787 // MCI events
226ec5a7 1788 // Note that wxCanvasClassName is already registered
ff4aedc5 1789 // and used by all wxWindows and normal wxControls
226ec5a7 1790 //
ff4aedc5
RN
1791 m_hNotifyWnd = ::CreateWindow
1792 (
1793 wxCanvasClassName,
1794 NULL,
1795 0, 0, 0, 0,
1796 0,
1797 (HWND) NULL,
1798 (HMENU)NULL,
1799 wxGetInstance(),
1800 (LPVOID) NULL
1801 );
1802
1803 if(!m_hNotifyWnd)
1804 {
1805 wxLogSysError( wxT("Could not create hidden needed for ")
1806 wxT("registering for DirectShow events!") );
1807
1808 return false;
1809 }
226ec5a7 1810
1146983c 1811 wxSetWindowProc(m_hNotifyWnd, wxMCIMediaBackend::NotifyWndProc);
ff4aedc5
RN
1812
1813 ::SetWindowLong(m_hNotifyWnd, GWL_USERDATA,
1814 (LONG) this);
1815
1816 //
1817 //Here, if the parent of the control has a sizer - we
1818 //tell it to recalculate the size of this control since
1819 //the user opened a seperate media file
1820 //
5987f174
RN
1821 m_ctrl->InvalidateBestSize();
1822 m_ctrl->GetParent()->Layout();
1823 m_ctrl->GetParent()->Refresh();
1824 m_ctrl->GetParent()->Update();
7c4a4505 1825 m_ctrl->SetSize(m_ctrl->GetSize());
72259e00 1826
3f9a3bf9
RN
1827 return true;
1828}
1829
ff4aedc5
RN
1830//---------------------------------------------------------------------------
1831// wxMCIMediaBackend::Load (URL version)
1832//
1833// MCI doesn't support URLs directly (?)
1834//
1835// TODO: Use wxURL/wxFileSystem and mmioInstallProc
1836//---------------------------------------------------------------------------
1837bool wxMCIMediaBackend::Load(const wxURI& WXUNUSED(location))
3f9a3bf9
RN
1838{
1839 return false;
1840}
1841
ff4aedc5
RN
1842//---------------------------------------------------------------------------
1843// wxMCIMediaBackend::Play
1844//
1845// Plays/Resumes the MCI device... a couple notes:
1846// 1) Certain drivers will crash and burn if we don't pass them an
1847// MCI_PLAY_PARMS, despite the documentation that says otherwise...
1848// 2) There is a MCI_RESUME command, but MCI_PLAY does the same thing
226ec5a7 1849// and will resume from a stopped state also, so there's no need to
ff4aedc5
RN
1850// call both, for example
1851//---------------------------------------------------------------------------
1852bool wxMCIMediaBackend::Play()
5987f174 1853{
5987f174 1854 MCI_PLAY_PARMS playParms;
ff4aedc5
RN
1855 playParms.dwCallback = (DWORD)m_hNotifyWnd;
1856
11219c9e 1857 bool bOK = ( mciSendCommand(m_hDev, MCI_PLAY, MCI_NOTIFY,
ff4aedc5 1858 (DWORD)(LPVOID)&playParms) == 0 );
11219c9e
RN
1859
1860 if(bOK)
1861 m_ctrl->Show(m_bVideo);
1862
1863 return bOK;
5987f174
RN
1864}
1865
ff4aedc5
RN
1866//---------------------------------------------------------------------------
1867// wxMCIMediaBackend::Pause
1868//
1869// Pauses the MCI device - nothing special
226ec5a7 1870//---------------------------------------------------------------------------
ff4aedc5 1871bool wxMCIMediaBackend::Pause()
5987f174
RN
1872{
1873 return (mciSendCommand(m_hDev, MCI_PAUSE, MCI_WAIT, 0) == 0);
1874}
1875
ff4aedc5
RN
1876//---------------------------------------------------------------------------
1877// wxMCIMediaBackend::Stop
1878//
1879// Stops the MCI device & seeks to the beginning as wxMediaCtrl docs outline
226ec5a7 1880//---------------------------------------------------------------------------
ff4aedc5 1881bool wxMCIMediaBackend::Stop()
5987f174
RN
1882{
1883 return (mciSendCommand(m_hDev, MCI_STOP, MCI_WAIT, 0) == 0) &&
1884 (mciSendCommand(m_hDev, MCI_SEEK, MCI_SEEK_TO_START, 0) == 0);
1885}
1886
ff4aedc5
RN
1887//---------------------------------------------------------------------------
1888// wxMCIMediaBackend::GetState
1889//
1890// Here we get the state and convert it to a wxMediaState -
1891// since we use direct comparisons with MCI_MODE_PLAY and
1892// MCI_MODE_PAUSE, we don't care if the MCI_STATUS call
1893// fails or not
226ec5a7 1894//---------------------------------------------------------------------------
ff4aedc5 1895wxMediaState wxMCIMediaBackend::GetState()
3f9a3bf9
RN
1896{
1897 MCI_STATUS_PARMS statusParms;
1898 statusParms.dwItem = MCI_STATUS_MODE;
ff4aedc5 1899
3f9a3bf9
RN
1900 mciSendCommand(m_hDev, MCI_STATUS, MCI_STATUS_ITEM,
1901 (DWORD)(LPVOID)&statusParms);
1902
1903 if(statusParms.dwReturn == MCI_MODE_PAUSE)
1904 return wxMEDIASTATE_PAUSED;
1905 else if(statusParms.dwReturn == MCI_MODE_PLAY)
1906 return wxMEDIASTATE_PLAYING;
1907 else
1908 return wxMEDIASTATE_STOPPED;
1909}
1910
ff4aedc5
RN
1911//---------------------------------------------------------------------------
1912// wxMCIMediaBackend::SetPosition
1913//
1914// Here we set the position of the device in the stream.
226ec5a7 1915// Note that MCI actually stops the device after you seek it if the
ff4aedc5 1916// device is playing/paused, so we need to play the file after
226ec5a7
WS
1917// MCI seeks like normal APIs would
1918//---------------------------------------------------------------------------
ff4aedc5 1919bool wxMCIMediaBackend::SetPosition(wxLongLong where)
3f9a3bf9
RN
1920{
1921 MCI_SEEK_PARMS seekParms;
1922 seekParms.dwCallback = 0;
e70fda0e 1923#if wxUSE_LONGLONG_NATIVE && !wxUSE_LONGLONG_WX
226ec5a7 1924 seekParms.dwTo = (DWORD)where.GetValue();
e70fda0e
WS
1925#else /* wxUSE_LONGLONG_WX */
1926 /* no way to return it in one piece */
1927 wxASSERT( where.GetHi()==0 );
1928 seekParms.dwTo = (DWORD)where.GetLo();
1929#endif /* wxUSE_LONGLONG_* */
3f9a3bf9 1930
ff4aedc5 1931 //device was playing?
3f9a3bf9
RN
1932 bool bReplay = GetState() == wxMEDIASTATE_PLAYING;
1933
226ec5a7 1934 if( mciSendCommand(m_hDev, MCI_SEEK, MCI_TO,
ff4aedc5 1935 (DWORD)(LPVOID)&seekParms) != 0)
3f9a3bf9 1936 return false;
3f9a3bf9 1937
ff4aedc5 1938 //If the device was playing, resume it
3f9a3bf9
RN
1939 if (bReplay)
1940 return Play();
1941 else
1942 return true;
1943}
1944
ff4aedc5
RN
1945//---------------------------------------------------------------------------
1946// wxMCIMediaBackend::GetPosition
1947//
1948// Gets the position of the device in the stream using the current
1949// time format... nothing special here...
226ec5a7 1950//---------------------------------------------------------------------------
ff4aedc5 1951wxLongLong wxMCIMediaBackend::GetPosition()
3f9a3bf9
RN
1952{
1953 MCI_STATUS_PARMS statusParms;
72259e00 1954 statusParms.dwItem = MCI_STATUS_POSITION;
ff4aedc5 1955
72259e00 1956 if (mciSendCommand(m_hDev, MCI_STATUS, MCI_STATUS_ITEM,
ff4aedc5 1957 (DWORD)(LPSTR)&statusParms) != 0)
3f9a3bf9
RN
1958 return 0;
1959
1960 return statusParms.dwReturn;
1961}
1962
6f8c67e7
JS
1963//---------------------------------------------------------------------------
1964// wxMCIMediaBackend::GetVolume
1965//
1966// Gets the volume of the current media via the MCI_DGV_STATUS_VOLUME
1967// message. Value ranges from 0 (minimum) to 1000 (maximum volume).
1968//---------------------------------------------------------------------------
1969double wxMCIMediaBackend::GetVolume()
1970{
1971 MCI_STATUS_PARMS statusParms;
1972 statusParms.dwCallback = NULL;
1973 statusParms.dwItem = 0x4019; //MCI_DGV_STATUS_VOLUME
1974
1975 if (mciSendCommand(m_hDev, MCI_STATUS, MCI_STATUS_ITEM,
1976 (DWORD)(LPSTR)&statusParms) != 0)
1977 return 0;
1978
1979 return ((double)statusParms.dwReturn) / 1000.0;
1980}
1981
1982//---------------------------------------------------------------------------
1983// wxMCIMediaBackend::SetVolume
1984//
1985// Sets the volume of the current media via the MCI_DGV_SETAUDIO_VOLUME
1986// message. Value ranges from 0 (minimum) to 1000 (maximum volume).
1987//---------------------------------------------------------------------------
1988bool wxMCIMediaBackend::SetVolume(double dVolume)
1989{
1990 MCI_DGV_SETAUDIO_PARMS audioParms;
1991 audioParms.dwCallback = NULL;
1992 audioParms.dwItem = 0x4002; //MCI_DGV_SETAUDIO_VOLUME
1993 audioParms.dwValue = (DWORD) (dVolume * 1000.0);
1994 audioParms.dwOver = 0;
1995 audioParms.lpstrAlgorithm = NULL;
1996 audioParms.lpstrQuality = NULL;
1997
1998 if (mciSendCommand(m_hDev, 0x0873, //MCI_SETAUDIO
1999 0x00800000L | 0x01000000L, //MCI_DGV_SETAUDIO+(_ITEM | _VALUE)
2000 (DWORD)(LPSTR)&audioParms) != 0)
2001 return false;
2002 return true;
2003}
2004
ff4aedc5
RN
2005//---------------------------------------------------------------------------
2006// wxMCIMediaBackend::GetDuration
2007//
2008// Gets the duration of the stream... nothing special
226ec5a7 2009//---------------------------------------------------------------------------
ff4aedc5 2010wxLongLong wxMCIMediaBackend::GetDuration()
3f9a3bf9
RN
2011{
2012 MCI_STATUS_PARMS statusParms;
72259e00 2013 statusParms.dwItem = MCI_STATUS_LENGTH;
ff4aedc5 2014
72259e00 2015 if (mciSendCommand(m_hDev, MCI_STATUS, MCI_STATUS_ITEM,
ff4aedc5 2016 (DWORD)(LPSTR)&statusParms) != 0)
3f9a3bf9
RN
2017 return 0;
2018
2019 return statusParms.dwReturn;
2020}
2021
ff4aedc5
RN
2022//---------------------------------------------------------------------------
2023// wxMCIMediaBackend::Move
2024//
2025// Moves the window to a location
226ec5a7
WS
2026//---------------------------------------------------------------------------
2027void wxMCIMediaBackend::Move(int WXUNUSED(x), int WXUNUSED(y),
ff4aedc5 2028 int w, int h)
3f9a3bf9 2029{
ff4aedc5
RN
2030 if (m_hNotifyWnd && m_bVideo)
2031 {
2032 MCI_DGV_RECT_PARMS putParms; //ifdefed MCI_DGV_PUT_PARMS
7c4a4505 2033 memset(&putParms, 0, sizeof(MCI_DGV_RECT_PARMS));
ff4aedc5 2034 putParms.rc.bottom = h;
7c4a4505
JS
2035 putParms.rc.right = w;
2036
2037 //wxStackWalker will crash and burn here on assert
2038 //and mci doesn't like 0 and 0 for some reason (out of range )
2039 //so just don't it in that case
2040 if(w || h)
2041 {
2042 wxMCIVERIFY( mciSendCommand(m_hDev, MCI_PUT,
ff4aedc5
RN
2043 0x00040000L, //MCI_DGV_PUT_DESTINATION
2044 (DWORD)(LPSTR)&putParms) );
7c4a4505 2045 }
ff4aedc5 2046 }
3f9a3bf9
RN
2047}
2048
ff4aedc5
RN
2049//---------------------------------------------------------------------------
2050// wxMCIMediaBackend::GetVideoSize
2051//
2052// Gets the original size of the movie for sizers
226ec5a7 2053//---------------------------------------------------------------------------
ff4aedc5 2054wxSize wxMCIMediaBackend::GetVideoSize() const
3f9a3bf9
RN
2055{
2056 if(m_bVideo)
2057 {
ff4aedc5 2058 MCI_DGV_RECT_PARMS whereParms; //ifdefed MCI_DGV_WHERE_PARMS
3f9a3bf9 2059
226ec5a7 2060 wxMCIVERIFY( mciSendCommand(m_hDev, MCI_WHERE,
ff4aedc5
RN
2061 0x00020000L, //MCI_DGV_WHERE_SOURCE
2062 (DWORD)(LPSTR)&whereParms) );
226ec5a7 2063
ff4aedc5 2064 return wxSize(whereParms.rc.right, whereParms.rc.bottom);
3f9a3bf9 2065 }
c47addef 2066 return wxSize(0,0);
3f9a3bf9
RN
2067}
2068
ff4aedc5
RN
2069//---------------------------------------------------------------------------
2070// wxMCIMediaBackend::GetPlaybackRate
2071//
2072// TODO
226ec5a7 2073//---------------------------------------------------------------------------
ff4aedc5 2074double wxMCIMediaBackend::GetPlaybackRate()
3f9a3bf9
RN
2075{
2076 return 1.0;
2077}
2078
ff4aedc5
RN
2079//---------------------------------------------------------------------------
2080// wxMCIMediaBackend::SetPlaybackRate
2081//
2082// TODO
226ec5a7 2083//---------------------------------------------------------------------------
ff4aedc5 2084bool wxMCIMediaBackend::SetPlaybackRate(double WXUNUSED(dRate))
3f9a3bf9 2085{
ff4aedc5
RN
2086/*
2087 MCI_WAVE_SET_SAMPLESPERSEC
2088 MCI_DGV_SET_PARMS setParms;
2089 setParms.dwSpeed = (DWORD) (dRate * 1000.0);
2090
226ec5a7 2091 return (mciSendCommand(m_hDev, MCI_SET,
ff4aedc5
RN
2092 0x00020000L, //MCI_DGV_SET_SPEED
2093 (DWORD)(LPSTR)&setParms) == 0);
2094*/
3f9a3bf9
RN
2095 return false;
2096}
2097
ff4aedc5
RN
2098//---------------------------------------------------------------------------
2099// [static] wxMCIMediaBackend::MSWWindowProc
2100//
226ec5a7 2101// Here we process a message when MCI reaches the stopping point
ff4aedc5 2102// in the stream
226ec5a7
WS
2103//---------------------------------------------------------------------------
2104LRESULT CALLBACK wxMCIMediaBackend::NotifyWndProc(HWND hWnd, UINT nMsg,
2105 WPARAM wParam,
ff4aedc5
RN
2106 LPARAM lParam)
2107{
2108 wxMCIMediaBackend* backend = (wxMCIMediaBackend*)
106d80ad 2109#ifdef _WIN32
ff4aedc5 2110 ::GetWindowLong(hWnd, GWL_USERDATA);
106d80ad
JS
2111#else
2112 ::GetWindowLongPtr(hWnd, GWLP_USERDATA);
2113#endif
ff4aedc5
RN
2114 wxASSERT(backend);
2115
2116 return backend->OnNotifyWndProc(hWnd, nMsg, wParam, lParam);
2117}
2118
226ec5a7
WS
2119LRESULT CALLBACK wxMCIMediaBackend::OnNotifyWndProc(HWND hWnd, UINT nMsg,
2120 WPARAM wParam,
ff4aedc5 2121 LPARAM lParam)
3f9a3bf9 2122{
5987f174
RN
2123 if(nMsg == MM_MCINOTIFY)
2124 {
ff4aedc5
RN
2125 wxASSERT(lParam == (LPARAM) m_hDev);
2126 if(wParam == MCI_NOTIFY_SUCCESSFUL && lParam == (LPARAM)m_hDev)
5987f174 2127 {
ff4aedc5
RN
2128 wxMediaEvent theEvent(wxEVT_MEDIA_STOP, m_ctrl->GetId());
2129 m_ctrl->ProcessEvent(theEvent);
2130
2131 if(theEvent.IsAllowed())
2132 {
226ec5a7 2133 wxMCIVERIFY( mciSendCommand(m_hDev, MCI_SEEK,
ff4aedc5 2134 MCI_SEEK_TO_START, 0) );
3f9a3bf9 2135
ff4aedc5 2136 //send the event to our child
226ec5a7 2137 wxMediaEvent theEvent(wxEVT_MEDIA_FINISHED,
ff4aedc5
RN
2138 m_ctrl->GetId());
2139 m_ctrl->ProcessEvent(theEvent);
2140 }
5987f174 2141 }
5987f174 2142 }
ff4aedc5 2143 return DefWindowProc(hWnd, nMsg, wParam, lParam);
3f9a3bf9 2144}
ff4aedc5
RN
2145//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2146//
2147// wxQTMediaBackend
226ec5a7 2148//
ff4aedc5
RN
2149// TODO: Use a less cludgy way to pause/get state/set state
2150// TODO: Dynamically load from qtml.dll
2151//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2152
ff4aedc5
RN
2153IMPLEMENT_DYNAMIC_CLASS(wxQTMediaBackend, wxMediaBackend);
2154
2155//Time between timer calls
2156#define MOVIE_DELAY 100
2157
2158#include "wx/timer.h"
2159
2160// --------------------------------------------------------------------------
2161// wxQTTimer - Handle Asyncronous Playing
2162// --------------------------------------------------------------------------
2163class _wxQTTimer : public wxTimer
2164{
2165public:
d7a9c895
RN
2166 _wxQTTimer(Movie movie, wxQTMediaBackend* parent, wxQuickTimeLibrary* pLib) :
2167 m_movie(movie), m_bPaused(false), m_parent(parent), m_pLib(pLib)
ff4aedc5
RN
2168 {
2169 }
2170
2171 ~_wxQTTimer()
2172 {
2173 }
2174
2175 bool GetPaused() {return m_bPaused;}
2176 void SetPaused(bool bPaused) {m_bPaused = bPaused;}
2177
2178 //-----------------------------------------------------------------------
2179 // _wxQTTimer::Notify
2180 //
2181 // 1) Checks to see if the movie is done, and if not continues
2182 // streaming the movie
2183 // 2) Sends the wxEVT_MEDIA_STOP event if we have reached the end of
2184 // the movie.
2185 //-----------------------------------------------------------------------
2186 void Notify()
2187 {
2188 if (!m_bPaused)
2189 {
d7a9c895
RN
2190 if(!m_pLib->IsMovieDone(m_movie))
2191 m_pLib->MoviesTask(m_movie, MOVIE_DELAY);
ff4aedc5
RN
2192 else
2193 {
226ec5a7 2194 wxMediaEvent theEvent(wxEVT_MEDIA_STOP,
ff4aedc5
RN
2195 m_parent->m_ctrl->GetId());
2196 m_parent->m_ctrl->ProcessEvent(theEvent);
2197
2198 if(theEvent.IsAllowed())
2199 {
2200 Stop();
2201 m_parent->Stop();
d7a9c895 2202 wxASSERT(m_pLib->GetMoviesError() == noErr);
ff4aedc5
RN
2203
2204 //send the event to our child
226ec5a7 2205 wxMediaEvent theEvent(wxEVT_MEDIA_FINISHED,
ff4aedc5
RN
2206 m_parent->m_ctrl->GetId());
2207 m_parent->m_ctrl->ProcessEvent(theEvent);
2208 }
2209 }
2210 }
2211 }
2212
2213protected:
2214 Movie m_movie; //Our movie instance
2215 bool m_bPaused; //Whether we are paused or not
2216 wxQTMediaBackend* m_parent; //Backend pointer
d7a9c895 2217 wxQuickTimeLibrary* m_pLib; //Interfaces
ff4aedc5
RN
2218};
2219
2220//---------------------------------------------------------------------------
2221// wxQTMediaBackend Destructor
2222//
2223// Sets m_timer to NULL signifying we havn't loaded anything yet
2224//---------------------------------------------------------------------------
2225wxQTMediaBackend::wxQTMediaBackend() : m_timer(NULL)
2226{
2227}
2228
2229//---------------------------------------------------------------------------
2230// wxQTMediaBackend Destructor
2231//
2232// 1) Cleans up the QuickTime movie instance
2233// 2) Decrements the QuickTime reference counter - if this reaches
2234// 0, QuickTime shuts down
2235// 3) Decrements the QuickTime Windows Media Layer reference counter -
2236// if this reaches 0, QuickTime shuts down the Windows Media Layer
2237//---------------------------------------------------------------------------
2238wxQTMediaBackend::~wxQTMediaBackend()
2239{
2240 if(m_timer)
2241 Cleanup();
2242
d7a9c895
RN
2243 if(m_lib.IsOk())
2244 {
2245 //Note that ExitMovies() is not neccessary, but
2246 //the docs are fuzzy on whether or not TerminateQTML is
2247 m_lib.ExitMovies();
2248 m_lib.TerminateQTML();
2249 }
ff4aedc5
RN
2250}
2251
2252//---------------------------------------------------------------------------
2253// wxQTMediaBackend::CreateControl
2254//
2255// 1) Intializes QuickTime
2256// 2) Creates the control window
2257//---------------------------------------------------------------------------
226ec5a7 2258bool wxQTMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent,
ff4aedc5 2259 wxWindowID id,
226ec5a7 2260 const wxPoint& pos,
ff4aedc5 2261 const wxSize& size,
226ec5a7 2262 long style,
ff4aedc5
RN
2263 const wxValidator& validator,
2264 const wxString& name)
2265{
d7a9c895
RN
2266 if(!m_lib.Initialize())
2267 return false;
2268
ff4aedc5 2269 int nError;
d7a9c895 2270 if ((nError = m_lib.InitializeQTML(0)) != noErr) //-2093 no dll
ff4aedc5
RN
2271 {
2272 wxFAIL_MSG(wxString::Format(wxT("Couldn't Initialize Quicktime-%i"), nError));
2273 return false;
2274 }
d7a9c895 2275 m_lib.EnterMovies();
ff4aedc5
RN
2276
2277 //
2278 // Create window
2279 // By default wxWindow(s) is created with a border -
2280 // so we need to get rid of those
2281 //
2282 // Since we don't have a child window like most other
2283 // backends, we don't need wxCLIP_CHILDREN
2284 //
2285 if ( !ctrl->wxControl::Create(parent, id, pos, size,
11085e4b 2286 (style & ~wxBORDER_MASK) | wxBORDER_NONE,
ff4aedc5
RN
2287 validator, name) )
2288 return false;
2289
ff4aedc5
RN
2290 m_ctrl = ctrl;
2291 return true;
2292}
2293
2294//---------------------------------------------------------------------------
2295// wxQTMediaBackend::Load (file version)
2296//
2297// 1) Get an FSSpec from the Windows path name
2298// 2) Open the movie
2299// 3) Obtain the movie instance from the movie resource
226ec5a7 2300// 4)
ff4aedc5
RN
2301//---------------------------------------------------------------------------
2302bool wxQTMediaBackend::Load(const wxString& fileName)
2303{
2304 if(m_timer)
2305 Cleanup();
3f9a3bf9 2306
ff4aedc5
RN
2307 OSErr err = noErr;
2308 short movieResFile;
2309 FSSpec sfFile;
2310
d7a9c895 2311 if (m_lib.NativePathNameToFSSpec ((char*) (const char*) fileName.mb_str(),
78450975 2312 &sfFile, 0) != noErr)
ff4aedc5 2313 return false;
226ec5a7 2314
d7a9c895 2315 if (m_lib.OpenMovieFile (&sfFile, &movieResFile, fsRdPerm) != noErr)
ff4aedc5
RN
2316 return false;
2317
2318 short movieResID = 0;
2319 Str255 movieName;
2320
d7a9c895 2321 err = m_lib.NewMovieFromFile (
ff4aedc5
RN
2322 &m_movie,
2323 movieResFile,
2324 &movieResID,
2325 movieName,
2326 newMovieActive,
2327 NULL); //wasChanged
2328
d7a9c895 2329 m_lib.CloseMovieFile (movieResFile);
ff4aedc5
RN
2330
2331 if (err != noErr)
2332 return false;
2333
2334 FinishLoad();
2335
d7a9c895 2336 return m_lib.GetMoviesError() == noErr;
ff4aedc5
RN
2337}
2338
2339//---------------------------------------------------------------------------
2340// wxQTMediaBackend::Move
2341//
2342// TODO
2343//---------------------------------------------------------------------------
2344bool wxQTMediaBackend::Load(const wxURI& location)
2345{
2346 if(m_timer)
2347 Cleanup();
2348
2349 wxString theURI = location.BuildURI();
2350
2351 OSErr err = noErr;
2352
d7a9c895 2353 Handle theHandle = m_lib.NewHandleClear(theURI.length() + 1);
ff4aedc5
RN
2354 wxASSERT(theHandle);
2355
d7a9c895 2356 m_lib.BlockMove(theURI.mb_str(), *theHandle, theURI.length() + 1);
ff4aedc5
RN
2357
2358 //create the movie from the handle that refers to the URI
d7a9c895 2359 err = m_lib.NewMovieFromDataRef(&m_movie, newMovieActive,
226ec5a7 2360 NULL, theHandle,
d7a9c895 2361 'url'); //URLDataHandlerSubType
ff4aedc5 2362
d7a9c895 2363 m_lib.DisposeHandle(theHandle);
ff4aedc5
RN
2364
2365 if (err != noErr)
2366 return false;
2367
2368 //preroll movie for streaming
2369 //TODO:Async this?
d7a9c895
RN
2370 /*
2371 TimeValue timeNow;
ff4aedc5
RN
2372 Fixed playRate;
2373 timeNow = GetMovieTime(m_movie, NULL);
2374 playRate = GetMoviePreferredRate(m_movie);
2375 PrePrerollMovie(m_movie, timeNow, playRate, NULL, NULL);
d7a9c895
RN
2376 PrerollMovie(m_movie, timeNow, playRate);
2377 m_lib.SetMovieRate(m_movie, playRate);
2378*/
ff4aedc5
RN
2379
2380 FinishLoad();
2381
d7a9c895 2382 return m_lib.GetMoviesError() == noErr;
ff4aedc5
RN
2383}
2384
2385//---------------------------------------------------------------------------
2386// wxQTMediaBackend::Move
2387//
2388// TODO
2389//---------------------------------------------------------------------------
2390void wxQTMediaBackend::FinishLoad()
2391{
d7a9c895 2392 m_timer = new _wxQTTimer(m_movie, (wxQTMediaBackend*) this, &m_lib);
ff4aedc5
RN
2393 wxASSERT(m_timer);
2394
2395 //get the real size of the movie
2396 Rect outRect;
d7a9c895
RN
2397 m_lib.GetMovieNaturalBoundsRect (m_movie, &outRect);
2398 wxASSERT(m_lib.GetMoviesError() == noErr);
ff4aedc5
RN
2399
2400 m_bestSize.x = outRect.right - outRect.left;
2401 m_bestSize.y = outRect.bottom - outRect.top;
226ec5a7 2402
ff4aedc5 2403 //reparent movie/*AudioMediaCharacteristic*/
d7a9c895
RN
2404 if(m_lib.GetMovieIndTrackType(m_movie, 1,
2405 'eyes', //VisualMediaCharacteristic,
2406 (1 << 1) //movieTrackCharacteristic
2407 | (1 << 2) //movieTrackEnabledOnly
2408 ) != NULL)
ff4aedc5 2409 {
d7a9c895 2410 m_lib.CreatePortAssociation(m_ctrl->GetHWND(), NULL, 0L);
226ec5a7 2411
d7a9c895
RN
2412 m_lib.SetMovieGWorld(m_movie,
2413 (CGrafPtr) m_lib.GetNativeWindowPort(m_ctrl->GetHWND()),
2414 NULL);
ff4aedc5
RN
2415 }
2416
2417 //we want millisecond precision
d7a9c895
RN
2418 m_lib.SetMovieTimeScale(m_movie, 1000);
2419 wxASSERT(m_lib.GetMoviesError() == noErr);
ff4aedc5
RN
2420
2421 //
2422 //Here, if the parent of the control has a sizer - we
2423 //tell it to recalculate the size of this control since
2424 //the user opened a seperate media file
2425 //
2426 m_ctrl->InvalidateBestSize();
2427 m_ctrl->GetParent()->Layout();
2428 m_ctrl->GetParent()->Refresh();
2429 m_ctrl->GetParent()->Update();
2430}
2431
2432//---------------------------------------------------------------------------
2433// wxQTMediaBackend::Move
2434//
2435// TODO
2436//---------------------------------------------------------------------------
2437bool wxQTMediaBackend::Play()
2438{
d7a9c895 2439 m_lib.StartMovie(m_movie);
ff4aedc5
RN
2440 m_timer->SetPaused(false);
2441 m_timer->Start(MOVIE_DELAY, wxTIMER_CONTINUOUS);
d7a9c895 2442 return m_lib.GetMoviesError() == noErr;
ff4aedc5
RN
2443}
2444
2445//---------------------------------------------------------------------------
2446// wxQTMediaBackend::Move
2447//
2448// TODO
2449//---------------------------------------------------------------------------
2450bool wxQTMediaBackend::Pause()
2451{
d7a9c895 2452 m_lib.StopMovie(m_movie);
ff4aedc5
RN
2453 m_timer->SetPaused(true);
2454 m_timer->Stop();
d7a9c895 2455 return m_lib.GetMoviesError() == noErr;
ff4aedc5
RN
2456}
2457
2458//---------------------------------------------------------------------------
2459// wxQTMediaBackend::Move
2460//
2461// TODO
2462//---------------------------------------------------------------------------
2463bool wxQTMediaBackend::Stop()
2464{
2465 m_timer->SetPaused(false);
2466 m_timer->Stop();
2467
d7a9c895
RN
2468 m_lib.StopMovie(m_movie);
2469 if(m_lib.GetMoviesError() != noErr)
ff4aedc5 2470 return false;
226ec5a7 2471
d7a9c895
RN
2472 m_lib.GoToBeginningOfMovie(m_movie);
2473 return m_lib.GetMoviesError() == noErr;
ff4aedc5
RN
2474}
2475
2476//---------------------------------------------------------------------------
2477// wxQTMediaBackend::Move
2478//
2479// TODO
2480//---------------------------------------------------------------------------
2481double wxQTMediaBackend::GetPlaybackRate()
2482{
d7a9c895 2483 return ( ((double)m_lib.GetMovieRate(m_movie)) / 0x10000);
ff4aedc5
RN
2484}
2485
2486//---------------------------------------------------------------------------
2487// wxQTMediaBackend::Move
2488//
2489// TODO
2490//---------------------------------------------------------------------------
2491bool wxQTMediaBackend::SetPlaybackRate(double dRate)
2492{
d7a9c895
RN
2493 m_lib.SetMovieRate(m_movie, (Fixed) (dRate * 0x10000));
2494 return m_lib.GetMoviesError() == noErr;
ff4aedc5
RN
2495}
2496
2497//---------------------------------------------------------------------------
2498// wxQTMediaBackend::Move
2499//
2500// TODO
2501//---------------------------------------------------------------------------
2502bool wxQTMediaBackend::SetPosition(wxLongLong where)
2503{
2504 TimeRecord theTimeRecord;
2505 memset(&theTimeRecord, 0, sizeof(TimeRecord));
2506 theTimeRecord.value.lo = where.GetValue();
d7a9c895
RN
2507 theTimeRecord.scale = m_lib.GetMovieTimeScale(m_movie);
2508 theTimeRecord.base = m_lib.GetMovieTimeBase(m_movie);
2509 m_lib.SetMovieTime(m_movie, &theTimeRecord);
ff4aedc5 2510
d7a9c895 2511 if (m_lib.GetMoviesError() != noErr)
ff4aedc5
RN
2512 return false;
2513
2514 return true;
2515}
2516
2517//---------------------------------------------------------------------------
e163773d 2518// wxQTMediaBackend::GetPosition
ff4aedc5 2519//
e163773d 2520// 1) Calls GetMovieTime to get the position we are in in the movie
8b5d5223 2521// in milliseconds (we called
ff4aedc5
RN
2522//---------------------------------------------------------------------------
2523wxLongLong wxQTMediaBackend::GetPosition()
2524{
d7a9c895 2525 return m_lib.GetMovieTime(m_movie, NULL);
ff4aedc5
RN
2526}
2527
6f8c67e7
JS
2528//---------------------------------------------------------------------------
2529// wxQTMediaBackend::GetVolume
2530//
2531// Gets the volume through GetMovieVolume - which returns a 16 bit short -
2532//
2533// +--------+--------+
2534// + (1) + (2) +
2535// +--------+--------+
2536//
2537// (1) first 8 bits are value before decimal
2538// (2) second 8 bits are value after decimal
2539//
2540// Volume ranges from -1.0 (gain but no sound), 0 (no sound and no gain) to
2541// 1 (full gain and sound)
2542//---------------------------------------------------------------------------
2543double wxQTMediaBackend::GetVolume()
2544{
2545 short sVolume = m_lib.GetMovieVolume(m_movie);
2546
2547 if(sVolume & (128 << 8)) //negative - no sound
2548 return 0.0;
2549
2550 return (sVolume & (127 << 8)) ? 1.0 : ((double)(sVolume & 255)) / 255.0;
2551}
2552
2553//---------------------------------------------------------------------------
2554// wxQTMediaBackend::SetVolume
2555//
2556// Sets the volume through SetMovieVolume - which takes a 16 bit short -
2557//
2558// +--------+--------+
2559// + (1) + (2) +
2560// +--------+--------+
2561//
2562// (1) first 8 bits are value before decimal
2563// (2) second 8 bits are value after decimal
2564//
2565// Volume ranges from -1.0 (gain but no sound), 0 (no sound and no gain) to
2566// 1 (full gain and sound)
2567//---------------------------------------------------------------------------
2568bool wxQTMediaBackend::SetVolume(double dVolume)
2569{
2570 short sVolume = (dVolume >= .9999 ? 1 << 8 :
2571 (short) (dVolume * 255));
2572 m_lib.SetMovieVolume(m_movie, sVolume);
2573 return true;
2574}
2575
ff4aedc5
RN
2576//---------------------------------------------------------------------------
2577// wxQTMediaBackend::Move
2578//
2579// TODO
2580//---------------------------------------------------------------------------
2581wxLongLong wxQTMediaBackend::GetDuration()
2582{
d7a9c895 2583 return m_lib.GetMovieDuration(m_movie);
ff4aedc5
RN
2584}
2585
2586//---------------------------------------------------------------------------
2587// wxQTMediaBackend::Move
2588//
2589// TODO
2590//---------------------------------------------------------------------------
2591wxMediaState wxQTMediaBackend::GetState()
2592{
226ec5a7 2593 if ( !m_timer || (m_timer->IsRunning() == false &&
ff4aedc5
RN
2594 m_timer->GetPaused() == false) )
2595 return wxMEDIASTATE_STOPPED;
2596
2597 if( m_timer->IsRunning() == true )
2598 return wxMEDIASTATE_PLAYING;
2599 else
2600 return wxMEDIASTATE_PAUSED;
2601}
2602
2603//---------------------------------------------------------------------------
2604// wxQTMediaBackend::Move
2605//
2606// TODO
2607//---------------------------------------------------------------------------
2608void wxQTMediaBackend::Cleanup()
2609{
2610 delete m_timer;
2611 m_timer = NULL;
2612
d7a9c895
RN
2613 m_lib.StopMovie(m_movie);
2614 m_lib.DisposeMovie(m_movie);
ff4aedc5
RN
2615}
2616
2617//---------------------------------------------------------------------------
2618// wxQTMediaBackend::Move
2619//
2620// TODO
2621//---------------------------------------------------------------------------
2622wxSize wxQTMediaBackend::GetVideoSize() const
2623{
2624 return m_bestSize;
2625}
2626
2627//---------------------------------------------------------------------------
2628// wxQTMediaBackend::Move
2629//
2630// TODO
2631//---------------------------------------------------------------------------
d7a9c895 2632void wxQTMediaBackend::Move(int WXUNUSED(x), int WXUNUSED(y), int w, int h)
ff4aedc5
RN
2633{
2634 if(m_timer)
2635 {
2636 Rect theRect = {0, 0, h, w};
2637
d7a9c895
RN
2638 m_lib.SetMovieBox(m_movie, &theRect);
2639 wxASSERT(m_lib.GetMoviesError() == noErr);
ff4aedc5
RN
2640 }
2641}
2642
2643//---------------------------------------------------------------------------
1146983c 2644// End QT Backend
ff4aedc5 2645//---------------------------------------------------------------------------
ff4aedc5
RN
2646
2647//in source file that contains stuff you don't directly use
2648#include <wx/html/forcelnk.h>
2649FORCE_LINK_ME(basewxmediabackends);
2650
2651//---------------------------------------------------------------------------
2652// End wxMediaCtrl Compilation Guard and this file
2653//---------------------------------------------------------------------------
72259e00
RL
2654#endif //wxUSE_MEDIACTRL
2655
ff4aedc5 2656