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