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