]> git.saurik.com Git - wxWidgets.git/blob - src/msw/mediactrl.cpp
2761249eb8e65b21ad63ae45778a0b1d34017aff
[wxWidgets.git] / src / msw / mediactrl.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/mediactrl.cpp
3 // Purpose: Built-in Media Backends for Windows
4 // Author: Ryan Norton <wxprojects@comcast.net>
5 // Modified by:
6 // Created: 11/07/04
7 // RCS-ID: $Id$
8 // Copyright: (c) Ryan Norton
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 /*
13 FIXME FIXME FIXME:
14 - extract different backends in different files (better yet, make backends
15 dynamically loadable...), they have nothing to do with each other and
16 this file is huge and also separate the standard contents from our code
17 itself
18 */
19
20 //===========================================================================
21 // DECLARATIONS
22 //===========================================================================
23
24 //---------------------------------------------------------------------------
25 // Pre-compiled header stuff
26 //---------------------------------------------------------------------------
27
28 // For compilers that support precompilation, includes "wx.h".
29 #include "wx/wxprec.h"
30
31 #ifdef __BORLANDC__
32 #pragma hdrstop
33 #endif
34
35 //---------------------------------------------------------------------------
36 // MediaCtrl include
37 //---------------------------------------------------------------------------
38 #include "wx/mediactrl.h"
39
40 //---------------------------------------------------------------------------
41 // Compilation guard
42 //---------------------------------------------------------------------------
43 #if wxUSE_MEDIACTRL
44
45 //---------------------------------------------------------------------------
46 // WX Includes
47 //---------------------------------------------------------------------------
48 #include "wx/log.h" //wxLogDebug
49 #include "wx/math.h" //log10 & pow
50 #include "wx/msw/private.h" //user info and wndproc setting/getting
51 #include "wx/dcclient.h"
52 #include "wx/timer.h"
53 #include "wx/dynlib.h"
54
55 //---------------------------------------------------------------------------
56 // Externals (somewhere in src/msw/app.cpp and src/msw/window.cpp)
57 //---------------------------------------------------------------------------
58 extern "C" WXDLLIMPEXP_BASE HINSTANCE wxGetInstance(void);
59 #ifdef __WXWINCE__
60 extern WXDLLIMPEXP_CORE wxChar *wxCanvasClassName;
61 #else
62 extern WXDLLIMPEXP_CORE const wxChar *wxCanvasClassName;
63 #endif
64
65 LRESULT WXDLLIMPEXP_CORE APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message,
66 WPARAM wParam, LPARAM lParam);
67
68 //===========================================================================
69 // BACKEND DECLARATIONS
70 //===========================================================================
71
72 //---------------------------------------------------------------------------
73 //
74 // wxAMMediaBackend
75 //
76 //---------------------------------------------------------------------------
77
78 //---------------------------------------------------------------------------
79 // wxActiveXContainer - includes all the COM-specific stuff we need
80 //---------------------------------------------------------------------------
81 #include "wx/msw/ole/activex.h"
82
83 //---------------------------------------------------------------------------
84 // IIDS - used by CoCreateInstance and IUnknown::QueryInterface
85 //
86 // [idl name] [idl decription]
87 // amcompat.idl Microsoft Active Movie Control (Ver 2.0)
88 // nscompat.idl Microsoft NetShow Player (Ver 1.0)
89 // msdxm.idl Windows Media Player (Ver 1.0)
90 // quartz.idl
91 //
92 // First, when I say I "from XXX.idl", I mean I go into the COM Browser
93 // ($Microsoft Visual Studio$/Common/Tools/OLEVIEW.EXE), open
94 // "type libraries", open a specific type library (for quartz for example its
95 // "ActiveMovie control type library (V1.0)"), save it as an .idl, compile the
96 // idl using the midl compiler that comes with visual studio
97 // ($Microsoft Visual Studio$/VC98/bin/midl.exe on VC6) with the /h argument
98 // to make it generate stubs (a .h & .c file), then clean up the generated
99 // interfaces I want with the STDMETHOD wrappers and then put them into
100 // mediactrl.cpp.
101 //
102 // According to the MSDN docs, IMediaPlayer requires Windows 98 SE
103 // or greater. NetShow is available on Windows 3.1 and I'm guessing
104 // IActiveMovie is too. IMediaPlayer is essentially the Windows Media
105 // Player 6.4 SDK.
106 //
107 // Some of these are not used but are kept here for future reference anyway
108 //---------------------------------------------------------------------------
109 const IID IID_IActiveMovie = {0x05589FA2,0xC356,0x11CE,{0xBF,0x01,0x00,0xAA,0x00,0x55,0x59,0x5A}};
110 const IID IID_IActiveMovie2 = {0xB6CD6554,0xE9CB,0x11D0,{0x82,0x1F,0x00,0xA0,0xC9,0x1F,0x9C,0xA0}};
111 const IID IID_IActiveMovie3 = {0x265EC140,0xAE62,0x11D1,{0x85,0x00,0x00,0xA0,0xC9,0x1F,0x9C,0xA0}};
112
113 const IID IID_INSOPlay = {0x2179C5D1,0xEBFF,0x11CF,{0xB6,0xFD,0x00,0xAA,0x00,0xB4,0xE2,0x20}};
114 const IID IID_INSPlay = {0xE7C4BE80,0x7960,0x11D0,{0xB7,0x27,0x00,0xAA,0x00,0xB4,0xE2,0x20}};
115 const IID IID_INSPlay1 = {0x265EC141,0xAE62,0x11D1,{0x85,0x00,0x00,0xA0,0xC9,0x1F,0x9C,0xA0}};
116
117 const IID IID_IMediaPlayer = {0x22D6F311,0xB0F6,0x11D0,{0x94,0xAB,0x00,0x80,0xC7,0x4C,0x7E,0x95}};
118 const IID IID_IMediaPlayer2 = {0x20D4F5E0,0x5475,0x11D2,{0x97,0x74,0x00,0x00,0xF8,0x08,0x55,0xE6}};
119
120 const CLSID CLSID_ActiveMovie = {0x05589FA1,0xC356,0x11CE,{0xBF,0x01,0x00,0xAA,0x00,0x55,0x59,0x5A}};
121 const CLSID CLSID_MediaPlayer = {0x22D6F312,0xB0F6,0x11D0,{0x94,0xAB,0x00,0x80,0xC7,0x4C,0x7E,0x95}};
122 const CLSID CLSID_NSPlay = {0x2179C5D3,0xEBFF,0x11CF,{0xB6,0xFD,0x00,0xAA,0x00,0xB4,0xE2,0x20}};
123
124 const IID IID_IAMOpenProgress = {0x8E1C39A1, 0xDE53, 0x11CF,{0xAA, 0x63, 0x00, 0x80, 0xC7, 0x44, 0x52, 0x8D}};
125
126 // QUARTZ
127 const CLSID CLSID_FilgraphManager = {0xE436EBB3,0x524F,0x11CE,{0x9F,0x53,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
128 const IID IID_IMediaEvent = {0x56A868B6,0x0AD4,0x11CE,{0xB0,0x3A,0x00,0x20,0xAF,0x0B,0xA7,0x70}};
129
130 //?? QUARTZ Also?
131 const CLSID CLSID_VideoMixingRenderer9 ={0x51B4ABF3, 0x748F, 0x4E3B,{0xA2, 0x76, 0xC8, 0x28, 0x33, 0x0E, 0x92, 0x6A}};
132 const IID IID_IVMRWindowlessControl9 = {0x8F537D09, 0xF85E, 0x4414,{0xB2, 0x3B, 0x50, 0x2E, 0x54, 0xC7, 0x99, 0x27}};
133 const IID IID_IFilterGraph = {0x56A8689F, 0x0AD4, 0x11CE,{0xB0, 0x3A, 0x00, 0x20, 0xAF, 0x0B, 0xA7, 0x70}};
134 const IID IID_IGraphBuilder = {0x56A868A9, 0x0AD4, 0x11CE,{0xB0, 0x3A, 0x00, 0x20, 0xAF, 0x0B, 0xA7, 0x70}};
135 const IID IID_IVMRFilterConfig9 = {0x5A804648, 0x4F66, 0x4867,{0x9C, 0x43, 0x4F, 0x5C, 0x82, 0x2C, 0xF1, 0xB8}};
136 const IID IID_IBaseFilter = {0x56A86895, 0x0AD4, 0x11CE,{0xB0, 0x3A, 0x00, 0x20, 0xAF, 0x0B, 0xA7, 0x70}};
137
138 //---------------------------------------------------------------------------
139 // QUARTZ COM INTERFACES (dumped from quartz.idl from MSVC COM Browser)
140 //---------------------------------------------------------------------------
141
142 struct IAMOpenProgress : public IUnknown
143 {
144 STDMETHOD(QueryProgress)(LONGLONG *pllTotal, LONGLONG *pllCurrent) PURE;
145 STDMETHOD(AbortOperation)(void) PURE;
146 };
147
148 struct IMediaEvent : public IDispatch
149 {
150 STDMETHOD(GetEventHandle)(LONG_PTR *) PURE;
151 STDMETHOD(GetEvent)(long *, LONG_PTR *, LONG_PTR *, long) PURE;
152 STDMETHOD(WaitForCompletion)(long, long *) PURE;
153 STDMETHOD(CancelDefaultHandling)(long) PURE;
154 STDMETHOD(RestoreDefaultHandling)(long) PURE;
155 STDMETHOD(FreeEventParams)(long, LONG_PTR, LONG_PTR) PURE;
156 };
157
158 //---------------------------------------------------------------------------
159 // ACTIVEMOVIE COM INTERFACES (dumped from amcompat.idl from MSVC COM Browser)
160 //---------------------------------------------------------------------------
161
162 enum ReadyStateConstants
163 {
164 amvUninitialized = 0,
165 amvLoading = 1,
166 amvInteractive = 3,
167 amvComplete = 4
168 };
169
170 enum StateConstants
171 {
172 amvNotLoaded = -1,
173 amvStopped = 0,
174 amvPaused = 1,
175 amvRunning = 2
176 };
177
178 enum DisplayModeConstants
179 {
180 amvTime = 0,
181 amvFrames = 1
182 };
183
184 enum WindowSizeConstants
185 {
186 amvOriginalSize = 0,
187 amvDoubleOriginalSize = 1,
188 amvOneSixteenthScreen = 2,
189 amvOneFourthScreen = 3,
190 amvOneHalfScreen = 4
191 };
192
193 enum AppearanceConstants
194 {
195 amvFlat = 0,
196 amv3D = 1
197 };
198
199 enum BorderStyleConstants
200 {
201 amvNone = 0,
202 amvFixedSingle = 1
203 };
204
205 struct IActiveMovie : public IDispatch
206 {
207 STDMETHOD(AboutBox)( void) PURE;
208 STDMETHOD(Run)( void) PURE;
209 STDMETHOD(Pause)( void) PURE;
210 STDMETHOD(Stop)( void) PURE;
211 STDMETHOD(get_ImageSourceWidth)(long __RPC_FAR *pWidth) PURE;
212 STDMETHOD(get_ImageSourceHeight)(long __RPC_FAR *pHeight) PURE;
213 STDMETHOD(get_Author)(BSTR __RPC_FAR *pbstrAuthor) PURE;
214 STDMETHOD(get_Title)(BSTR __RPC_FAR *pbstrTitle) PURE;
215 STDMETHOD(get_Copyright)(BSTR __RPC_FAR *pbstrCopyright) PURE;
216 STDMETHOD(get_Description)(BSTR __RPC_FAR *pbstrDescription) PURE;
217 STDMETHOD(get_Rating)(BSTR __RPC_FAR *pbstrRating) PURE;
218 STDMETHOD(get_FileName)(BSTR __RPC_FAR *pbstrFileName) PURE;
219 STDMETHOD(put_FileName)(BSTR pbstrFileName) PURE;
220 STDMETHOD(get_Duration)(double __RPC_FAR *pValue) PURE;
221 STDMETHOD(get_CurrentPosition)(double __RPC_FAR *pValue) PURE;
222 STDMETHOD(put_CurrentPosition)(double pValue) PURE;
223 STDMETHOD(get_PlayCount)(long __RPC_FAR *pPlayCount) PURE;
224 STDMETHOD(put_PlayCount)(long pPlayCount) PURE;
225 STDMETHOD(get_SelectionStart)(double __RPC_FAR *pValue) PURE;
226 STDMETHOD(put_SelectionStart)(double pValue) PURE;
227 STDMETHOD(get_SelectionEnd)(double __RPC_FAR *pValue) PURE;
228 STDMETHOD(put_SelectionEnd)(double pValue) PURE;
229 STDMETHOD(get_CurrentState)(StateConstants __RPC_FAR *pState) PURE;
230 STDMETHOD(get_Rate)(double __RPC_FAR *pValue) PURE;
231 STDMETHOD(put_Rate)(double pValue) PURE;
232 STDMETHOD(get_Volume)(long __RPC_FAR *pValue) PURE;
233 STDMETHOD(put_Volume)(long pValue) PURE;
234 STDMETHOD(get_Balance)(long __RPC_FAR *pValue) PURE;
235 STDMETHOD(put_Balance)(long pValue) PURE;
236 STDMETHOD(get_EnableContextMenu)(VARIANT_BOOL __RPC_FAR *pEnable) PURE;
237 STDMETHOD(put_EnableContextMenu)(VARIANT_BOOL pEnable) PURE;
238 STDMETHOD(get_ShowDisplay)(VARIANT_BOOL __RPC_FAR *Show) PURE;
239 STDMETHOD(put_ShowDisplay)(VARIANT_BOOL Show) PURE;
240 STDMETHOD(get_ShowControls)(VARIANT_BOOL __RPC_FAR *Show) PURE;
241 STDMETHOD(put_ShowControls)(VARIANT_BOOL Show) PURE;
242 STDMETHOD(get_ShowPositionControls)(VARIANT_BOOL __RPC_FAR *Show) PURE;
243 STDMETHOD(put_ShowPositionControls)(VARIANT_BOOL Show) PURE;
244 STDMETHOD(get_ShowSelectionControls)(VARIANT_BOOL __RPC_FAR *Show) PURE;
245 STDMETHOD(put_ShowSelectionControls)(VARIANT_BOOL Show) PURE;
246 STDMETHOD(get_ShowTracker)(VARIANT_BOOL __RPC_FAR *Show) PURE;
247 STDMETHOD(put_ShowTracker)(VARIANT_BOOL Show) PURE;
248 STDMETHOD(get_EnablePositionControls)(VARIANT_BOOL __RPC_FAR *Enable) PURE;
249 STDMETHOD(put_EnablePositionControls)(VARIANT_BOOL Enable) PURE;
250 STDMETHOD(get_EnableSelectionControls)(VARIANT_BOOL __RPC_FAR *Enable) PURE;
251 STDMETHOD(put_EnableSelectionControls)(VARIANT_BOOL Enable) PURE;
252 STDMETHOD(get_EnableTracker)(VARIANT_BOOL __RPC_FAR *Enable) PURE;
253 STDMETHOD(put_EnableTracker)(VARIANT_BOOL Enable) PURE;
254 STDMETHOD(get_AllowHideDisplay)(VARIANT_BOOL __RPC_FAR *Show) PURE;
255 STDMETHOD(put_AllowHideDisplay)(VARIANT_BOOL Show) PURE;
256 STDMETHOD(get_AllowHideControls)(VARIANT_BOOL __RPC_FAR *Show) PURE;
257 STDMETHOD(put_AllowHideControls)(VARIANT_BOOL Show) PURE;
258 STDMETHOD(get_DisplayMode)(DisplayModeConstants __RPC_FAR *pValue) PURE;
259 STDMETHOD(put_DisplayMode)(DisplayModeConstants pValue) PURE;
260 STDMETHOD(get_AllowChangeDisplayMode)(VARIANT_BOOL __RPC_FAR *fAllow) PURE;
261 STDMETHOD(put_AllowChangeDisplayMode)(VARIANT_BOOL fAllow) PURE;
262 STDMETHOD(get_FilterGraph)(IUnknown __RPC_FAR *__RPC_FAR *ppFilterGraph) PURE;
263 STDMETHOD(put_FilterGraph)(IUnknown __RPC_FAR *ppFilterGraph) PURE;
264 STDMETHOD(get_FilterGraphDispatch)(IDispatch __RPC_FAR *__RPC_FAR *pDispatch) PURE;
265 STDMETHOD(get_DisplayForeColor)(unsigned long __RPC_FAR *ForeColor) PURE;
266 STDMETHOD(put_DisplayForeColor)(unsigned long ForeColor) PURE;
267 STDMETHOD(get_DisplayBackColor)(unsigned long __RPC_FAR *BackColor) PURE;
268 STDMETHOD(put_DisplayBackColor)(unsigned long BackColor) PURE;
269 STDMETHOD(get_MovieWindowSize)(WindowSizeConstants __RPC_FAR *WindowSize) PURE;
270 STDMETHOD(put_MovieWindowSize)(WindowSizeConstants WindowSize) PURE;
271 STDMETHOD(get_FullScreenMode)(VARIANT_BOOL __RPC_FAR *pEnable) PURE;
272 STDMETHOD(put_FullScreenMode)(VARIANT_BOOL pEnable) PURE;
273 STDMETHOD(get_AutoStart)(VARIANT_BOOL __RPC_FAR *pEnable) PURE;
274 STDMETHOD(put_AutoStart)(VARIANT_BOOL pEnable) PURE;
275 STDMETHOD(get_AutoRewind)(VARIANT_BOOL __RPC_FAR *pEnable) PURE;
276 STDMETHOD(put_AutoRewind)(VARIANT_BOOL pEnable) PURE;
277 STDMETHOD(get_hWnd)(long __RPC_FAR *hWnd) PURE;
278 STDMETHOD(get_Appearance)(AppearanceConstants __RPC_FAR *pAppearance) PURE;
279 STDMETHOD(put_Appearance)(AppearanceConstants pAppearance) PURE;
280 STDMETHOD(get_BorderStyle)(BorderStyleConstants __RPC_FAR *pBorderStyle) PURE;
281 STDMETHOD(put_BorderStyle)(BorderStyleConstants pBorderStyle) PURE;
282 STDMETHOD(get_Enabled)(VARIANT_BOOL __RPC_FAR *pEnabled) PURE;
283 STDMETHOD(put_Enabled)(VARIANT_BOOL pEnabled) PURE;
284 STDMETHOD(get_Info)(long __RPC_FAR *ppInfo) PURE;
285 };
286
287
288
289 struct IActiveMovie2 : public IActiveMovie
290 {
291 STDMETHOD(IsSoundCardEnabled)(VARIANT_BOOL __RPC_FAR *pbSoundCard) PURE;
292 STDMETHOD(get_ReadyState)(ReadyStateConstants __RPC_FAR *pValue) PURE;
293 };
294
295 struct IActiveMovie3 : public IActiveMovie2
296 {
297 STDMETHOD(get_MediaPlayer)(IDispatch __RPC_FAR *__RPC_FAR *ppDispatch) PURE;
298 };
299
300
301 //---------------------------------------------------------------------------
302 // MEDIAPLAYER COM INTERFACES (dumped from msdxm.idl from MSVC COM Browser)
303 //---------------------------------------------------------------------------
304
305 enum MPPlayStateConstants
306 {
307 mpStopped = 0,
308 mpPaused = 1,
309 mpPlaying = 2,
310 mpWaiting = 3,
311 mpScanForward = 4,
312 mpScanReverse = 5,
313 mpClosed = 6
314 };
315
316 enum MPDisplaySizeConstants
317 {
318 mpDefaultSize = 0,
319 mpHalfSize = 1,
320 mpDoubleSize = 2,
321 mpFullScreen = 3,
322 mpFitToSize = 4,
323 mpOneSixteenthScreen = 5,
324 mpOneFourthScreen = 6,
325 mpOneHalfScreen = 7
326 };
327
328 enum MPReadyStateConstants
329 {
330 mpReadyStateUninitialized = 0,
331 mpReadyStateLoading = 1,
332 mpReadyStateInteractive = 3,
333 mpReadyStateComplete = 4
334 };
335
336 typedef unsigned long VB_OLE_COLOR;
337
338 enum MPDisplayModeConstants
339 {
340 mpTime = 0,
341 mpFrames = 1
342 };
343
344 enum MPMoreInfoType
345 {
346 mpShowURL = 0,
347 mpClipURL = 1,
348 mpBannerURL = 2
349 };
350
351 enum MPMediaInfoType
352 {
353 mpShowFilename = 0,
354 mpShowTitle = 1,
355 mpShowAuthor = 2,
356 mpShowCopyright = 3,
357 mpShowRating = 4,
358 mpShowDescription = 5,
359 mpShowLogoIcon = 6,
360 mpClipFilename = 7,
361 mpClipTitle = 8,
362 mpClipAuthor = 9,
363 mpClipCopyright = 10,
364 mpClipRating = 11,
365 mpClipDescription = 12,
366 mpClipLogoIcon = 13,
367 mpBannerImage = 14,
368 mpBannerMoreInfo = 15,
369 mpWatermark = 16
370 };
371
372 enum DVDMenuIDConstants
373 {
374 dvdMenu_Title = 2,
375 dvdMenu_Root = 3,
376 dvdMenu_Subpicture = 4,
377 dvdMenu_Audio = 5,
378 dvdMenu_Angle = 6,
379 dvdMenu_Chapter = 7
380 };
381
382 enum MPShowDialogConstants
383 {
384 mpShowDialogHelp = 0,
385 mpShowDialogStatistics = 1,
386 mpShowDialogOptions = 2,
387 mpShowDialogContextMenu = 3
388 };
389
390
391 struct IMediaPlayer : public IDispatch
392 {
393 STDMETHOD(get_CurrentPosition)(double __RPC_FAR *pCurrentPosition) PURE;
394 STDMETHOD(put_CurrentPosition)(double pCurrentPosition) PURE;
395 STDMETHOD(get_Duration)(double __RPC_FAR *pDuration) PURE;
396 STDMETHOD(get_ImageSourceWidth)(long __RPC_FAR *pWidth) PURE;
397 STDMETHOD(get_ImageSourceHeight)(long __RPC_FAR *pHeight) PURE;
398 STDMETHOD(get_MarkerCount)(long __RPC_FAR *pMarkerCount) PURE;
399 STDMETHOD(get_CanScan)(VARIANT_BOOL __RPC_FAR *pCanScan) PURE;
400 STDMETHOD(get_CanSeek)(VARIANT_BOOL __RPC_FAR *pCanSeek) PURE;
401 STDMETHOD(get_CanSeekToMarkers)(VARIANT_BOOL __RPC_FAR *pCanSeekToMarkers) PURE;
402 STDMETHOD(get_CurrentMarker)(long __RPC_FAR *pCurrentMarker) PURE;
403 STDMETHOD(put_CurrentMarker)(long pCurrentMarker) PURE;
404 STDMETHOD(get_FileName)(BSTR __RPC_FAR *pbstrFileName) PURE;
405 STDMETHOD(put_FileName)(BSTR pbstrFileName) PURE;
406 STDMETHOD(get_SourceLink)(BSTR __RPC_FAR *pbstrSourceLink) PURE;
407 STDMETHOD(get_CreationDate)(DATE __RPC_FAR *pCreationDate) PURE;
408 STDMETHOD(get_ErrorCorrection)(BSTR __RPC_FAR *pbstrErrorCorrection) PURE;
409 STDMETHOD(get_Bandwidth)(long __RPC_FAR *pBandwidth) PURE;
410 STDMETHOD(get_SourceProtocol)(long __RPC_FAR *pSourceProtocol) PURE;
411 STDMETHOD(get_ReceivedPackets)(long __RPC_FAR *pReceivedPackets) PURE;
412 STDMETHOD(get_RecoveredPackets)(long __RPC_FAR *pRecoveredPackets) PURE;
413 STDMETHOD(get_LostPackets)(long __RPC_FAR *pLostPackets) PURE;
414 STDMETHOD(get_ReceptionQuality)(long __RPC_FAR *pReceptionQuality) PURE;
415 STDMETHOD(get_BufferingCount)(long __RPC_FAR *pBufferingCount) PURE;
416 STDMETHOD(get_IsBroadcast)(VARIANT_BOOL __RPC_FAR *pIsBroadcast) PURE;
417 STDMETHOD(get_BufferingProgress)(long __RPC_FAR *pBufferingProgress) PURE;
418 STDMETHOD(get_ChannelName)(BSTR __RPC_FAR *pbstrChannelName) PURE;
419 STDMETHOD(get_ChannelDescription)(BSTR __RPC_FAR *pbstrChannelDescription) PURE;
420 STDMETHOD(get_ChannelURL)(BSTR __RPC_FAR *pbstrChannelURL) PURE;
421 STDMETHOD(get_ContactAddress)(BSTR __RPC_FAR *pbstrContactAddress) PURE;
422 STDMETHOD(get_ContactPhone)(BSTR __RPC_FAR *pbstrContactPhone) PURE;
423 STDMETHOD(get_ContactEmail)(BSTR __RPC_FAR *pbstrContactEmail) PURE;
424 STDMETHOD(get_BufferingTime)(double __RPC_FAR *pBufferingTime) PURE;
425 STDMETHOD(put_BufferingTime)(double pBufferingTime) PURE;
426 STDMETHOD(get_AutoStart)(VARIANT_BOOL __RPC_FAR *pAutoStart) PURE;
427 STDMETHOD(put_AutoStart)(VARIANT_BOOL pAutoStart) PURE;
428 STDMETHOD(get_AutoRewind)(VARIANT_BOOL __RPC_FAR *pAutoRewind) PURE;
429 STDMETHOD(put_AutoRewind)(VARIANT_BOOL pAutoRewind) PURE;
430 STDMETHOD(get_Rate)(double __RPC_FAR *pRate) PURE;
431 STDMETHOD(put_Rate)(double pRate) PURE;
432 STDMETHOD(get_SendKeyboardEvents)(VARIANT_BOOL __RPC_FAR *pSendKeyboardEvents) PURE;
433 STDMETHOD(put_SendKeyboardEvents)(VARIANT_BOOL pSendKeyboardEvents) PURE;
434 STDMETHOD(get_SendMouseClickEvents)(VARIANT_BOOL __RPC_FAR *pSendMouseClickEvents) PURE;
435 STDMETHOD(put_SendMouseClickEvents)(VARIANT_BOOL pSendMouseClickEvents) PURE;
436 STDMETHOD(get_SendMouseMoveEvents)(VARIANT_BOOL __RPC_FAR *pSendMouseMoveEvents) PURE;
437 STDMETHOD(put_SendMouseMoveEvents)(VARIANT_BOOL pSendMouseMoveEvents) PURE;
438 STDMETHOD(get_PlayCount)(long __RPC_FAR *pPlayCount) PURE;
439 STDMETHOD(put_PlayCount)(long pPlayCount) PURE;
440 STDMETHOD(get_ClickToPlay)(VARIANT_BOOL __RPC_FAR *pClickToPlay) PURE;
441 STDMETHOD(put_ClickToPlay)(VARIANT_BOOL pClickToPlay) PURE;
442 STDMETHOD(get_AllowScan)(VARIANT_BOOL __RPC_FAR *pAllowScan) PURE;
443 STDMETHOD(put_AllowScan)(VARIANT_BOOL pAllowScan) PURE;
444 STDMETHOD(get_EnableContextMenu)(VARIANT_BOOL __RPC_FAR *pEnableContextMenu) PURE;
445 STDMETHOD(put_EnableContextMenu)(VARIANT_BOOL pEnableContextMenu) PURE;
446 STDMETHOD(get_CursorType)(long __RPC_FAR *pCursorType) PURE;
447 STDMETHOD(put_CursorType)(long pCursorType) PURE;
448 STDMETHOD(get_CodecCount)(long __RPC_FAR *pCodecCount) PURE;
449 STDMETHOD(get_AllowChangeDisplaySize)(VARIANT_BOOL __RPC_FAR *pAllowChangeDisplaySize) PURE;
450 STDMETHOD(put_AllowChangeDisplaySize)( VARIANT_BOOL pAllowChangeDisplaySize) PURE;
451 STDMETHOD(get_IsDurationValid)(VARIANT_BOOL __RPC_FAR *pIsDurationValid) PURE;
452 STDMETHOD(get_OpenState)(long __RPC_FAR *pOpenState) PURE;
453 STDMETHOD(get_SendOpenStateChangeEvents)(VARIANT_BOOL __RPC_FAR *pSendOpenStateChangeEvents) PURE;
454 STDMETHOD(put_SendOpenStateChangeEvents)(VARIANT_BOOL pSendOpenStateChangeEvents) PURE;
455 STDMETHOD(get_SendWarningEvents)( VARIANT_BOOL __RPC_FAR *pSendWarningEvents) PURE;
456 STDMETHOD(put_SendWarningEvents)(VARIANT_BOOL pSendWarningEvents) PURE;
457 STDMETHOD(get_SendErrorEvents)(VARIANT_BOOL __RPC_FAR *pSendErrorEvents) PURE;
458 STDMETHOD(put_SendErrorEvents)(VARIANT_BOOL pSendErrorEvents) PURE;
459 STDMETHOD(get_PlayState)(MPPlayStateConstants __RPC_FAR *pPlayState) PURE;
460 STDMETHOD(get_SendPlayStateChangeEvents)(VARIANT_BOOL __RPC_FAR *pSendPlayStateChangeEvents) PURE;
461 STDMETHOD(put_SendPlayStateChangeEvents)(VARIANT_BOOL pSendPlayStateChangeEvents) PURE;
462 STDMETHOD(get_DisplaySize)(MPDisplaySizeConstants __RPC_FAR *pDisplaySize) PURE;
463 STDMETHOD(put_DisplaySize)(MPDisplaySizeConstants pDisplaySize) PURE;
464 STDMETHOD(get_InvokeURLs)(VARIANT_BOOL __RPC_FAR *pInvokeURLs) PURE;
465 STDMETHOD(put_InvokeURLs)(VARIANT_BOOL pInvokeURLs) PURE;
466 STDMETHOD(get_BaseURL)(BSTR __RPC_FAR *pbstrBaseURL) PURE;
467 STDMETHOD(put_BaseURL)(BSTR pbstrBaseURL) PURE;
468 STDMETHOD(get_DefaultFrame)(BSTR __RPC_FAR *pbstrDefaultFrame) PURE;
469 STDMETHOD(put_DefaultFrame)(BSTR pbstrDefaultFrame) PURE;
470 STDMETHOD(get_HasError)(VARIANT_BOOL __RPC_FAR *pHasError) PURE;
471 STDMETHOD(get_ErrorDescription)(BSTR __RPC_FAR *pbstrErrorDescription) PURE;
472 STDMETHOD(get_ErrorCode)(long __RPC_FAR *pErrorCode) PURE;
473 STDMETHOD(get_AnimationAtStart)(VARIANT_BOOL __RPC_FAR *pAnimationAtStart) PURE;
474 STDMETHOD(put_AnimationAtStart)(VARIANT_BOOL pAnimationAtStart) PURE;
475 STDMETHOD(get_TransparentAtStart)( VARIANT_BOOL __RPC_FAR *pTransparentAtStart) PURE;
476 STDMETHOD(put_TransparentAtStart)(VARIANT_BOOL pTransparentAtStart) PURE;
477 STDMETHOD(get_Volume)(long __RPC_FAR *pVolume) PURE;
478 STDMETHOD(put_Volume)(long pVolume) PURE;
479 STDMETHOD(get_Balance)(long __RPC_FAR *pBalance) PURE;
480 STDMETHOD(put_Balance)(long pBalance) PURE;
481 STDMETHOD(get_ReadyState)(MPReadyStateConstants __RPC_FAR *pValue) PURE;
482 STDMETHOD(get_SelectionStart)(double __RPC_FAR *pValue) PURE;
483 STDMETHOD(put_SelectionStart)(double pValue) PURE;
484 STDMETHOD(get_SelectionEnd)(double __RPC_FAR *pValue) PURE;
485 STDMETHOD(put_SelectionEnd)(double pValue) PURE;
486 STDMETHOD(get_ShowDisplay)(VARIANT_BOOL __RPC_FAR *Show) PURE;
487 STDMETHOD(put_ShowDisplay)(VARIANT_BOOL Show) PURE;
488 STDMETHOD(get_ShowControls)(VARIANT_BOOL __RPC_FAR *Show) PURE;
489 STDMETHOD(put_ShowControls)(VARIANT_BOOL Show) PURE;
490 STDMETHOD(get_ShowPositionControls)(VARIANT_BOOL __RPC_FAR *Show) PURE;
491 STDMETHOD(put_ShowPositionControls)(VARIANT_BOOL Show) PURE;
492 STDMETHOD(get_ShowTracker)(VARIANT_BOOL __RPC_FAR *Show) PURE;
493 STDMETHOD(put_ShowTracker)(VARIANT_BOOL Show) PURE;
494 STDMETHOD(get_EnablePositionControls)(VARIANT_BOOL __RPC_FAR *Enable) PURE;
495 STDMETHOD(put_EnablePositionControls)(VARIANT_BOOL Enable) PURE;
496 STDMETHOD(get_EnableTracker)(VARIANT_BOOL __RPC_FAR *Enable) PURE;
497 STDMETHOD(put_EnableTracker)(VARIANT_BOOL Enable) PURE;
498 STDMETHOD(get_Enabled)(VARIANT_BOOL __RPC_FAR *pEnabled) PURE;
499 STDMETHOD(put_Enabled)(VARIANT_BOOL pEnabled) PURE;
500 STDMETHOD(get_DisplayForeColor)(VB_OLE_COLOR __RPC_FAR *ForeColor) PURE;
501 STDMETHOD(put_DisplayForeColor)(VB_OLE_COLOR ForeColor) PURE;
502 STDMETHOD(get_DisplayBackColor)(VB_OLE_COLOR __RPC_FAR *BackColor) PURE;
503 STDMETHOD(put_DisplayBackColor)(VB_OLE_COLOR BackColor) PURE;
504 STDMETHOD(get_DisplayMode)(MPDisplayModeConstants __RPC_FAR *pValue) PURE;
505 STDMETHOD(put_DisplayMode)(MPDisplayModeConstants pValue) PURE;
506 STDMETHOD(get_VideoBorder3D)(VARIANT_BOOL __RPC_FAR *pVideoBorderWidth) PURE;
507 STDMETHOD(put_VideoBorder3D)(VARIANT_BOOL pVideoBorderWidth) PURE;
508 STDMETHOD(get_VideoBorderWidth)(long __RPC_FAR *pVideoBorderWidth) PURE;
509 STDMETHOD(put_VideoBorderWidth)(long pVideoBorderWidth) PURE;
510 STDMETHOD(get_VideoBorderColor)(VB_OLE_COLOR __RPC_FAR *pVideoBorderWidth) PURE;
511 STDMETHOD(put_VideoBorderColor)(VB_OLE_COLOR pVideoBorderWidth) PURE;
512 STDMETHOD(get_ShowGotoBar)(VARIANT_BOOL __RPC_FAR *pbool) PURE;
513 STDMETHOD(put_ShowGotoBar)(VARIANT_BOOL pbool) PURE;
514 STDMETHOD(get_ShowStatusBar)(VARIANT_BOOL __RPC_FAR *pbool) PURE;
515 STDMETHOD(put_ShowStatusBar)(VARIANT_BOOL pbool) PURE;
516 STDMETHOD(get_ShowCaptioning)(VARIANT_BOOL __RPC_FAR *pbool) PURE;
517 STDMETHOD(put_ShowCaptioning)(VARIANT_BOOL pbool) PURE;
518 STDMETHOD(get_ShowAudioControls)(VARIANT_BOOL __RPC_FAR *pbool) PURE;
519 STDMETHOD(put_ShowAudioControls)(VARIANT_BOOL pbool) PURE;
520 STDMETHOD(get_CaptioningID)( BSTR __RPC_FAR *pstrText) PURE;
521 STDMETHOD(put_CaptioningID)(BSTR pstrText) PURE;
522 STDMETHOD(get_Mute)(VARIANT_BOOL __RPC_FAR *vbool) PURE;
523 STDMETHOD(put_Mute)(VARIANT_BOOL vbool) PURE;
524 STDMETHOD(get_CanPreview)(VARIANT_BOOL __RPC_FAR *pCanPreview) PURE;
525 STDMETHOD(get_PreviewMode)(VARIANT_BOOL __RPC_FAR *pPreviewMode) PURE;
526 STDMETHOD(put_PreviewMode)(VARIANT_BOOL pPreviewMode) PURE;
527 STDMETHOD(get_HasMultipleItems)(VARIANT_BOOL __RPC_FAR *pHasMuliItems) PURE;
528 STDMETHOD(get_Language)(long __RPC_FAR *pLanguage) PURE;
529 STDMETHOD(put_Language)(long pLanguage) PURE;
530 STDMETHOD(get_AudioStream)(long __RPC_FAR *pStream) PURE;
531 STDMETHOD(put_AudioStream)(long pStream) PURE;
532 STDMETHOD(get_SAMIStyle)(BSTR __RPC_FAR *pbstrStyle) PURE;
533 STDMETHOD(put_SAMIStyle)(BSTR pbstrStyle) PURE;
534 STDMETHOD(get_SAMILang)(BSTR __RPC_FAR *pbstrLang) PURE;
535 STDMETHOD(put_SAMILang)(BSTR pbstrLang) PURE;
536 STDMETHOD(get_SAMIFileName)(BSTR __RPC_FAR *pbstrFileName) PURE;
537 STDMETHOD(put_SAMIFileName)(BSTR pbstrFileName) PURE;
538 STDMETHOD(get_StreamCount)( long __RPC_FAR *pStreamCount) PURE;
539 STDMETHOD(get_ClientId)(BSTR __RPC_FAR *pbstrClientId) PURE;
540 STDMETHOD(get_ConnectionSpeed)(long __RPC_FAR *plConnectionSpeed) PURE;
541 STDMETHOD(get_AutoSize)(VARIANT_BOOL __RPC_FAR *pbool) PURE;
542 STDMETHOD(put_AutoSize)(VARIANT_BOOL pbool) PURE;
543 STDMETHOD(get_EnableFullScreenControls)(VARIANT_BOOL __RPC_FAR *pbVal) PURE;
544 STDMETHOD(put_EnableFullScreenControls)(VARIANT_BOOL pbVal) PURE;
545 STDMETHOD(get_ActiveMovie)(IDispatch __RPC_FAR *__RPC_FAR *ppdispatch) PURE;
546 STDMETHOD(get_NSPlay)(IDispatch __RPC_FAR *__RPC_FAR *ppdispatch) PURE;
547 STDMETHOD(get_WindowlessVideo)(VARIANT_BOOL __RPC_FAR *pbool) PURE;
548 STDMETHOD(put_WindowlessVideo)(VARIANT_BOOL pbool) PURE;
549 STDMETHOD(Play)(void) PURE;
550 STDMETHOD(Stop)(void) PURE;
551 STDMETHOD(Pause)(void) PURE;
552 STDMETHOD(GetMarkerTime)(long MarkerNum,
553 double __RPC_FAR *pMarkerTime) PURE;
554 STDMETHOD(GetMarkerName)(long MarkerNum,
555 BSTR __RPC_FAR *pbstrMarkerName) PURE;
556 STDMETHOD(AboutBox)(void) PURE;
557 STDMETHOD(GetCodecInstalled)(long CodecNum,
558 VARIANT_BOOL __RPC_FAR *pCodecInstalled) PURE;
559 STDMETHOD(GetCodecDescription)(long CodecNum,
560 BSTR __RPC_FAR *pbstrCodecDescription) PURE;
561 STDMETHOD(GetCodecURL)(long CodecNum,
562 BSTR __RPC_FAR *pbstrCodecURL) PURE;
563 STDMETHOD(GetMoreInfoURL)(MPMoreInfoType MoreInfoType,
564 BSTR __RPC_FAR *pbstrMoreInfoURL) PURE;
565 STDMETHOD(GetMediaInfoString)(MPMediaInfoType MediaInfoType,
566 BSTR __RPC_FAR *pbstrMediaInfo) PURE;
567 STDMETHOD(Cancel)(void) PURE;
568 STDMETHOD(Open)(BSTR bstrFileName) PURE;
569 STDMETHOD(IsSoundCardEnabled)(VARIANT_BOOL __RPC_FAR *pbSoundCard) PURE;
570 STDMETHOD(Next)(void) PURE;
571 STDMETHOD(Previous)(void) PURE;
572 STDMETHOD(StreamSelect)(long StreamNum) PURE;
573 STDMETHOD(FastForward)(void) PURE;
574 STDMETHOD(FastReverse)(void) PURE;
575 STDMETHOD(GetStreamName)(long StreamNum,
576 BSTR __RPC_FAR *pbstrStreamName) PURE;
577 STDMETHOD(GetStreamGroup)(long StreamNum,
578 long __RPC_FAR *pStreamGroup) PURE;
579 STDMETHOD(GetStreamSelected)(long StreamNum, VARIANT_BOOL __RPC_FAR *pStreamSelected) PURE;
580 };
581
582 struct IMediaPlayer2 : public IMediaPlayer
583 {
584 STDMETHOD(get_DVD)(struct IMediaPlayerDvd __RPC_FAR *__RPC_FAR *ppdispatch) PURE;
585 STDMETHOD(GetMediaParameter)(long EntryNum, BSTR bstrParameterName, BSTR __RPC_FAR *pbstrParameterValue) PURE;
586 STDMETHOD(GetMediaParameterName(long EntryNum, long Index, BSTR __RPC_FAR *pbstrParameterName) PURE;
587 STDMETHOD(get_EntryCount)(long __RPC_FAR *pNumberEntries) PURE;
588 STDMETHOD(GetCurrentEntry)(long __RPC_FAR *pEntryNumber) PURE;
589 STDMETHOD(SetCurrentEntry)(long EntryNumber) PURE;
590 STDMETHOD(ShowDialog)(MPShowDialogConstants mpDialogIndex) PURE;
591 };
592
593 //---------------------------------------------------------------------------
594 // NETSHOW COM INTERFACES (dumped from nscompat.idl from MSVC COM Browser)
595 //---------------------------------------------------------------------------
596
597 struct INSOPlay : public IDispatch
598 {
599 STDMETHOD(get_ImageSourceWidth)(long __RPC_FAR *pWidth) PURE;
600 STDMETHOD(get_ImageSourceHeight)(long __RPC_FAR *pHeight) PURE;
601 STDMETHOD(get_Duration)(double __RPC_FAR *pDuration) PURE;
602 STDMETHOD(get_Author)(BSTR __RPC_FAR *pbstrAuthor) PURE;
603 STDMETHOD(get_Copyright)(BSTR __RPC_FAR *pbstrCopyright) PURE;
604 STDMETHOD(get_Description)(BSTR __RPC_FAR *pbstrDescription) PURE;
605 STDMETHOD(get_Rating)(BSTR __RPC_FAR *pbstrRating) PURE;
606 STDMETHOD(get_Title)(BSTR __RPC_FAR *pbstrTitle) PURE;
607 STDMETHOD(get_SourceLink)(BSTR __RPC_FAR *pbstrSourceLink) PURE;
608 STDMETHOD(get_MarkerCount)(long __RPC_FAR *pMarkerCount) PURE;
609 STDMETHOD(get_CanScan)(VARIANT_BOOL __RPC_FAR *pCanScan) PURE;
610 STDMETHOD(get_CanSeek)(VARIANT_BOOL __RPC_FAR *pCanSeek) PURE;
611 STDMETHOD(get_CanSeekToMarkers)(VARIANT_BOOL __RPC_FAR *pCanSeekToMarkers) PURE;
612 STDMETHOD(get_CreationDate)(DATE __RPC_FAR *pCreationDate) PURE;
613 STDMETHOD(get_Bandwidth)(long __RPC_FAR *pBandwidth) PURE;
614 STDMETHOD(get_ErrorCorrection)(BSTR __RPC_FAR *pbstrErrorCorrection) PURE;
615 STDMETHOD(get_AutoStart)(VARIANT_BOOL __RPC_FAR *pAutoStart) PURE;
616 STDMETHOD(put_AutoStart)(VARIANT_BOOL pAutoStart) PURE;
617 STDMETHOD(get_AutoRewind)(VARIANT_BOOL __RPC_FAR *pAutoRewind) PURE;
618 STDMETHOD(put_AutoRewind)(VARIANT_BOOL pAutoRewind) PURE;
619 STDMETHOD(get_AllowChangeControlType)(VARIANT_BOOL __RPC_FAR *pAllowChangeControlType) PURE;
620 STDMETHOD(put_AllowChangeControlType)(VARIANT_BOOL pAllowChangeControlType) PURE;
621 STDMETHOD(get_InvokeURLs)(VARIANT_BOOL __RPC_FAR *pInvokeURLs) PURE;
622 STDMETHOD(put_InvokeURLs)(VARIANT_BOOL pInvokeURLs) PURE;
623 STDMETHOD(get_EnableContextMenu)(VARIANT_BOOL __RPC_FAR *pEnableContextMenu) PURE;
624 STDMETHOD(put_EnableContextMenu)(VARIANT_BOOL pEnableContextMenu) PURE;
625 STDMETHOD(get_TransparentAtStart)(VARIANT_BOOL __RPC_FAR *pTransparentAtStart) PURE;
626 STDMETHOD(put_TransparentAtStart)(VARIANT_BOOL pTransparentAtStart) PURE;
627 STDMETHOD(get_TransparentOnStop)(VARIANT_BOOL __RPC_FAR *pTransparentOnStop) PURE;
628 STDMETHOD(put_TransparentOnStop)(VARIANT_BOOL pTransparentOnStop) PURE;
629 STDMETHOD(get_ClickToPlay)(VARIANT_BOOL __RPC_FAR *pClickToPlay) PURE;
630 STDMETHOD(put_ClickToPlay)(VARIANT_BOOL pClickToPlay) PURE;
631 STDMETHOD(get_FileName)(BSTR __RPC_FAR *pbstrFileName) PURE;
632 STDMETHOD(put_FileName)(BSTR pbstrFileName) PURE;
633 STDMETHOD(get_CurrentPosition)(double __RPC_FAR *pCurrentPosition) PURE;
634 STDMETHOD(put_CurrentPosition)(double pCurrentPosition) PURE;
635 STDMETHOD(get_Rate)(double __RPC_FAR *pRate) PURE;
636 STDMETHOD(put_Rate)(double pRate) PURE;
637 STDMETHOD(get_CurrentMarker)(long __RPC_FAR *pCurrentMarker) PURE;
638 STDMETHOD(put_CurrentMarker)(long pCurrentMarker) PURE;
639 STDMETHOD(get_PlayCount)(long __RPC_FAR *pPlayCount) PURE;
640 STDMETHOD(put_PlayCount)(long pPlayCount) PURE;
641 STDMETHOD(get_CurrentState)(long __RPC_FAR *pCurrentState) PURE;
642 STDMETHOD(get_DisplaySize)(long __RPC_FAR *pDisplaySize) PURE;
643 STDMETHOD(put_DisplaySize)(long pDisplaySize) PURE;
644 STDMETHOD(get_MainWindow)(long __RPC_FAR *pMainWindow) PURE;
645 STDMETHOD(get_ControlType)(long __RPC_FAR *pControlType) PURE;
646 STDMETHOD(put_ControlType)(long pControlType) PURE;
647 STDMETHOD(get_AllowScan)(VARIANT_BOOL __RPC_FAR *pAllowScan) PURE;
648 STDMETHOD(put_AllowScan)(VARIANT_BOOL pAllowScan) PURE;
649 STDMETHOD(get_SendKeyboardEvents)(VARIANT_BOOL __RPC_FAR *pSendKeyboardEvents) PURE;
650 STDMETHOD(put_SendKeyboardEvents)(VARIANT_BOOL pSendKeyboardEvents) PURE;
651 STDMETHOD(get_SendMouseClickEvents)(VARIANT_BOOL __RPC_FAR *pSendMouseClickEvents) PURE;
652 STDMETHOD(put_SendMouseClickEvents)(VARIANT_BOOL pSendMouseClickEvents) PURE;
653 STDMETHOD(get_SendMouseMoveEvents)(VARIANT_BOOL __RPC_FAR *pSendMouseMoveEvents) PURE;
654 STDMETHOD(put_SendMouseMoveEvents)(VARIANT_BOOL pSendMouseMoveEvents) PURE;
655 STDMETHOD(get_SendStateChangeEvents)(VARIANT_BOOL __RPC_FAR *pSendStateChangeEvents) PURE;
656 STDMETHOD(put_SendStateChangeEvents)(VARIANT_BOOL pSendStateChangeEvents) PURE;
657 STDMETHOD(get_ReceivedPackets)(long __RPC_FAR *pReceivedPackets) PURE;
658 STDMETHOD(get_RecoveredPackets)(long __RPC_FAR *pRecoveredPackets) PURE;
659 STDMETHOD(get_LostPackets)(long __RPC_FAR *pLostPackets) PURE;
660 STDMETHOD(get_ReceptionQuality)(long __RPC_FAR *pReceptionQuality) PURE;
661 STDMETHOD(get_BufferingCount)(long __RPC_FAR *pBufferingCount) PURE;
662 STDMETHOD(get_CursorType)(long __RPC_FAR *pCursorType) PURE;
663 STDMETHOD(put_CursorType)(long pCursorType) PURE;
664 STDMETHOD(get_AnimationAtStart)(VARIANT_BOOL __RPC_FAR *pAnimationAtStart) PURE;
665 STDMETHOD(put_AnimationAtStart)(VARIANT_BOOL pAnimationAtStart) PURE;
666 STDMETHOD(get_AnimationOnStop)(VARIANT_BOOL __RPC_FAR *pAnimationOnStop) PURE;
667 STDMETHOD(put_AnimationOnStop)(VARIANT_BOOL pAnimationOnStop) PURE;
668 STDMETHOD(Play)(void) PURE;
669 STDMETHOD(Pause)(void) PURE;
670 STDMETHOD(Stop)(void) PURE;
671 STDMETHOD(GetMarkerTime)(long MarkerNum, double __RPC_FAR *pMarkerTime) PURE;
672 STDMETHOD(GetMarkerName)(long MarkerNum, BSTR __RPC_FAR *pbstrMarkerName) PURE;
673 };
674
675 struct INSPlay : public INSOPlay
676 {
677 STDMETHOD(get_ChannelName)(BSTR __RPC_FAR *pbstrChannelName) PURE;
678 STDMETHOD(get_ChannelDescription)(BSTR __RPC_FAR *pbstrChannelDescription) PURE;
679 STDMETHOD(get_ChannelURL)(BSTR __RPC_FAR *pbstrChannelURL) PURE;
680 STDMETHOD(get_ContactAddress)(BSTR __RPC_FAR *pbstrContactAddress) PURE;
681 STDMETHOD(get_ContactPhone)(BSTR __RPC_FAR *pbstrContactPhone) PURE;
682 STDMETHOD(get_ContactEmail)(BSTR __RPC_FAR *pbstrContactEmail) PURE;
683 STDMETHOD(get_AllowChangeDisplaySize)(VARIANT_BOOL __RPC_FAR *pAllowChangeDisplaySize) PURE;
684 STDMETHOD(put_AllowChangeDisplaySize)(VARIANT_BOOL pAllowChangeDisplaySize) PURE;
685 STDMETHOD(get_CodecCount)(long __RPC_FAR *pCodecCount) PURE;
686 STDMETHOD(get_IsBroadcast)(VARIANT_BOOL __RPC_FAR *pIsBroadcast) PURE;
687 STDMETHOD(get_IsDurationValid)(VARIANT_BOOL __RPC_FAR *pIsDurationValid) PURE;
688 STDMETHOD(get_SourceProtocol)(long __RPC_FAR *pSourceProtocol) PURE;
689 STDMETHOD(get_OpenState)(long __RPC_FAR *pOpenState) PURE;
690 STDMETHOD(get_SendOpenStateChangeEvents)(VARIANT_BOOL __RPC_FAR *pSendOpenStateChangeEvents) PURE;
691 STDMETHOD(put_SendOpenStateChangeEvents)(VARIANT_BOOL pSendOpenStateChangeEvents) PURE;
692 STDMETHOD(get_SendWarningEvents)(VARIANT_BOOL __RPC_FAR *pSendWarningEvents) PURE;
693 STDMETHOD(put_SendWarningEvents)(VARIANT_BOOL pSendWarningEvents) PURE;
694 STDMETHOD(get_SendErrorEvents)(VARIANT_BOOL __RPC_FAR *pSendErrorEvents) PURE;
695 STDMETHOD(put_SendErrorEvents)(VARIANT_BOOL pSendErrorEvents) PURE;
696 STDMETHOD(get_HasError)(VARIANT_BOOL __RPC_FAR *pHasError) PURE;
697 STDMETHOD(get_ErrorDescription)(BSTR __RPC_FAR *pbstrErrorDescription) PURE;
698 STDMETHOD(get_ErrorCode)(long __RPC_FAR *pErrorCode) PURE;
699 STDMETHOD(get_PlayState)(long __RPC_FAR *pPlayState) PURE;
700 STDMETHOD(get_SendPlayStateChangeEvents)(VARIANT_BOOL __RPC_FAR *pSendPlayStateChangeEvents) PURE;
701 STDMETHOD(put_SendPlayStateChangeEvents)(VARIANT_BOOL pSendPlayStateChangeEvents) PURE;
702 STDMETHOD(get_BufferingTime)(double __RPC_FAR *pBufferingTime) PURE;
703 STDMETHOD(put_BufferingTime)(double pBufferingTime) PURE;
704 STDMETHOD(get_UseFixedUDPPort)(VARIANT_BOOL __RPC_FAR *pUseFixedUDPPort) PURE;
705 STDMETHOD(put_UseFixedUDPPort)(VARIANT_BOOL pUseFixedUDPPort) PURE;
706 STDMETHOD(get_FixedUDPPort)(long __RPC_FAR *pFixedUDPPort) PURE;
707 STDMETHOD(put_FixedUDPPort)(long pFixedUDPPort) PURE;
708 STDMETHOD(get_UseHTTPProxy)(VARIANT_BOOL __RPC_FAR *pUseHTTPProxy) PURE;
709 STDMETHOD(put_UseHTTPProxy)(VARIANT_BOOL pUseHTTPProxy) PURE;
710 STDMETHOD(get_EnableAutoProxy)(VARIANT_BOOL __RPC_FAR *pEnableAutoProxy) PURE;
711 STDMETHOD(put_EnableAutoProxy)(VARIANT_BOOL pEnableAutoProxy) PURE;
712 STDMETHOD(get_HTTPProxyHost)(BSTR __RPC_FAR *pbstrHTTPProxyHost) PURE;
713 STDMETHOD(put_HTTPProxyHost)(BSTR pbstrHTTPProxyHost) PURE;
714 STDMETHOD(get_HTTPProxyPort)(long __RPC_FAR *pHTTPProxyPort) PURE;
715 STDMETHOD(put_HTTPProxyPort)(long pHTTPProxyPort) PURE;
716 STDMETHOD(get_EnableMulticast)(VARIANT_BOOL __RPC_FAR *pEnableMulticast) PURE;
717 STDMETHOD(put_EnableMulticast)(VARIANT_BOOL pEnableMulticast) PURE;
718 STDMETHOD(get_EnableUDP)(VARIANT_BOOL __RPC_FAR *pEnableUDP) PURE;
719 STDMETHOD(put_EnableUDP)(VARIANT_BOOL pEnableUDP) PURE;
720 STDMETHOD(get_EnableTCP)(VARIANT_BOOL __RPC_FAR *pEnableTCP) PURE;
721 STDMETHOD(put_EnableTCP)(VARIANT_BOOL pEnableTCP) PURE;
722 STDMETHOD(get_EnableHTTP)(VARIANT_BOOL __RPC_FAR *pEnableHTTP) PURE;
723 STDMETHOD(put_EnableHTTP)(VARIANT_BOOL pEnableHTTP) PURE;
724 STDMETHOD(get_BufferingProgress)(long __RPC_FAR *pBufferingProgress) PURE;
725 STDMETHOD(get_BaseURL)(BSTR __RPC_FAR *pbstrBaseURL) PURE;
726 STDMETHOD(put_BaseURL)(BSTR pbstrBaseURL) PURE;
727 STDMETHOD(get_DefaultFrame)(BSTR __RPC_FAR *pbstrDefaultFrame) PURE;
728 STDMETHOD(put_DefaultFrame)(BSTR pbstrDefaultFrame) PURE;
729 STDMETHOD(AboutBox))(void) PURE;
730 STDMETHOD(Cancel)(void) PURE;
731 STDMETHOD(GetCodecInstalled)(long CodecNum, VARIANT_BOOL __RPC_FAR *pCodecInstalled) PURE;
732 STDMETHOD(GetCodecDescription)(long CodecNum, BSTR __RPC_FAR *pbstrCodecDescription) PURE;
733 STDMETHOD(GetCodecURL)(long CodecNum, BSTR __RPC_FAR *pbstrCodecURL) PURE;
734 STDMETHOD(Open)(BSTR bstrFileName) PURE;
735 };
736
737
738 struct INSPlay1 : public INSPlay
739 {
740 STDMETHOD(get_MediaPlayer)(IDispatch __RPC_FAR *__RPC_FAR *ppdispatch) PURE;
741 };
742
743 //---------------------------------------------------------------------------
744 // MISC COM INTERFACES
745 //---------------------------------------------------------------------------
746 typedef enum _FilterState
747 {
748 State_Stopped,
749 State_Paused,
750 State_Running
751 } FILTER_STATE;
752 typedef enum _PinDirection {
753 PINDIR_INPUT,
754 PINDIR_OUTPUT
755 } PIN_DIRECTION;
756
757 typedef struct _FilterInfo {
758 WCHAR achName[128];
759 struct IFilterGraph *pGraph;
760 } FILTER_INFO;
761
762 typedef struct _PinInfo {
763 struct IBaseFilter *pFilter;
764 PIN_DIRECTION dir;
765 WCHAR achName[128];
766 } PIN_INFO;
767
768 struct IBaseFilter;
769 struct IPin;
770 struct IEnumFilters;
771 typedef struct _MediaType {
772 GUID majortype;
773 GUID subtype;
774 BOOL bFixedSizeSamples;
775 BOOL bTemporalCompression;
776 ULONG lSampleSize;
777 GUID formattype;
778 IUnknown *pUnk;
779 ULONG cbFormat;
780 BYTE *pbFormat;
781 } AM_MEDIA_TYPE;
782
783 struct IFilterGraph : public IUnknown
784 {
785 STDMETHOD(AddFilter)(IBaseFilter *, LPCWSTR) PURE;
786 STDMETHOD(RemoveFilter)(IBaseFilter *) PURE;
787 STDMETHOD(EnumFilters)(IEnumFilters **) PURE;
788 STDMETHOD(FindFilterByName)(LPCWSTR, IBaseFilter **) PURE;
789 STDMETHOD(ConnectDirect)(IPin *, IPin *, const AM_MEDIA_TYPE *) PURE;
790 STDMETHOD(Reconnect)(IPin *) PURE;
791 STDMETHOD(Disconnect)(IPin *) PURE;
792 STDMETHOD(SetDefaultSyncSource)() PURE;
793 };
794
795 struct IGraphBuilder : public IFilterGraph
796 {
797 STDMETHOD(Connect)(IPin *, IPin *) PURE;
798 STDMETHOD(Render)(IPin *) PURE;
799 STDMETHOD(RenderFile)(LPCWSTR, LPCWSTR) PURE;
800 STDMETHOD(AddSourceFilter)(LPCWSTR, LPCWSTR, IBaseFilter **) PURE;
801 STDMETHOD(SetLogFile)(DWORD_PTR) PURE;
802 STDMETHOD(Abort)() PURE;
803 STDMETHOD(ShouldOperationContinue)() PURE;
804 };
805
806 struct IReferenceClock;
807 struct IEnumPins;
808 #define REFERENCE_TIME LONGLONG
809 struct IMediaFilter : public IPersist
810 {
811 STDMETHOD(Stop)( void) PURE;
812 STDMETHOD(Pause)( void) PURE;
813 STDMETHOD(Run)(REFERENCE_TIME tStart) PURE;
814 STDMETHOD(GetState)(DWORD dwMilliSecsTimeout,
815 FILTER_STATE *State) PURE;
816 STDMETHOD(SetSyncSource)(IReferenceClock *pClock) PURE;
817 STDMETHOD(GetSyncSource)(IReferenceClock **pClock) PURE;
818 };
819
820 struct IBaseFilter : public IMediaFilter
821 {
822 STDMETHOD(EnumPins)(IEnumPins **ppEnum) PURE;
823 STDMETHOD(FindPin)(LPCWSTR Id, IPin **ppPin) PURE;
824 STDMETHOD(QueryFilterInfo)(FILTER_INFO *pInfo) PURE;
825 STDMETHOD(JoinFilterGraph)(IFilterGraph *pGraph, LPCWSTR pName) PURE;
826 STDMETHOD(QueryVendorInfo)(LPWSTR *pVendorInfo) PURE;
827 };
828
829
830 //###########################################################################
831 //
832 //
833 // wxAMMediaBackend
834 //
835 //
836 //###########################################################################
837
838 typedef BOOL (WINAPI* LPAMGETERRORTEXT)(HRESULT, wxChar *, DWORD);
839
840 class WXDLLIMPEXP_MEDIA wxAMMediaBackend : public wxMediaBackendCommonBase
841 {
842 public:
843 wxAMMediaBackend();
844 virtual ~wxAMMediaBackend();
845 void Clear();
846
847 virtual bool CreateControl(wxControl* ctrl, wxWindow* parent,
848 wxWindowID id,
849 const wxPoint& pos,
850 const wxSize& size,
851 long style,
852 const wxValidator& validator,
853 const wxString& name);
854
855 virtual bool Play();
856 virtual bool Pause();
857 virtual bool Stop();
858
859 virtual bool Load(const wxString& fileName);
860 virtual bool Load(const wxURI& location);
861 virtual bool Load(const wxURI& location, const wxURI& proxy);
862
863 bool DoLoad(const wxString& location);
864 void FinishLoad();
865
866 virtual wxMediaState GetState();
867
868 virtual bool SetPosition(wxLongLong where);
869 virtual wxLongLong GetPosition();
870 virtual wxLongLong GetDuration();
871
872 virtual void Move(int x, int y, int w, int h);
873 wxSize GetVideoSize() const;
874
875 virtual double GetPlaybackRate();
876 virtual bool SetPlaybackRate(double);
877
878 virtual double GetVolume();
879 virtual bool SetVolume(double);
880
881 virtual bool ShowPlayerControls(wxMediaCtrlPlayerControls flags);
882 void Cleanup();
883
884 void DoGetDownloadProgress(wxLongLong*, wxLongLong*);
885 virtual wxLongLong GetDownloadProgress()
886 {
887 wxLongLong progress, total;
888 DoGetDownloadProgress(&progress, &total);
889 return progress;
890 }
891 virtual wxLongLong GetDownloadTotal()
892 {
893 wxLongLong progress, total;
894 DoGetDownloadProgress(&progress, &total);
895 return total;
896 }
897
898 wxActiveXContainer* m_pAX;
899 IActiveMovie* m_pAM;
900 IMediaPlayer* m_pMP;
901 wxTimer* m_pTimer;
902 wxSize m_bestSize;
903
904 #ifdef __WXDEBUG__
905 wxDynamicLibrary m_dllQuartz;
906 LPAMGETERRORTEXT m_lpAMGetErrorText;
907 wxString GetErrorString(HRESULT hrdsv);
908 #endif // __WXDEBUG__
909
910 DECLARE_DYNAMIC_CLASS(wxAMMediaBackend)
911 };
912
913 //---------------------------------------------------------------------------
914 //
915 // wxMCIMediaBackend
916 //
917 //---------------------------------------------------------------------------
918
919 //---------------------------------------------------------------------------
920 // MCI Includes
921 //---------------------------------------------------------------------------
922 #ifndef __WXWINCE__
923 #include <mmsystem.h>
924
925 class WXDLLIMPEXP_MEDIA wxMCIMediaBackend : public wxMediaBackendCommonBase
926 {
927 public:
928
929 wxMCIMediaBackend();
930 ~wxMCIMediaBackend();
931
932 virtual bool CreateControl(wxControl* ctrl, wxWindow* parent,
933 wxWindowID id,
934 const wxPoint& pos,
935 const wxSize& size,
936 long style,
937 const wxValidator& validator,
938 const wxString& name);
939
940 virtual bool Play();
941 virtual bool Pause();
942 virtual bool Stop();
943
944 virtual bool Load(const wxURI& location,
945 const wxURI& proxy)
946 { return wxMediaBackend::Load(location, proxy); }
947
948 virtual bool Load(const wxString& fileName);
949 virtual bool Load(const wxURI& location);
950
951 virtual wxMediaState GetState();
952
953 virtual bool SetPosition(wxLongLong where);
954 virtual wxLongLong GetPosition();
955 virtual wxLongLong GetDuration();
956
957 virtual void Move(int x, int y, int w, int h);
958 wxSize GetVideoSize() const;
959
960 virtual double GetPlaybackRate();
961 virtual bool SetPlaybackRate(double dRate);
962
963 virtual double GetVolume();
964 virtual bool SetVolume(double);
965
966 static LRESULT CALLBACK NotifyWndProc(HWND hWnd, UINT nMsg,
967 WPARAM wParam, LPARAM lParam);
968
969 LRESULT CALLBACK OnNotifyWndProc(HWND hWnd, UINT nMsg,
970 WPARAM wParam, LPARAM lParam);
971
972 MCIDEVICEID m_hDev; //Our MCI Device ID/Handler
973 HWND m_hNotifyWnd; //Window to use for MCI events
974 bool m_bVideo; //Whether or not we have video
975
976 DECLARE_DYNAMIC_CLASS(wxMCIMediaBackend)
977 };
978 #endif
979
980 //---------------------------------------------------------------------------
981 //
982 // wxQTMediaBackend
983 //
984 // We don't include Quicktime headers here and define all the types
985 // ourselves because looking for the quicktime libaries etc. would
986 // be tricky to do and making this a dependency for the MSVC projects
987 // would be unrealistic.
988 //
989 // Thanks to Robert Roebling for the wxDL macro/library idea
990 //---------------------------------------------------------------------------
991
992 //---------------------------------------------------------------------------
993 // QT Includes
994 //---------------------------------------------------------------------------
995 //#include <qtml.h> //Windoze QT include
996 //#include <QuickTimeComponents.h> //Standard QT stuff
997 #include "wx/dynlib.h"
998
999 //---------------------------------------------------------------------------
1000 // QT Types
1001 //---------------------------------------------------------------------------
1002 typedef struct MovieRecord* Movie;
1003 typedef wxInt16 OSErr;
1004 typedef wxInt32 OSStatus;
1005 #define noErr 0
1006 #define fsRdPerm 1
1007 typedef unsigned char Str255[256];
1008 #define StringPtr unsigned char*
1009 #define newMovieActive 1
1010 #define newMovieAsyncOK (1 << 8)
1011 #define Ptr char*
1012 #define Handle Ptr*
1013 #define Fixed long
1014 #define OSType unsigned long
1015 #define CGrafPtr struct GrafPort *
1016 #define TimeScale long
1017 #define TimeBase struct TimeBaseRecord *
1018 typedef struct ComponentInstanceRecord * ComponentInstance;
1019 #define kMovieLoadStatePlayable 10000
1020 #define Boolean int
1021 #define MovieController ComponentInstance
1022
1023 #ifndef URLDataHandlerSubType
1024 #if defined(__WATCOMC__) || defined(__MINGW32__)
1025 // use magic numbers for compilers which complain about multicharacter integers
1026 const OSType URLDataHandlerSubType = 1970433056;
1027 const OSType VisualMediaCharacteristic = 1702454643;
1028 #else
1029 const OSType URLDataHandlerSubType = 'url ';
1030 const OSType VisualMediaCharacteristic = 'eyes';
1031 #endif
1032 #endif
1033
1034 struct FSSpec {
1035 short vRefNum;
1036 long parID;
1037 Str255 name; /*Str63 on mac, Str255 on msw */
1038 };
1039
1040 struct Rect {
1041 short top;
1042 short left;
1043 short bottom;
1044 short right;
1045 };
1046
1047 struct wide {
1048 wxInt32 hi;
1049 wxUint32 lo;
1050 };
1051
1052 struct TimeRecord {
1053 wide value; /* units */
1054 TimeScale scale; /* units per second */
1055 TimeBase base;
1056 };
1057
1058 struct Point {
1059 short v;
1060 short h;
1061 };
1062
1063 struct EventRecord {
1064 wxUint16 what;
1065 wxUint32 message;
1066 wxUint32 when;
1067 Point where;
1068 wxUint16 modifiers;
1069 };
1070
1071 enum {
1072 mcTopLeftMovie = 1,
1073 mcScaleMovieToFit = 2,
1074 mcWithBadge = 4,
1075 mcNotVisible = 8,
1076 mcWithFrame = 16
1077 };
1078
1079 //---------------------------------------------------------------------------
1080 // QT Library
1081 //---------------------------------------------------------------------------
1082 #define wxDL_METHOD_DEFINE( rettype, name, args, shortargs, defret ) \
1083 typedef rettype (* name ## Type) args ; \
1084 name ## Type pfn_ ## name; \
1085 rettype name args \
1086 { if (m_ok) return pfn_ ## name shortargs ; return defret; }
1087
1088 #define wxDL_VOIDMETHOD_DEFINE( name, args, shortargs ) \
1089 typedef void (* name ## Type) args ; \
1090 name ## Type pfn_ ## name; \
1091 void name args \
1092 { if (m_ok) pfn_ ## name shortargs ; }
1093
1094 #define wxDL_METHOD_LOAD( lib, name, success ) \
1095 pfn_ ## name = (name ## Type) lib.GetSymbol( wxT(#name), &success ); \
1096 if (!success) { wxLog::EnableLogging(bWasLoggingEnabled); return false; }
1097
1098
1099 class WXDLLIMPEXP_MEDIA wxQuickTimeLibrary
1100 {
1101 public:
1102 ~wxQuickTimeLibrary()
1103 {
1104 if(m_dll.IsLoaded())
1105 m_dll.Unload();
1106 }
1107
1108 bool Initialize();
1109 bool IsOk() const {return m_ok;}
1110
1111 protected:
1112 wxDynamicLibrary m_dll;
1113 bool m_ok;
1114
1115 public:
1116 wxDL_VOIDMETHOD_DEFINE( StartMovie, (Movie m), (m) );
1117 wxDL_VOIDMETHOD_DEFINE( StopMovie, (Movie m), (m) );
1118 wxDL_METHOD_DEFINE( bool, IsMovieDone, (Movie m), (m), false);
1119 wxDL_VOIDMETHOD_DEFINE( GoToBeginningOfMovie, (Movie m), (m) );
1120 wxDL_METHOD_DEFINE( OSErr, GetMoviesError, (), (), -1);
1121 wxDL_METHOD_DEFINE( OSErr, EnterMovies, (), (), -1);
1122 wxDL_VOIDMETHOD_DEFINE( ExitMovies, (), () );
1123 wxDL_METHOD_DEFINE( OSErr, InitializeQTML, (long flags), (flags), -1);
1124 wxDL_VOIDMETHOD_DEFINE( TerminateQTML, (), () );
1125
1126 wxDL_METHOD_DEFINE( OSErr, NativePathNameToFSSpec,
1127 (char* inName, FSSpec* outFile, long flags),
1128 (inName, outFile, flags), -1);
1129
1130 wxDL_METHOD_DEFINE( OSErr, OpenMovieFile,
1131 (const FSSpec * fileSpec, short * resRefNum, wxInt8 permission),
1132 (fileSpec, resRefNum, permission), -1 );
1133
1134 wxDL_METHOD_DEFINE( OSErr, CloseMovieFile,
1135 (short resRefNum), (resRefNum), -1);
1136
1137 wxDL_METHOD_DEFINE( OSErr, NewMovieFromFile,
1138 (Movie * theMovie, short resRefNum, short * resId,
1139 StringPtr resName, short newMovieFlags,
1140 bool * dataRefWasChanged),
1141 (theMovie, resRefNum, resId, resName, newMovieFlags,
1142 dataRefWasChanged), -1);
1143
1144 wxDL_VOIDMETHOD_DEFINE( SetMovieRate, (Movie m, Fixed rate), (m, rate) );
1145 wxDL_METHOD_DEFINE( Fixed, GetMovieRate, (Movie m), (m), 0);
1146 wxDL_VOIDMETHOD_DEFINE( MoviesTask, (Movie m, long maxms), (m, maxms) );
1147 wxDL_VOIDMETHOD_DEFINE( BlockMove,
1148 (const char* p1, const char* p2, long s), (p1,p2,s) );
1149 wxDL_METHOD_DEFINE( Handle, NewHandleClear, (long s), (s), NULL );
1150
1151 wxDL_METHOD_DEFINE( OSErr, NewMovieFromDataRef,
1152 (Movie * m, short flags, short * id,
1153 Handle dataRef, OSType dataRefType),
1154 (m,flags,id,dataRef,dataRefType), -1 );
1155
1156 wxDL_VOIDMETHOD_DEFINE( DisposeHandle, (Handle h), (h) );
1157 wxDL_VOIDMETHOD_DEFINE( GetMovieNaturalBoundsRect, (Movie m, Rect* r), (m,r) );
1158 wxDL_METHOD_DEFINE( void*, GetMovieIndTrackType,
1159 (Movie m, long index, OSType type, long flags),
1160 (m,index,type,flags), NULL );
1161 wxDL_VOIDMETHOD_DEFINE( CreatePortAssociation,
1162 (void* hWnd, void* junk, long morejunk), (hWnd, junk, morejunk) );
1163 wxDL_METHOD_DEFINE(void*, GetNativeWindowPort, (void* hWnd), (hWnd), NULL);
1164 wxDL_VOIDMETHOD_DEFINE(SetMovieGWorld, (Movie m, CGrafPtr port, void* whatever),
1165 (m, port, whatever) );
1166 wxDL_VOIDMETHOD_DEFINE(DisposeMovie, (Movie m), (m) );
1167 wxDL_VOIDMETHOD_DEFINE(SetMovieBox, (Movie m, Rect* r), (m,r));
1168 wxDL_VOIDMETHOD_DEFINE(SetMovieTimeScale, (Movie m, long s), (m,s));
1169 wxDL_METHOD_DEFINE(long, GetMovieDuration, (Movie m), (m), 0);
1170 wxDL_METHOD_DEFINE(TimeBase, GetMovieTimeBase, (Movie m), (m), 0);
1171 wxDL_METHOD_DEFINE(TimeScale, GetMovieTimeScale, (Movie m), (m), 0);
1172 wxDL_METHOD_DEFINE(long, GetMovieTime, (Movie m, void* cruft), (m,cruft), 0);
1173 wxDL_VOIDMETHOD_DEFINE(SetMovieTime, (Movie m, TimeRecord* tr), (m,tr) );
1174 wxDL_METHOD_DEFINE(short, GetMovieVolume, (Movie m), (m), 0);
1175 wxDL_VOIDMETHOD_DEFINE(SetMovieVolume, (Movie m, short sVolume), (m,sVolume) );
1176 wxDL_VOIDMETHOD_DEFINE(SetMovieTimeValue, (Movie m, long s), (m,s));
1177 wxDL_METHOD_DEFINE(ComponentInstance, NewMovieController, (Movie m, const Rect* mr, long fl), (m,mr,fl), 0);
1178 wxDL_VOIDMETHOD_DEFINE(DisposeMovieController, (ComponentInstance ci), (ci));
1179 wxDL_METHOD_DEFINE(int, MCSetVisible, (ComponentInstance m, int b), (m, b), 0);
1180
1181
1182 wxDL_VOIDMETHOD_DEFINE(PrePrerollMovie, (Movie m, long t, Fixed r, WXFARPROC p1, void* p2), (m,t,r,p1,p2) );
1183 wxDL_VOIDMETHOD_DEFINE(PrerollMovie, (Movie m, long t, Fixed r), (m,t,r) );
1184 wxDL_METHOD_DEFINE(Fixed, GetMoviePreferredRate, (Movie m), (m), 0);
1185 wxDL_METHOD_DEFINE(long, GetMovieLoadState, (Movie m), (m), 0);
1186 wxDL_METHOD_DEFINE(void*, NewRoutineDescriptor, (WXFARPROC f, int l, void* junk), (f, l, junk), 0);
1187 wxDL_VOIDMETHOD_DEFINE(DisposeRoutineDescriptor, (void* f), (f));
1188 wxDL_METHOD_DEFINE(void*, GetCurrentArchitecture, (), (), 0);
1189 wxDL_METHOD_DEFINE(int, MCDoAction, (ComponentInstance ci, long f, void* p), (ci,f,p), 0);
1190 wxDL_VOIDMETHOD_DEFINE(MCSetControllerBoundsRect, (ComponentInstance ci, Rect* r), (ci,r));
1191 wxDL_VOIDMETHOD_DEFINE(DestroyPortAssociation, (CGrafPtr g), (g));
1192 wxDL_VOIDMETHOD_DEFINE(NativeEventToMacEvent, (MSG* p1, EventRecord* p2), (p1,p2));
1193 wxDL_VOIDMETHOD_DEFINE(MCIsPlayerEvent, (ComponentInstance ci, EventRecord* p2), (ci, p2));
1194 wxDL_METHOD_DEFINE(int, MCSetMovie, (ComponentInstance ci, Movie m, void* p1, Point w),
1195 (ci,m,p1,w),0);
1196 wxDL_VOIDMETHOD_DEFINE(MCPositionController,
1197 (ComponentInstance ci, Rect* r, void* junk, void* morejunk), (ci,r,junk,morejunk));
1198 wxDL_VOIDMETHOD_DEFINE(MCSetActionFilterWithRefCon,
1199 (ComponentInstance ci, WXFARPROC cb, void* ref), (ci,cb,ref));
1200 wxDL_VOIDMETHOD_DEFINE(MCGetControllerInfo, (MovieController mc, long* flags), (mc,flags));
1201 wxDL_VOIDMETHOD_DEFINE(BeginUpdate, (CGrafPtr port), (port));
1202 wxDL_VOIDMETHOD_DEFINE(UpdateMovie, (Movie m), (m));
1203 wxDL_VOIDMETHOD_DEFINE(EndUpdate, (CGrafPtr port), (port));
1204 wxDL_METHOD_DEFINE( OSErr, GetMoviesStickyError, (), (), -1);
1205 };
1206
1207 bool wxQuickTimeLibrary::Initialize()
1208 {
1209 m_ok = false;
1210
1211 bool bWasLoggingEnabled = wxLog::EnableLogging(false); //Turn off the wxDynamicLibrary logging
1212
1213 if(!m_dll.Load(wxT("qtmlClient.dll")))
1214 {
1215 wxLog::EnableLogging(bWasLoggingEnabled);
1216 return false;
1217 }
1218
1219 wxDL_METHOD_LOAD( m_dll, StartMovie, m_ok );
1220 wxDL_METHOD_LOAD( m_dll, StopMovie, m_ok );
1221 wxDL_METHOD_LOAD( m_dll, IsMovieDone, m_ok );
1222 wxDL_METHOD_LOAD( m_dll, GoToBeginningOfMovie, m_ok );
1223 wxDL_METHOD_LOAD( m_dll, GetMoviesError, m_ok );
1224 wxDL_METHOD_LOAD( m_dll, EnterMovies, m_ok );
1225 wxDL_METHOD_LOAD( m_dll, ExitMovies, m_ok );
1226 wxDL_METHOD_LOAD( m_dll, InitializeQTML, m_ok );
1227 wxDL_METHOD_LOAD( m_dll, TerminateQTML, m_ok );
1228 wxDL_METHOD_LOAD( m_dll, NativePathNameToFSSpec, m_ok );
1229 wxDL_METHOD_LOAD( m_dll, OpenMovieFile, m_ok );
1230 wxDL_METHOD_LOAD( m_dll, CloseMovieFile, m_ok );
1231 wxDL_METHOD_LOAD( m_dll, NewMovieFromFile, m_ok );
1232 wxDL_METHOD_LOAD( m_dll, GetMovieRate, m_ok );
1233 wxDL_METHOD_LOAD( m_dll, SetMovieRate, m_ok );
1234 wxDL_METHOD_LOAD( m_dll, MoviesTask, m_ok );
1235 wxDL_METHOD_LOAD( m_dll, BlockMove, m_ok );
1236 wxDL_METHOD_LOAD( m_dll, NewHandleClear, m_ok );
1237 wxDL_METHOD_LOAD( m_dll, NewMovieFromDataRef, m_ok );
1238 wxDL_METHOD_LOAD( m_dll, DisposeHandle, m_ok );
1239 wxDL_METHOD_LOAD( m_dll, GetMovieNaturalBoundsRect, m_ok );
1240 wxDL_METHOD_LOAD( m_dll, GetMovieIndTrackType, m_ok );
1241 wxDL_METHOD_LOAD( m_dll, CreatePortAssociation, m_ok );
1242 wxDL_METHOD_LOAD( m_dll, DestroyPortAssociation, m_ok );
1243 wxDL_METHOD_LOAD( m_dll, GetNativeWindowPort, m_ok );
1244 wxDL_METHOD_LOAD( m_dll, SetMovieGWorld, m_ok );
1245 wxDL_METHOD_LOAD( m_dll, DisposeMovie, m_ok );
1246 wxDL_METHOD_LOAD( m_dll, SetMovieBox, m_ok );
1247 wxDL_METHOD_LOAD( m_dll, SetMovieTimeScale, m_ok );
1248 wxDL_METHOD_LOAD( m_dll, GetMovieDuration, m_ok );
1249 wxDL_METHOD_LOAD( m_dll, GetMovieTimeBase, m_ok );
1250 wxDL_METHOD_LOAD( m_dll, GetMovieTimeScale, m_ok );
1251 wxDL_METHOD_LOAD( m_dll, GetMovieTime, m_ok );
1252 wxDL_METHOD_LOAD( m_dll, SetMovieTime, m_ok );
1253 wxDL_METHOD_LOAD( m_dll, GetMovieVolume, m_ok );
1254 wxDL_METHOD_LOAD( m_dll, SetMovieVolume, m_ok );
1255 wxDL_METHOD_LOAD( m_dll, SetMovieTimeValue, m_ok );
1256 wxDL_METHOD_LOAD( m_dll, NewMovieController, m_ok );
1257 wxDL_METHOD_LOAD( m_dll, DisposeMovieController, m_ok );
1258 wxDL_METHOD_LOAD( m_dll, MCSetVisible, m_ok );
1259 wxDL_METHOD_LOAD( m_dll, PrePrerollMovie, m_ok );
1260 wxDL_METHOD_LOAD( m_dll, PrerollMovie, m_ok );
1261 wxDL_METHOD_LOAD( m_dll, GetMoviePreferredRate, m_ok );
1262 wxDL_METHOD_LOAD( m_dll, GetMovieLoadState, m_ok );
1263 wxDL_METHOD_LOAD( m_dll, MCDoAction, m_ok );
1264 wxDL_METHOD_LOAD( m_dll, MCSetControllerBoundsRect, m_ok );
1265 wxDL_METHOD_LOAD( m_dll, NativeEventToMacEvent, m_ok );
1266 wxDL_METHOD_LOAD( m_dll, MCIsPlayerEvent, m_ok );
1267 wxDL_METHOD_LOAD( m_dll, MCSetMovie, m_ok );
1268 wxDL_METHOD_LOAD( m_dll, MCSetActionFilterWithRefCon, m_ok );
1269 wxDL_METHOD_LOAD( m_dll, MCGetControllerInfo, m_ok );
1270 wxDL_METHOD_LOAD( m_dll, BeginUpdate, m_ok );
1271 wxDL_METHOD_LOAD( m_dll, UpdateMovie, m_ok );
1272 wxDL_METHOD_LOAD( m_dll, EndUpdate, m_ok );
1273 wxDL_METHOD_LOAD( m_dll, GetMoviesStickyError, m_ok );
1274
1275 wxLog::EnableLogging(bWasLoggingEnabled);
1276 m_ok = true;
1277
1278 return true;
1279 }
1280
1281 class WXDLLIMPEXP_MEDIA wxQTMediaBackend : public wxMediaBackendCommonBase
1282 {
1283 public:
1284 wxQTMediaBackend();
1285 ~wxQTMediaBackend();
1286
1287 virtual bool CreateControl(wxControl* ctrl, wxWindow* parent,
1288 wxWindowID id,
1289 const wxPoint& pos,
1290 const wxSize& size,
1291 long style,
1292 const wxValidator& validator,
1293 const wxString& name);
1294
1295 virtual bool Play();
1296 virtual bool Pause();
1297 virtual bool Stop();
1298
1299 virtual bool Load(const wxURI& location,
1300 const wxURI& proxy)
1301 { return wxMediaBackend::Load(location, proxy); }
1302
1303 virtual bool Load(const wxString& fileName);
1304 virtual bool Load(const wxURI& location);
1305
1306 virtual wxMediaState GetState();
1307
1308 virtual bool SetPosition(wxLongLong where);
1309 virtual wxLongLong GetPosition();
1310 virtual wxLongLong GetDuration();
1311
1312 virtual void Move(int x, int y, int w, int h);
1313 wxSize GetVideoSize() const;
1314
1315 virtual double GetPlaybackRate();
1316 virtual bool SetPlaybackRate(double dRate);
1317
1318 virtual double GetVolume();
1319 virtual bool SetVolume(double);
1320
1321 void Cleanup();
1322 void FinishLoad();
1323
1324 static void PPRMProc (Movie theMovie, OSErr theErr, void* theRefCon);
1325 //TODO: Last param actually long - does this work on 64bit machines?
1326 static Boolean MCFilterProc (MovieController theController,
1327 short action, void *params, LONG_PTR refCon);
1328
1329 static LRESULT CALLBACK QTWndProc(HWND, UINT, WPARAM, LPARAM);
1330
1331 virtual bool ShowPlayerControls(wxMediaCtrlPlayerControls flags);
1332
1333 wxSize m_bestSize; //Original movie size
1334 Movie m_movie; //QT Movie handle/instance
1335 bool m_bVideo; //Whether or not we have video
1336 bool m_bPlaying; //Whether or not movie is playing
1337 wxTimer* m_timer; //Load or Play timer
1338 wxQuickTimeLibrary m_lib; //DLL to load functions from
1339 ComponentInstance m_pMC; //Movie Controller
1340
1341 friend class wxQTMediaEvtHandler;
1342 DECLARE_DYNAMIC_CLASS(wxQTMediaBackend)
1343 };
1344
1345 // helper to hijack background erasing for the QT window
1346 class WXDLLIMPEXP_MEDIA wxQTMediaEvtHandler : public wxEvtHandler
1347 {
1348 public:
1349 wxQTMediaEvtHandler(wxQTMediaBackend *qtb, WXHWND hwnd)
1350 {
1351 m_qtb = qtb;
1352 m_hwnd = hwnd;
1353
1354 m_qtb->m_ctrl->Connect(m_qtb->m_ctrl->GetId(),
1355 wxEVT_ERASE_BACKGROUND,
1356 wxEraseEventHandler(wxQTMediaEvtHandler::OnEraseBackground),
1357 NULL, this
1358 );
1359 }
1360
1361 void OnEraseBackground(wxEraseEvent& event);
1362
1363 private:
1364 wxQTMediaBackend *m_qtb;
1365 WXHWND m_hwnd;
1366
1367 DECLARE_NO_COPY_CLASS(wxQTMediaEvtHandler)
1368 };
1369
1370
1371 //===========================================================================
1372 // IMPLEMENTATION
1373 //===========================================================================
1374
1375 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1376 //
1377 // wxAMMediaBackend
1378 //
1379 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1380
1381 IMPLEMENT_DYNAMIC_CLASS(wxAMMediaBackend, wxMediaBackend)
1382
1383 //---------------------------------------------------------------------------
1384 // Usual debugging macros
1385 //---------------------------------------------------------------------------
1386 #ifdef __WXDEBUG__
1387 #define MAX_ERROR_TEXT_LEN 160
1388
1389 //Get the error string for Active Movie
1390 wxString wxAMMediaBackend::GetErrorString(HRESULT hrdsv)
1391 {
1392 wxChar szError[MAX_ERROR_TEXT_LEN];
1393 if( m_lpAMGetErrorText != NULL &&
1394 (*m_lpAMGetErrorText)(hrdsv, szError, MAX_ERROR_TEXT_LEN) == 0)
1395 {
1396 return wxString::Format(wxT("DirectShow error \"%s\" \n")
1397 wxT("(numeric %X)\n")
1398 wxT("occured"),
1399 szError, (int)hrdsv);
1400 }
1401 else
1402 {
1403 return wxString::Format(wxT("Unknown error \n")
1404 wxT("(numeric %X)\n")
1405 wxT("occured"),
1406 (int)hrdsv);
1407 }
1408 }
1409
1410 #define wxAMFAIL(x) wxFAIL_MSG(GetErrorString(x));
1411 #define wxVERIFY(x) wxASSERT((x))
1412 #define wxAMLOG(x) wxLogDebug(GetErrorString(x))
1413 #else
1414 #define wxAMVERIFY(x) (x)
1415 #define wxVERIFY(x) (x)
1416 #define wxAMLOG(x)
1417 #define wxAMFAIL(x)
1418 #endif
1419
1420 //---------------------------------------------------------------------------
1421 // Standard macros for ease of use
1422 //---------------------------------------------------------------------------
1423 #define SAFE_RELEASE(x) { if (x) x->Release(); x = NULL; }
1424
1425 //---------------------------------------------------------------------------
1426 // wxAMLoadTimer
1427 //
1428 // Queries the control periodically to see if it has reached the point
1429 // in its loading cycle where we can begin playing the media - if so
1430 // then we finish up some things like getting the original size of the video
1431 // and then sending the loaded event to our handler
1432 //---------------------------------------------------------------------------
1433 class wxAMLoadTimer : public wxTimer
1434 {
1435 public:
1436 wxAMLoadTimer(wxAMMediaBackend* parent) :
1437 m_parent(parent) {}
1438
1439 void Notify()
1440 {
1441 if(m_parent->m_pMP)
1442 {
1443 MPReadyStateConstants nState;
1444 m_parent->m_pMP->get_ReadyState(&nState);
1445 if(nState != mpReadyStateLoading)
1446 {
1447 Stop();
1448 m_parent->FinishLoad();
1449 delete this;
1450 }
1451 }
1452 else
1453 {
1454 IActiveMovie2* pAM2 = NULL;
1455 ReadyStateConstants nState;
1456 if(m_parent->m_pAM->QueryInterface(IID_IActiveMovie2,
1457 (void**)&pAM2) == 0 &&
1458 pAM2->get_ReadyState(&nState) == 0)
1459 {
1460 pAM2->Release();
1461 if(nState != amvLoading)
1462 {
1463 Stop();
1464 m_parent->FinishLoad();
1465 delete this;
1466 }
1467 }
1468 else
1469 {
1470 if(pAM2)
1471 pAM2->Release();
1472
1473 Stop();
1474 m_parent->FinishLoad();
1475 delete this;
1476 }
1477 }
1478
1479 }
1480
1481 protected:
1482 wxAMMediaBackend* m_parent; //Backend pointer
1483 };
1484
1485 //---------------------------------------------------------------------------
1486 // wxAMPlayTimer
1487 //
1488 // Sets m_hNotifyWnd to NULL to signify that we haven't loaded anything yet
1489 // Queries the control periodically to see if it has stopped -
1490 // if it has it sends the stop event
1491 //---------------------------------------------------------------------------
1492 class wxAMPlayTimer : public wxTimer
1493 {
1494 public:
1495 wxAMPlayTimer(wxAMMediaBackend* parent) :
1496 m_parent(parent) {}
1497
1498 void Notify()
1499 {
1500 if(m_parent->GetState() == wxMEDIASTATE_STOPPED &&
1501 //NB: Stop events could get triggered by the interface
1502 //if ShowPlayerControls is enabled,
1503 //so we need this hack here to make an attempt
1504 //at it not getting sent - but its far from ideal -
1505 //they can still get sent in some cases
1506 m_parent->GetPosition() == m_parent->GetDuration())
1507 {
1508 if ( m_parent->SendStopEvent() )
1509 {
1510 //Seek to beginning of movie
1511 m_parent->wxAMMediaBackend::SetPosition(0);
1512 Stop();
1513
1514 //send the event to our child
1515 m_parent->QueueFinishEvent();
1516 }
1517 }
1518 }
1519
1520 protected:
1521 wxAMMediaBackend* m_parent; //Backend pointer
1522 };
1523
1524
1525 /*
1526 // The following is an alternative way - but it doesn't seem
1527 // to work with the IActiveMovie control - it probably processes
1528 // its own events
1529 //---------------------------------------------------------------------------
1530 // wxAMPlayTimer
1531 //
1532 // Query the IMediaEvent interface from the embedded WMP's
1533 // filtergraph, then process the events from it - sending
1534 // EC_COMPLETE events as stop events to the media control.
1535 //---------------------------------------------------------------------------
1536 class wxAMPlayTimer : public wxTimer
1537 {
1538 public:
1539 wxAMPlayTimer(wxAMMediaBackend* pBE) : m_pBE(pBE), m_pME(NULL)
1540 {
1541 HRESULT hr;
1542 IUnknown* pGB;
1543 hr = m_pBE->m_pAM->get_FilterGraph(&pGB);
1544 wxASSERT(SUCCEEDED(hr));
1545 hr = pGB->QueryInterface(IID_IMediaEvent, (void**)&m_pME);
1546 wxASSERT(SUCCEEDED(hr));
1547 pGB->Release();
1548 }
1549
1550 ~wxAMPlayTimer()
1551 {
1552 SAFE_RELEASE(m_pME);
1553 }
1554
1555 void Notify()
1556 {
1557 LONG evCode;
1558 LONG_PTR evParam1,
1559 evParam2;
1560
1561 //
1562 // DirectShow keeps a list of queued events, and we need
1563 // to go through them one by one, stopping at (Hopefully only one)
1564 // EC_COMPLETE message
1565 //
1566 while( m_pME->GetEvent(&evCode, &evParam1, &evParam2, 0) == 0 )
1567 {
1568 // Cleanup memory that GetEvent allocated
1569 HRESULT hr = m_pME->FreeEventParams(evCode,
1570 evParam1, evParam2);
1571 if(hr != 0)
1572 {
1573 //Even though this makes a messagebox this
1574 //is windows where we can do gui stuff in seperate
1575 //threads :)
1576 wxFAIL_MSG(m_pBE->GetErrorString(hr));
1577 }
1578 // If this is the end of the clip, notify handler
1579 else if(1 == evCode) //EC_COMPLETE
1580 {
1581 if ( m_pBE->SendStopEvent() )
1582 {
1583 Stop();
1584
1585 m_pBE->QueueFinishEvent();
1586 }
1587 }
1588 }
1589 }
1590
1591 protected:
1592 wxAMMediaBackend* m_pBE; //Backend pointer
1593 IMediaEvent* m_pME; //To determine when to send stop event
1594 };
1595 */
1596
1597 //---------------------------------------------------------------------------
1598 // wxAMMediaBackend Constructor
1599 //---------------------------------------------------------------------------
1600 wxAMMediaBackend::wxAMMediaBackend()
1601 :m_pAX(NULL),
1602 m_pAM(NULL),
1603 m_pMP(NULL),
1604 m_pTimer(NULL)
1605 {
1606 }
1607
1608 //---------------------------------------------------------------------------
1609 // wxAMMediaBackend Destructor
1610 //---------------------------------------------------------------------------
1611 wxAMMediaBackend::~wxAMMediaBackend()
1612 {
1613 Clear(); //Free memory from Load()
1614
1615 if(m_pAX)
1616 {
1617 {
1618 wxLogNull noLog;
1619 m_pAX->DissociateHandle();
1620 }
1621 delete m_pAX;
1622 m_pAM->Release();
1623
1624 if(m_pMP)
1625 m_pMP->Release();
1626 }
1627 }
1628
1629 //---------------------------------------------------------------------------
1630 // wxAMMediaBackend::Clear
1631 //
1632 // Free up interfaces and memory allocated by LoadXXX
1633 //---------------------------------------------------------------------------
1634 void wxAMMediaBackend::Clear()
1635 {
1636 if(m_pTimer)
1637 {
1638 delete m_pTimer;
1639 m_pTimer = NULL;
1640 }
1641 }
1642
1643 //---------------------------------------------------------------------------
1644 // wxAMMediaBackend::CreateControl
1645 //---------------------------------------------------------------------------
1646 bool wxAMMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent,
1647 wxWindowID id,
1648 const wxPoint& pos,
1649 const wxSize& size,
1650 long style,
1651 const wxValidator& validator,
1652 const wxString& name)
1653 {
1654 // First get the AMGetErrorText procedure in debug
1655 // mode for more meaningful messages
1656 #ifdef __WXDEBUG__
1657 if ( m_dllQuartz.Load(_T("quartz.dll"), wxDL_VERBATIM) )
1658 {
1659 m_lpAMGetErrorText = (LPAMGETERRORTEXT)
1660 m_dllQuartz.GetSymbolAorW(wxT("AMGetErrorText"));
1661 }
1662 #endif // __WXDEBUG__
1663
1664 // Now determine which (if any) media player interface is
1665 // available - IMediaPlayer or IActiveMovie
1666 if( ::CoCreateInstance(CLSID_MediaPlayer, NULL,
1667 CLSCTX_INPROC_SERVER,
1668 IID_IMediaPlayer, (void**)&m_pMP) != 0 )
1669 {
1670 if( ::CoCreateInstance(CLSID_ActiveMovie, NULL,
1671 CLSCTX_INPROC_SERVER,
1672 IID_IActiveMovie, (void**)&m_pAM) != 0 )
1673 return false;
1674 m_pAM->QueryInterface(IID_IMediaPlayer, (void**)&m_pMP);
1675 }
1676 else
1677 {
1678 m_pMP->QueryInterface(IID_IActiveMovie, (void**)&m_pAM);
1679 }
1680 //
1681 // Create window
1682 // By default wxWindow(s) is created with a border -
1683 // so we need to get rid of those
1684 //
1685 // Since we don't have a child window like most other
1686 // backends, we don't need wxCLIP_CHILDREN
1687 //
1688 if ( !ctrl->wxControl::Create(parent, id, pos, size,
1689 (style & ~wxBORDER_MASK) | wxBORDER_NONE,
1690 validator, name) )
1691 return false;
1692
1693 //
1694 // Now create the ActiveX container along with the media player
1695 // interface and query them
1696 //
1697 m_ctrl = wxStaticCast(ctrl, wxMediaCtrl);
1698 m_pAX = new wxActiveXContainer(ctrl,
1699 m_pMP ? IID_IMediaPlayer : IID_IActiveMovie,
1700 m_pAM);
1701
1702
1703 //
1704 // Here we set up wx-specific stuff for the default
1705 // settings wxMediaCtrl says it will stay to
1706 //
1707 if(m_pMP)
1708 {
1709 m_pMP->put_DisplaySize(mpFitToSize);
1710 // TODO: Unsure what actual effect this has
1711 m_pMP->put_WindowlessVideo(VARIANT_TRUE);
1712 }
1713 else
1714 m_pAM->put_MovieWindowSize(amvDoubleOriginalSize);
1715
1716 //by default true
1717 m_pAM->put_AutoStart(VARIANT_FALSE);
1718 //by default enabled
1719 wxAMMediaBackend::ShowPlayerControls(wxMEDIACTRLPLAYERCONTROLS_NONE);
1720 //by default with AM only 0.5
1721 wxAMMediaBackend::SetVolume(1.0);
1722
1723 // don't erase the background of our control window so that resizing is a
1724 // bit smoother
1725 m_ctrl->SetBackgroundStyle(wxBG_STYLE_CUSTOM);
1726
1727 // success
1728 return true;
1729 }
1730
1731 //---------------------------------------------------------------------------
1732 // wxAMMediaBackend::Load (file version)
1733 //---------------------------------------------------------------------------
1734 bool wxAMMediaBackend::Load(const wxString& fileName)
1735 {
1736 return DoLoad(fileName);
1737 }
1738
1739 //---------------------------------------------------------------------------
1740 // wxAMMediaBackend::Load (URL Version)
1741 //---------------------------------------------------------------------------
1742 bool wxAMMediaBackend::Load(const wxURI& location)
1743 {
1744 // Turn off loading from a proxy as user
1745 // may have set it previously
1746 INSPlay* pPlay = NULL;
1747 m_pAM->QueryInterface(IID_INSPlay, (void**) &pPlay);
1748 if(pPlay)
1749 {
1750 pPlay->put_UseHTTPProxy(VARIANT_FALSE);
1751 pPlay->Release();
1752 }
1753
1754 return DoLoad(location.BuildURI());
1755 }
1756
1757 //---------------------------------------------------------------------------
1758 // wxAMMediaBackend::Load (URL Version with Proxy)
1759 //---------------------------------------------------------------------------
1760 bool wxAMMediaBackend::Load(const wxURI& location, const wxURI& proxy)
1761 {
1762 // Set the proxy of the NETSHOW interface
1763 INSPlay* pPlay = NULL;
1764 m_pAM->QueryInterface(IID_INSPlay, (void**) &pPlay);
1765
1766 if(pPlay)
1767 {
1768 pPlay->put_UseHTTPProxy(VARIANT_TRUE);
1769 pPlay->put_HTTPProxyHost(wxBasicString(proxy.GetServer()).Get());
1770 pPlay->put_HTTPProxyPort(wxAtoi(proxy.GetPort()));
1771 pPlay->Release();
1772 }
1773
1774 return DoLoad(location.BuildURI());
1775 }
1776
1777 //---------------------------------------------------------------------------
1778 // wxAMMediaBackend::DoLoad
1779 //
1780 // Called by all functions - this actually renders
1781 // the file and sets up the filter graph
1782 //---------------------------------------------------------------------------
1783 bool wxAMMediaBackend::DoLoad(const wxString& location)
1784 {
1785 Clear(); //Clear up previously allocated memory
1786
1787 HRESULT hr;
1788
1789 // Play the movie the normal way through the embedded
1790 // WMP. Supposively Open is better in theory because
1791 // the docs say its async and put_FileName is not -
1792 // but in practice they both seem to be async anyway
1793 if(m_pMP)
1794 hr = m_pMP->Open( wxBasicString(location).Get() );
1795 else
1796 hr = m_pAM->put_FileName( wxBasicString(location).Get() );
1797
1798 if(FAILED(hr))
1799 {
1800 wxAMLOG(hr);
1801 return false;
1802 }
1803
1804 // In AM playing will FAIL if
1805 // the user plays before the media is loaded
1806 m_pTimer = new wxAMLoadTimer(this);
1807 m_pTimer->Start(20);
1808 return true;
1809 }
1810
1811 //---------------------------------------------------------------------------
1812 // wxAMMediaBackend::FinishLoad
1813 //
1814 // Called by our wxAMLoadTimer when the
1815 // embedded WMP tells its the media is ready to play.
1816 //
1817 // Here we get the original size of the video and
1818 // send the loaded event to our watcher :).
1819 //---------------------------------------------------------------------------
1820 void wxAMMediaBackend::FinishLoad()
1821 {
1822 //Get the original video size
1823 m_pAM->get_ImageSourceWidth((long*)&m_bestSize.x);
1824 m_pAM->get_ImageSourceHeight((long*)&m_bestSize.y);
1825
1826 //
1827 //Start the play timer to catch stop events
1828 //Previous load timer cleans up itself
1829 //
1830 m_pTimer = new wxAMPlayTimer(this);
1831
1832 NotifyMovieLoaded();
1833 }
1834
1835 //---------------------------------------------------------------------------
1836 // wxAMMediaBackend::ShowPlayerControls
1837 //---------------------------------------------------------------------------
1838 bool wxAMMediaBackend::ShowPlayerControls(wxMediaCtrlPlayerControls flags)
1839 {
1840 // Note that IMediaPlayer doesn't have a statusbar by
1841 // default but IActiveMovie does - so lets try to keep
1842 // the interface consistant
1843 if(!flags)
1844 {
1845 m_pAM->put_Enabled(VARIANT_FALSE);
1846 m_pAM->put_ShowControls(VARIANT_FALSE);
1847 if(m_pMP)
1848 m_pMP->put_ShowStatusBar(VARIANT_FALSE);
1849 }
1850 else
1851 {
1852 m_pAM->put_Enabled(VARIANT_TRUE);
1853 m_pAM->put_ShowControls(VARIANT_TRUE);
1854
1855 m_pAM->put_ShowPositionControls(
1856 (flags & wxMEDIACTRLPLAYERCONTROLS_STEP) ?
1857 VARIANT_TRUE : VARIANT_FALSE);
1858
1859 if(m_pMP)
1860 {
1861 m_pMP->put_ShowStatusBar(VARIANT_TRUE);
1862 m_pMP->put_ShowAudioControls(
1863 (flags & wxMEDIACTRLPLAYERCONTROLS_VOLUME) ?
1864 VARIANT_TRUE : VARIANT_FALSE);
1865 }
1866 }
1867
1868 return true;
1869 }
1870
1871 //---------------------------------------------------------------------------
1872 // wxAMMediaBackend::Play
1873 //
1874 // Plays the stream. If it is non-seekable, it will restart it (implicit).
1875 //
1876 // Note that we use SUCCEEDED here because run/pause/stop tend to be overly
1877 // picky and return warnings on pretty much every call
1878 //---------------------------------------------------------------------------
1879 bool wxAMMediaBackend::Play()
1880 {
1881 // Actually try to play the movie, even though it may not be loaded yet.
1882 HRESULT hr = m_pAM->Run();
1883 if(SUCCEEDED(hr))
1884 {
1885 m_pTimer->Start(20);
1886 return true;
1887 }
1888 wxAMLOG(hr);
1889 return false;
1890 }
1891
1892 //---------------------------------------------------------------------------
1893 // wxAMMediaBackend::Pause
1894 //
1895 // Pauses the stream.
1896 //---------------------------------------------------------------------------
1897 bool wxAMMediaBackend::Pause()
1898 {
1899 HRESULT hr = m_pAM->Pause();
1900 if(SUCCEEDED(hr))
1901 return true;
1902 wxAMLOG(hr);
1903 return false;
1904 }
1905
1906 //---------------------------------------------------------------------------
1907 // wxAMMediaBackend::Stop
1908 //
1909 // Stops the stream.
1910 //---------------------------------------------------------------------------
1911 bool wxAMMediaBackend::Stop()
1912 {
1913 HRESULT hr = m_pAM->Stop();
1914 if(SUCCEEDED(hr))
1915 {
1916 //Seek to beginning
1917 wxAMMediaBackend::SetPosition(0);
1918 //Stop stop event timer
1919 m_pTimer->Stop();
1920 return true;
1921 }
1922 wxAMLOG(hr);
1923 return false;
1924 }
1925
1926 //---------------------------------------------------------------------------
1927 // wxAMMediaBackend::SetPosition
1928 //
1929 // 1) Translates the current position's time to directshow time,
1930 // which is in a scale of 1 second (in a double)
1931 // 2) Sets the play position of the IMediaSeeking interface -
1932 // passing NULL as the stop position means to keep the old
1933 // stop position
1934 //---------------------------------------------------------------------------
1935 bool wxAMMediaBackend::SetPosition(wxLongLong where)
1936 {
1937 HRESULT hr = m_pAM->put_CurrentPosition(
1938 ((LONGLONG)where.GetValue()) / 1000.0
1939 );
1940 if(FAILED(hr))
1941 {
1942 wxAMLOG(hr);
1943 return false;
1944 }
1945
1946 return true;
1947 }
1948
1949 //---------------------------------------------------------------------------
1950 // wxAMMediaBackend::GetPosition
1951 //
1952 // 1) Obtains the current play and stop positions from IMediaSeeking
1953 // 2) Returns the play position translated to our time base
1954 //---------------------------------------------------------------------------
1955 wxLongLong wxAMMediaBackend::GetPosition()
1956 {
1957 double outCur;
1958 HRESULT hr = m_pAM->get_CurrentPosition(&outCur);
1959 if(FAILED(hr))
1960 {
1961 wxAMLOG(hr);
1962 return 0;
1963 }
1964
1965 //h,m,s,milli - outdur is in 1 second (double)
1966 outCur *= 1000;
1967 wxLongLong ll;
1968 ll.Assign(outCur);
1969
1970 return ll;
1971 }
1972
1973 //---------------------------------------------------------------------------
1974 // wxAMMediaBackend::GetVolume
1975 //
1976 // Gets the volume through the IBasicAudio interface -
1977 // value ranges from 0 (MAX volume) to -10000 (minimum volume).
1978 // -100 per decibel.
1979 //---------------------------------------------------------------------------
1980 double wxAMMediaBackend::GetVolume()
1981 {
1982 long lVolume;
1983 HRESULT hr = m_pAM->get_Volume(&lVolume);
1984 if(FAILED(hr))
1985 {
1986 wxAMLOG(hr);
1987 return 0.0;
1988 }
1989 return pow(10.0, lVolume/2000.0);
1990 }
1991
1992 //---------------------------------------------------------------------------
1993 // wxAMMediaBackend::SetVolume
1994 //
1995 // Sets the volume through the IBasicAudio interface -
1996 // value ranges from 0 (MAX volume) to -10000 (minimum volume).
1997 // -100 per decibel.
1998 //---------------------------------------------------------------------------
1999 bool wxAMMediaBackend::SetVolume(double dVolume)
2000 {
2001 //pow(10.0, -80.0) to correct 0 == -INF
2002 long lVolume = (long)(2000.0 * log10(pow(10.0, -80.0)+dVolume));
2003 HRESULT hr = m_pAM->put_Volume( lVolume );
2004 if(FAILED(hr))
2005 {
2006 wxAMLOG(hr);
2007 return false;
2008 }
2009 return true;
2010 }
2011
2012 //---------------------------------------------------------------------------
2013 // wxAMMediaBackend::GetDuration
2014 //
2015 // 1) Obtains the duration of the media from IAMMultiMediaStream
2016 // 2) Converts that value to our time base, and returns it
2017 //
2018 // NB: With VBR MP3 files the default DirectShow MP3 render does not
2019 // read the Xing header correctly, resulting in skewed values for duration
2020 // and seeking
2021 //---------------------------------------------------------------------------
2022 wxLongLong wxAMMediaBackend::GetDuration()
2023 {
2024 double outDuration;
2025 HRESULT hr = m_pAM->get_Duration(&outDuration);
2026 if(FAILED(hr))
2027 {
2028 wxAMLOG(hr);
2029 return 0;
2030 }
2031
2032 //h,m,s,milli - outdur is in 1 second (double)
2033 outDuration *= 1000;
2034 wxLongLong ll;
2035 ll.Assign(outDuration);
2036
2037 return ll;
2038 }
2039
2040 //---------------------------------------------------------------------------
2041 // wxAMMediaBackend::GetState
2042 //
2043 // Returns the cached state
2044 //---------------------------------------------------------------------------
2045 wxMediaState wxAMMediaBackend::GetState()
2046 {
2047 StateConstants nState;
2048 HRESULT hr = m_pAM->get_CurrentState(&nState);
2049 if(FAILED(hr))
2050 {
2051 wxAMLOG(hr);
2052 return wxMEDIASTATE_STOPPED;
2053 }
2054
2055 return (wxMediaState)nState;
2056 }
2057
2058 //---------------------------------------------------------------------------
2059 // wxAMMediaBackend::GetPlaybackRate
2060 //
2061 // Pretty simple way of obtaining the playback rate from
2062 // the IMediaSeeking interface
2063 //---------------------------------------------------------------------------
2064 double wxAMMediaBackend::GetPlaybackRate()
2065 {
2066 double dRate;
2067 HRESULT hr = m_pAM->get_Rate(&dRate);
2068 if(FAILED(hr))
2069 {
2070 wxAMLOG(hr);
2071 return 0.0;
2072 }
2073 return dRate;
2074 }
2075
2076 //---------------------------------------------------------------------------
2077 // wxAMMediaBackend::SetPlaybackRate
2078 //
2079 // Sets the playback rate of the media - DirectShow is pretty good
2080 // about this, actually
2081 //---------------------------------------------------------------------------
2082 bool wxAMMediaBackend::SetPlaybackRate(double dRate)
2083 {
2084 HRESULT hr = m_pAM->put_Rate(dRate);
2085 if(FAILED(hr))
2086 {
2087 wxAMLOG(hr);
2088 return false;
2089 }
2090
2091 return true;
2092 }
2093
2094 //---------------------------------------------------------------------------
2095 // wxAMMediaBackend::GetDownloadXXX
2096 //
2097 // Queries for and gets the total size of the file and the current
2098 // progress in downloading that file from the IAMOpenProgress
2099 // interface from the media player interface's filter graph
2100 //---------------------------------------------------------------------------
2101 void wxAMMediaBackend::DoGetDownloadProgress(wxLongLong* pLoadProgress,
2102 wxLongLong* pLoadTotal)
2103 {
2104 LONGLONG loadTotal = 0, loadProgress = 0;
2105 IUnknown* pFG;
2106 IAMOpenProgress* pOP;
2107 HRESULT hr;
2108 hr = m_pAM->get_FilterGraph(&pFG);
2109 if(SUCCEEDED(hr))
2110 {
2111 hr = pFG->QueryInterface(IID_IAMOpenProgress, (void**)&pOP);
2112 if(SUCCEEDED(hr))
2113 {
2114 hr = pOP->QueryProgress(&loadTotal, &loadProgress);
2115 pOP->Release();
2116 }
2117 pFG->Release();
2118 }
2119
2120 if(SUCCEEDED(hr))
2121 {
2122 *pLoadProgress = loadProgress;
2123 *pLoadTotal = loadTotal;
2124 }
2125 else
2126 {
2127 //When not loading from a URL QueryProgress will return
2128 //E_NOINTERFACE or whatever
2129 //wxAMFAIL(hr);
2130 *pLoadProgress = 0;
2131 *pLoadTotal = 0;
2132 }
2133 }
2134
2135 //---------------------------------------------------------------------------
2136 // wxAMMediaBackend::GetVideoSize
2137 //
2138 // Obtains the cached original video size
2139 //---------------------------------------------------------------------------
2140 wxSize wxAMMediaBackend::GetVideoSize() const
2141 {
2142 return m_bestSize;
2143 }
2144
2145 //---------------------------------------------------------------------------
2146 // wxAMMediaBackend::Move
2147 //
2148 // We take care of this in our redrawing
2149 //---------------------------------------------------------------------------
2150 void wxAMMediaBackend::Move(int WXUNUSED(x), int WXUNUSED(y),
2151 int WXUNUSED(w), int WXUNUSED(h))
2152 {
2153 }
2154
2155 //---------------------------------------------------------------------------
2156 // End of wxAMMediaBackend
2157 //---------------------------------------------------------------------------
2158
2159 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2160 //
2161 // wxMCIMediaBackend
2162 //
2163 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2164
2165 #ifndef __WXWINCE__
2166 IMPLEMENT_DYNAMIC_CLASS(wxMCIMediaBackend, wxMediaBackend)
2167
2168 //---------------------------------------------------------------------------
2169 // Usual debugging macros for MCI returns
2170 //---------------------------------------------------------------------------
2171
2172 #ifdef __WXDEBUG__
2173 #define wxMCIVERIFY(arg) \
2174 { \
2175 DWORD nRet; \
2176 if ( (nRet = (arg)) != 0) \
2177 { \
2178 TCHAR sz[5000]; \
2179 mciGetErrorString(nRet, sz, 5000); \
2180 wxFAIL_MSG(wxString::Format(_T("MCI Error:%s"), sz)); \
2181 } \
2182 }
2183 #else
2184 #define wxMCIVERIFY(arg) (arg);
2185 #endif
2186
2187 //---------------------------------------------------------------------------
2188 // Simulation for <digitalv.h>
2189 //
2190 // Mingw and possibly other compilers don't have the digitalv.h header
2191 // that is needed to have some essential features of mci work with
2192 // windows - so we provide the declarations for the types we use here
2193 //---------------------------------------------------------------------------
2194
2195 typedef struct {
2196 DWORD_PTR dwCallback;
2197 #ifdef MCI_USE_OFFEXT
2198 POINT ptOffset;
2199 POINT ptExtent;
2200 #else
2201 RECT rc;
2202 #endif
2203 } MCI_DGV_RECT_PARMS;
2204
2205 typedef struct {
2206 DWORD_PTR dwCallback;
2207 HWND hWnd;
2208 #ifndef _WIN32
2209 WORD wReserved1;
2210 #endif
2211 UINT nCmdShow;
2212 #ifndef _WIN32
2213 WORD wReserved2;
2214 #endif
2215 wxChar* lpstrText;
2216 } MCI_DGV_WINDOW_PARMS;
2217
2218 typedef struct {
2219 DWORD_PTR dwCallback;
2220 DWORD dwTimeFormat;
2221 DWORD dwAudio;
2222 DWORD dwFileFormat;
2223 DWORD dwSpeed;
2224 } MCI_DGV_SET_PARMS;
2225
2226 typedef struct {
2227 DWORD_PTR dwCallback;
2228 DWORD dwItem;
2229 DWORD dwValue;
2230 DWORD dwOver;
2231 wxChar* lpstrAlgorithm;
2232 wxChar* lpstrQuality;
2233 } MCI_DGV_SETAUDIO_PARMS;
2234
2235 //---------------------------------------------------------------------------
2236 // wxMCIMediaBackend Constructor
2237 //
2238 // Here we don't need to do much except say we don't have any video :)
2239 //---------------------------------------------------------------------------
2240 wxMCIMediaBackend::wxMCIMediaBackend() : m_hNotifyWnd(NULL), m_bVideo(false)
2241 {
2242 }
2243
2244 //---------------------------------------------------------------------------
2245 // wxMCIMediaBackend Destructor
2246 //
2247 // We close the mci device - note that there may not be an mci device here,
2248 // or it may fail - but we don't really care, since we're destructing
2249 //---------------------------------------------------------------------------
2250 wxMCIMediaBackend::~wxMCIMediaBackend()
2251 {
2252 if(m_hNotifyWnd)
2253 {
2254 mciSendCommand(m_hDev, MCI_CLOSE, 0, 0);
2255 DestroyWindow(m_hNotifyWnd);
2256 m_hNotifyWnd = NULL;
2257 }
2258 }
2259
2260 //---------------------------------------------------------------------------
2261 // wxMCIMediaBackend::Create
2262 //
2263 // Here we just tell wxMediaCtrl that mci does exist (which it does, on all
2264 // msw systems, at least in some form dating back to win16 days)
2265 //---------------------------------------------------------------------------
2266 bool wxMCIMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent,
2267 wxWindowID id,
2268 const wxPoint& pos,
2269 const wxSize& size,
2270 long style,
2271 const wxValidator& validator,
2272 const wxString& name)
2273 {
2274 //
2275 // Create window
2276 // By default wxWindow(s) is created with a border -
2277 // so we need to get rid of those, and create with
2278 // wxCLIP_CHILDREN, so that if the driver/backend
2279 // is a child window, it refereshes properly
2280 //
2281 if ( !ctrl->wxControl::Create(parent, id, pos, size,
2282 (style & ~wxBORDER_MASK) | wxBORDER_NONE | wxCLIP_CHILDREN,
2283 validator, name) )
2284 return false;
2285
2286 m_ctrl = wxStaticCast(ctrl, wxMediaCtrl);
2287 return true;
2288 }
2289
2290 //---------------------------------------------------------------------------
2291 // wxMCIMediaBackend::Load (file version)
2292 //
2293 // Here we have MCI load a file and device, set the time format to our
2294 // default (milliseconds), and set the video (if any) to play in the control
2295 //---------------------------------------------------------------------------
2296 bool wxMCIMediaBackend::Load(const wxString& fileName)
2297 {
2298 //
2299 //if the user already called load close the previous MCI device
2300 //
2301 if(m_hNotifyWnd)
2302 {
2303 mciSendCommand(m_hDev, MCI_CLOSE, 0, 0);
2304 DestroyWindow(m_hNotifyWnd);
2305 m_hNotifyWnd = NULL;
2306 }
2307
2308 //
2309 //Opens a file and has MCI select a device. Normally you'd put
2310 //MCI_OPEN_TYPE in addition to MCI_OPEN_ELEMENT - however if you
2311 //omit this it tells MCI to select the device instead. This is
2312 //good because we have no reliable way of "enumerating" the devices
2313 //in MCI
2314 //
2315 MCI_OPEN_PARMS openParms;
2316 openParms.lpstrElementName = (wxChar*) fileName.c_str();
2317
2318 if ( mciSendCommand(0, MCI_OPEN, MCI_OPEN_ELEMENT,
2319 (DWORD)(LPVOID)&openParms) != 0)
2320 return false;
2321
2322 m_hDev = openParms.wDeviceID;
2323
2324 //
2325 //Now set the time format for the device to milliseconds
2326 //
2327 MCI_SET_PARMS setParms;
2328 setParms.dwCallback = 0;
2329 setParms.dwTimeFormat = MCI_FORMAT_MILLISECONDS;
2330
2331 if (mciSendCommand(m_hDev, MCI_SET, MCI_SET_TIME_FORMAT,
2332 (DWORD)(LPVOID)&setParms) != 0)
2333 return false;
2334
2335 //
2336 //Now tell the MCI device to display the video in our wxMediaCtrl
2337 //
2338 MCI_DGV_WINDOW_PARMS windowParms;
2339 windowParms.hWnd = (HWND)m_ctrl->GetHandle();
2340
2341 m_bVideo = (mciSendCommand(m_hDev, MCI_WINDOW,
2342 0x00010000L, //MCI_DGV_WINDOW_HWND
2343 (DWORD)(LPVOID)&windowParms) == 0);
2344
2345 //
2346 // Create a hidden window and register to handle
2347 // MCI events
2348 // Note that wxCanvasClassName is already registered
2349 // and used by all wxWindows and normal wxControls
2350 //
2351 m_hNotifyWnd = ::CreateWindow
2352 (
2353 wxCanvasClassName,
2354 NULL,
2355 0, 0, 0, 0,
2356 0,
2357 (HWND) NULL,
2358 (HMENU)NULL,
2359 wxGetInstance(),
2360 (LPVOID) NULL
2361 );
2362
2363 if(!m_hNotifyWnd)
2364 {
2365 wxLogSysError( wxT("Could not create hidden needed for ")
2366 wxT("registering for MCI events!") );
2367
2368 return false;
2369 }
2370
2371 wxSetWindowProc(m_hNotifyWnd, wxMCIMediaBackend::NotifyWndProc);
2372 wxSetWindowUserData(m_hNotifyWnd, this);
2373
2374 NotifyMovieLoaded();
2375
2376 return true;
2377 }
2378
2379 //---------------------------------------------------------------------------
2380 // wxMCIMediaBackend::Load (URL version)
2381 //
2382 // MCI doesn't support URLs directly (?)
2383 //
2384 // TODO: Use wxURL/wxFileSystem and mmioInstallProc
2385 //---------------------------------------------------------------------------
2386 bool wxMCIMediaBackend::Load(const wxURI& WXUNUSED(location))
2387 {
2388 return false;
2389 }
2390
2391 //---------------------------------------------------------------------------
2392 // wxMCIMediaBackend::Play
2393 //
2394 // Plays/Resumes the MCI device... a couple notes:
2395 // 1) Certain drivers will crash and burn if we don't pass them an
2396 // MCI_PLAY_PARMS, despite the documentation that says otherwise...
2397 // 2) There is a MCI_RESUME command, but MCI_PLAY does the same thing
2398 // and will resume from a stopped state also, so there's no need to
2399 // call both, for example
2400 //---------------------------------------------------------------------------
2401 bool wxMCIMediaBackend::Play()
2402 {
2403 MCI_PLAY_PARMS playParms;
2404 playParms.dwCallback = (DWORD)m_hNotifyWnd;
2405
2406 bool bOK = ( mciSendCommand(m_hDev, MCI_PLAY, MCI_NOTIFY,
2407 (DWORD)(LPVOID)&playParms) == 0 );
2408
2409 if(bOK)
2410 m_ctrl->Show(m_bVideo);
2411
2412 return bOK;
2413 }
2414
2415 //---------------------------------------------------------------------------
2416 // wxMCIMediaBackend::Pause
2417 //
2418 // Pauses the MCI device - nothing special
2419 //---------------------------------------------------------------------------
2420 bool wxMCIMediaBackend::Pause()
2421 {
2422 return (mciSendCommand(m_hDev, MCI_PAUSE, MCI_WAIT, 0) == 0);
2423 }
2424
2425 //---------------------------------------------------------------------------
2426 // wxMCIMediaBackend::Stop
2427 //
2428 // Stops the MCI device & seeks to the beginning as wxMediaCtrl docs outline
2429 //---------------------------------------------------------------------------
2430 bool wxMCIMediaBackend::Stop()
2431 {
2432 return (mciSendCommand(m_hDev, MCI_STOP, MCI_WAIT, 0) == 0) &&
2433 (mciSendCommand(m_hDev, MCI_SEEK, MCI_SEEK_TO_START, 0) == 0);
2434 }
2435
2436 //---------------------------------------------------------------------------
2437 // wxMCIMediaBackend::GetState
2438 //
2439 // Here we get the state and convert it to a wxMediaState -
2440 // since we use direct comparisons with MCI_MODE_PLAY and
2441 // MCI_MODE_PAUSE, we don't care if the MCI_STATUS call
2442 // fails or not
2443 //---------------------------------------------------------------------------
2444 wxMediaState wxMCIMediaBackend::GetState()
2445 {
2446 MCI_STATUS_PARMS statusParms;
2447 statusParms.dwItem = MCI_STATUS_MODE;
2448
2449 mciSendCommand(m_hDev, MCI_STATUS, MCI_STATUS_ITEM,
2450 (DWORD)(LPVOID)&statusParms);
2451
2452 if(statusParms.dwReturn == MCI_MODE_PAUSE)
2453 return wxMEDIASTATE_PAUSED;
2454 else if(statusParms.dwReturn == MCI_MODE_PLAY)
2455 return wxMEDIASTATE_PLAYING;
2456 else
2457 return wxMEDIASTATE_STOPPED;
2458 }
2459
2460 //---------------------------------------------------------------------------
2461 // wxMCIMediaBackend::SetPosition
2462 //
2463 // Here we set the position of the device in the stream.
2464 // Note that MCI actually stops the device after you seek it if the
2465 // device is playing/paused, so we need to play the file after
2466 // MCI seeks like normal APIs would
2467 //---------------------------------------------------------------------------
2468 bool wxMCIMediaBackend::SetPosition(wxLongLong where)
2469 {
2470 MCI_SEEK_PARMS seekParms;
2471 seekParms.dwCallback = 0;
2472 #if wxUSE_LONGLONG_NATIVE && !wxUSE_LONGLONG_WX
2473 seekParms.dwTo = (DWORD)where.GetValue();
2474 #else /* wxUSE_LONGLONG_WX */
2475 /* no way to return it in one piece */
2476 wxASSERT( where.GetHi()==0 );
2477 seekParms.dwTo = (DWORD)where.GetLo();
2478 #endif /* wxUSE_LONGLONG_* */
2479
2480 //device was playing?
2481 bool bReplay = GetState() == wxMEDIASTATE_PLAYING;
2482
2483 if( mciSendCommand(m_hDev, MCI_SEEK, MCI_TO,
2484 (DWORD)(LPVOID)&seekParms) != 0)
2485 return false;
2486
2487 //If the device was playing, resume it
2488 if (bReplay)
2489 return Play();
2490 else
2491 return true;
2492 }
2493
2494 //---------------------------------------------------------------------------
2495 // wxMCIMediaBackend::GetPosition
2496 //
2497 // Gets the position of the device in the stream using the current
2498 // time format... nothing special here...
2499 //---------------------------------------------------------------------------
2500 wxLongLong wxMCIMediaBackend::GetPosition()
2501 {
2502 MCI_STATUS_PARMS statusParms;
2503 statusParms.dwItem = MCI_STATUS_POSITION;
2504
2505 if (mciSendCommand(m_hDev, MCI_STATUS, MCI_STATUS_ITEM,
2506 (DWORD)(LPSTR)&statusParms) != 0)
2507 return 0;
2508
2509 return statusParms.dwReturn;
2510 }
2511
2512 //---------------------------------------------------------------------------
2513 // wxMCIMediaBackend::GetVolume
2514 //
2515 // Gets the volume of the current media via the MCI_DGV_STATUS_VOLUME
2516 // message. Value ranges from 0 (minimum) to 1000 (maximum volume).
2517 //---------------------------------------------------------------------------
2518 double wxMCIMediaBackend::GetVolume()
2519 {
2520 MCI_STATUS_PARMS statusParms;
2521 statusParms.dwCallback = 0;
2522 statusParms.dwItem = 0x4019; //MCI_DGV_STATUS_VOLUME
2523
2524 if (mciSendCommand(m_hDev, MCI_STATUS, MCI_STATUS_ITEM,
2525 (DWORD)(LPSTR)&statusParms) != 0)
2526 return 0;
2527
2528 return ((double)statusParms.dwReturn) / 1000.0;
2529 }
2530
2531 //---------------------------------------------------------------------------
2532 // wxMCIMediaBackend::SetVolume
2533 //
2534 // Sets the volume of the current media via the MCI_DGV_SETAUDIO_VOLUME
2535 // message. Value ranges from 0 (minimum) to 1000 (maximum volume).
2536 //---------------------------------------------------------------------------
2537 bool wxMCIMediaBackend::SetVolume(double dVolume)
2538 {
2539 MCI_DGV_SETAUDIO_PARMS audioParms;
2540 audioParms.dwCallback = 0;
2541 audioParms.dwItem = 0x4002; //MCI_DGV_SETAUDIO_VOLUME
2542 audioParms.dwValue = (DWORD) (dVolume * 1000.0);
2543 audioParms.dwOver = 0;
2544 audioParms.lpstrAlgorithm = NULL;
2545 audioParms.lpstrQuality = NULL;
2546
2547 if (mciSendCommand(m_hDev, 0x0873, //MCI_SETAUDIO
2548 //MCI_DGV_SETAUDIO+(_ITEM | _VALUE)
2549 0x00800000L | 0x01000000L,
2550 (DWORD)(LPSTR)&audioParms) != 0)
2551 return false;
2552 return true;
2553 }
2554
2555 //---------------------------------------------------------------------------
2556 // wxMCIMediaBackend::GetDuration
2557 //
2558 // Gets the duration of the stream... nothing special
2559 //---------------------------------------------------------------------------
2560 wxLongLong wxMCIMediaBackend::GetDuration()
2561 {
2562 MCI_STATUS_PARMS statusParms;
2563 statusParms.dwItem = MCI_STATUS_LENGTH;
2564
2565 if (mciSendCommand(m_hDev, MCI_STATUS, MCI_STATUS_ITEM,
2566 (DWORD)(LPSTR)&statusParms) != 0)
2567 return 0;
2568
2569 return statusParms.dwReturn;
2570 }
2571
2572 //---------------------------------------------------------------------------
2573 // wxMCIMediaBackend::Move
2574 //
2575 // Moves the window to a location
2576 //---------------------------------------------------------------------------
2577 void wxMCIMediaBackend::Move(int WXUNUSED(x), int WXUNUSED(y),
2578 int w, int h)
2579 {
2580 if (m_hNotifyWnd && m_bVideo)
2581 {
2582 MCI_DGV_RECT_PARMS putParms; //ifdefed MCI_DGV_PUT_PARMS
2583 memset(&putParms, 0, sizeof(MCI_DGV_RECT_PARMS));
2584 putParms.rc.bottom = h;
2585 putParms.rc.right = w;
2586
2587 //wxStackWalker will crash and burn here on assert
2588 //and mci doesn't like 0 and 0 for some reason (out of range )
2589 //so just don't it in that case
2590 if(w || h)
2591 {
2592 wxMCIVERIFY( mciSendCommand(m_hDev, MCI_PUT,
2593 0x00040000L, //MCI_DGV_PUT_DESTINATION
2594 (DWORD)(LPSTR)&putParms) );
2595 }
2596 }
2597 }
2598
2599 //---------------------------------------------------------------------------
2600 // wxMCIMediaBackend::GetVideoSize
2601 //
2602 // Gets the original size of the movie for sizers
2603 //---------------------------------------------------------------------------
2604 wxSize wxMCIMediaBackend::GetVideoSize() const
2605 {
2606 if(m_bVideo)
2607 {
2608 MCI_DGV_RECT_PARMS whereParms; //ifdefed MCI_DGV_WHERE_PARMS
2609
2610 wxMCIVERIFY( mciSendCommand(m_hDev, MCI_WHERE,
2611 0x00020000L, //MCI_DGV_WHERE_SOURCE
2612 (DWORD)(LPSTR)&whereParms) );
2613
2614 return wxSize(whereParms.rc.right, whereParms.rc.bottom);
2615 }
2616 return wxSize(0,0);
2617 }
2618
2619 //---------------------------------------------------------------------------
2620 // wxMCIMediaBackend::GetPlaybackRate
2621 //
2622 // TODO
2623 //---------------------------------------------------------------------------
2624 double wxMCIMediaBackend::GetPlaybackRate()
2625 {
2626 return 1.0;
2627 }
2628
2629 //---------------------------------------------------------------------------
2630 // wxMCIMediaBackend::SetPlaybackRate
2631 //
2632 // TODO
2633 //---------------------------------------------------------------------------
2634 bool wxMCIMediaBackend::SetPlaybackRate(double WXUNUSED(dRate))
2635 {
2636 /*
2637 MCI_WAVE_SET_SAMPLESPERSEC
2638 MCI_DGV_SET_PARMS setParms;
2639 setParms.dwSpeed = (DWORD) (dRate * 1000.0);
2640
2641 return (mciSendCommand(m_hDev, MCI_SET,
2642 0x00020000L, //MCI_DGV_SET_SPEED
2643 (DWORD)(LPSTR)&setParms) == 0);
2644 */
2645 return false;
2646 }
2647
2648 //---------------------------------------------------------------------------
2649 // [static] wxMCIMediaBackend::MSWWindowProc
2650 //
2651 // Here we process a message when MCI reaches the stopping point
2652 // in the stream
2653 //---------------------------------------------------------------------------
2654 LRESULT CALLBACK wxMCIMediaBackend::NotifyWndProc(HWND hWnd, UINT nMsg,
2655 WPARAM wParam,
2656 LPARAM lParam)
2657 {
2658 wxMCIMediaBackend* backend =
2659 (wxMCIMediaBackend*)wxGetWindowUserData(hWnd);
2660
2661 return backend->OnNotifyWndProc(hWnd, nMsg, wParam, lParam);
2662 }
2663
2664 LRESULT CALLBACK wxMCIMediaBackend::OnNotifyWndProc(HWND hWnd, UINT nMsg,
2665 WPARAM wParam,
2666 LPARAM lParam)
2667 {
2668 if(nMsg == MM_MCINOTIFY)
2669 {
2670 wxASSERT(lParam == (LPARAM) m_hDev);
2671 if(wParam == MCI_NOTIFY_SUCCESSFUL && lParam == (LPARAM)m_hDev)
2672 {
2673 if ( SendStopEvent() )
2674 {
2675 wxMCIVERIFY( mciSendCommand(m_hDev, MCI_SEEK,
2676 MCI_SEEK_TO_START, 0) );
2677
2678 QueueFinishEvent();
2679 }
2680 }
2681 }
2682 return DefWindowProc(hWnd, nMsg, wParam, lParam);
2683 }
2684 #endif
2685 // __WXWINCE__
2686
2687 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2688 //
2689 // wxQTMediaBackend
2690 //
2691 // TODO: Use a less cludgy way to pause/get state/set state
2692 // FIXME: Greg Hazel reports that sometimes files that cannot be played
2693 // with this backend are treated as playable anyway - not verifyed though.
2694 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2695
2696 IMPLEMENT_DYNAMIC_CLASS(wxQTMediaBackend, wxMediaBackend)
2697
2698 //Time between timer calls - this is the Apple recommondation to the TCL
2699 //team I believe
2700 #define MOVIE_DELAY 20
2701
2702 #include "wx/timer.h"
2703
2704
2705 //---------------------------------------------------------------------------
2706 // wxQTLoadTimer
2707 //
2708 // QT, esp. QT for Windows is very picky about how you go about
2709 // async loading. If you were to go through a Windows message loop
2710 // or a MoviesTask or both and then check the movie load state
2711 // it would still return 1000 (loading)... even (pre)prerolling doesn't
2712 // help. However, making a load timer like this works
2713 //---------------------------------------------------------------------------
2714 class wxQTLoadTimer : public wxTimer
2715 {
2716 public:
2717 wxQTLoadTimer(Movie movie, wxQTMediaBackend* parent, wxQuickTimeLibrary* pLib) :
2718 m_movie(movie), m_parent(parent), m_pLib(pLib) {}
2719
2720 void Notify()
2721 {
2722 m_pLib->MoviesTask(m_movie, 0);
2723 //kMovieLoadStatePlayable
2724 if(m_pLib->GetMovieLoadState(m_movie) >= 10000)
2725 {
2726 m_parent->FinishLoad();
2727 delete this;
2728 }
2729 }
2730
2731 protected:
2732 Movie m_movie; //Our movie instance
2733 wxQTMediaBackend* m_parent; //Backend pointer
2734 wxQuickTimeLibrary* m_pLib; //Interfaces
2735 };
2736
2737
2738 // --------------------------------------------------------------------------
2739 // wxQTPlayTimer - Handle Asyncronous Playing
2740 //
2741 // 1) Checks to see if the movie is done, and if not continues
2742 // streaming the movie
2743 // 2) Sends the wxEVT_MEDIA_STOP event if we have reached the end of
2744 // the movie.
2745 // --------------------------------------------------------------------------
2746 class wxQTPlayTimer : public wxTimer
2747 {
2748 public:
2749 wxQTPlayTimer(Movie movie, wxQTMediaBackend* parent,
2750 wxQuickTimeLibrary* pLib) :
2751 m_movie(movie), m_parent(parent), m_pLib(pLib) {}
2752
2753 void Notify()
2754 {
2755 //
2756 // OK, a little explaining - basically originally
2757 // we only called MoviesTask if the movie was actually
2758 // playing (not paused or stopped)... this was before
2759 // we realized MoviesTask actually handles repainting
2760 // of the current frame - so if you were to resize
2761 // or something it would previously not redraw that
2762 // portion of the movie.
2763 //
2764 // So now we call MoviesTask always so that it repaints
2765 // correctly.
2766 //
2767 m_pLib->MoviesTask(m_movie, 0);
2768
2769 //
2770 // Handle the stop event - if the movie has reached
2771 // the end, notify our handler
2772 //
2773 // m_bPlaying == !(Stopped | Paused)
2774 //
2775 if (m_parent->m_bPlaying)
2776 {
2777 if(m_pLib->IsMovieDone(m_movie))
2778 {
2779 if ( m_parent->SendStopEvent() )
2780 {
2781 m_parent->Stop();
2782 wxASSERT(m_pLib->GetMoviesError() == noErr);
2783
2784 m_parent->QueueFinishEvent();
2785 }
2786 }
2787 }
2788 }
2789
2790 protected:
2791 Movie m_movie; //Our movie instance
2792 wxQTMediaBackend* m_parent; //Backend pointer
2793 wxQuickTimeLibrary* m_pLib; //Interfaces
2794 };
2795
2796
2797 //---------------------------------------------------------------------------
2798 // wxQTMediaBackend::QTWndProc
2799 //
2800 // Forwards events to the Movie Controller so that it can
2801 // redraw itself/process messages etc..
2802 //---------------------------------------------------------------------------
2803 LRESULT CALLBACK wxQTMediaBackend::QTWndProc(HWND hWnd, UINT nMsg,
2804 WPARAM wParam, LPARAM lParam)
2805 {
2806 wxQTMediaBackend* pThis = (wxQTMediaBackend*)wxGetWindowUserData(hWnd);
2807
2808 MSG msg;
2809 msg.hwnd = hWnd;
2810 msg.message = nMsg;
2811 msg.wParam = wParam;
2812 msg.lParam = lParam;
2813 msg.time = 0;
2814 msg.pt.x = 0;
2815 msg.pt.y = 0;
2816 EventRecord theEvent;
2817 pThis->m_lib.NativeEventToMacEvent(&msg, &theEvent);
2818 pThis->m_lib.MCIsPlayerEvent(pThis->m_pMC, &theEvent);
2819 return pThis->m_ctrl->MSWWindowProc(nMsg, wParam, lParam);
2820 }
2821
2822 //---------------------------------------------------------------------------
2823 // wxQTMediaBackend Destructor
2824 //
2825 // Sets m_timer to NULL signifying we havn't loaded anything yet
2826 //---------------------------------------------------------------------------
2827 wxQTMediaBackend::wxQTMediaBackend()
2828 : m_movie(NULL), m_bPlaying(false), m_timer(NULL), m_pMC(NULL)
2829 {
2830 }
2831
2832 //---------------------------------------------------------------------------
2833 // wxQTMediaBackend Destructor
2834 //
2835 // 1) Cleans up the QuickTime movie instance
2836 // 2) Decrements the QuickTime reference counter - if this reaches
2837 // 0, QuickTime shuts down
2838 // 3) Decrements the QuickTime Windows Media Layer reference counter -
2839 // if this reaches 0, QuickTime shuts down the Windows Media Layer
2840 //---------------------------------------------------------------------------
2841 wxQTMediaBackend::~wxQTMediaBackend()
2842 {
2843 if(m_movie)
2844 Cleanup();
2845
2846 if(m_lib.IsOk())
2847 {
2848 if(m_pMC)
2849 {
2850 m_lib.DisposeMovieController(m_pMC);
2851 // m_pMC = NULL;
2852 }
2853
2854 // destroy wxQTMediaEvtHandler we pushed on it
2855 m_ctrl->PopEventHandler(true);
2856
2857 m_lib.DestroyPortAssociation(
2858 (CGrafPtr)m_lib.GetNativeWindowPort(m_ctrl->GetHWND()));
2859
2860 //Note that ExitMovies() is not necessary, but
2861 //the docs are fuzzy on whether or not TerminateQTML is
2862 m_lib.ExitMovies();
2863 m_lib.TerminateQTML();
2864 }
2865 }
2866
2867 //---------------------------------------------------------------------------
2868 // wxQTMediaBackend::CreateControl
2869 //
2870 // 1) Intializes QuickTime
2871 // 2) Creates the control window
2872 //---------------------------------------------------------------------------
2873 bool wxQTMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent,
2874 wxWindowID id,
2875 const wxPoint& pos,
2876 const wxSize& size,
2877 long style,
2878 const wxValidator& validator,
2879 const wxString& name)
2880 {
2881 if(!m_lib.Initialize())
2882 return false;
2883
2884 int nError = m_lib.InitializeQTML(0);
2885 if (nError != noErr) //-2093 no dll
2886 {
2887 wxFAIL_MSG(wxString::Format(wxT("Couldn't Initialize Quicktime-%i"),
2888 nError));
2889 return false;
2890 }
2891 m_lib.EnterMovies();
2892
2893 //
2894 // Create window
2895 // By default wxWindow(s) is created with a border -
2896 // so we need to get rid of those
2897 //
2898 // Since we don't have a child window like most other
2899 // backends, we don't need wxCLIP_CHILDREN
2900 //
2901 if ( !ctrl->wxControl::Create(parent, id, pos, size,
2902 (style & ~wxBORDER_MASK) | wxBORDER_NONE,
2903 validator, name) )
2904 return false;
2905
2906
2907 m_ctrl = wxStaticCast(ctrl, wxMediaCtrl);
2908
2909 // Create a port association for our window so we
2910 // can use it as a WindowRef
2911 m_lib.CreatePortAssociation(m_ctrl->GetHWND(), NULL, 0L);
2912
2913 //Part of a suggestion from Greg Hazel to repaint
2914 //movie when idle
2915 m_ctrl->PushEventHandler(new wxQTMediaEvtHandler(this, m_ctrl->GetHWND()));
2916
2917 // done
2918 return true;
2919 }
2920
2921 //---------------------------------------------------------------------------
2922 // wxQTMediaBackend::Load (file version)
2923 //
2924 // 1) Get an FSSpec from the Windows path name
2925 // 2) Open the movie
2926 // 3) Obtain the movie instance from the movie resource
2927 // 4) Close the movie resource
2928 // 5) Finish loading
2929 //---------------------------------------------------------------------------
2930 bool wxQTMediaBackend::Load(const wxString& fileName)
2931 {
2932 if(m_movie)
2933 Cleanup();
2934
2935 short movieResFile = 0; //= 0 because of annoying VC6 warning
2936 FSSpec sfFile;
2937
2938 if (m_lib.NativePathNameToFSSpec ((char*) (const char*) fileName.mb_str(),
2939 &sfFile, 0) != noErr)
2940 return false;
2941
2942 if (m_lib.OpenMovieFile (&sfFile, &movieResFile, fsRdPerm) != noErr)
2943 return false;
2944
2945 short movieResID = 0;
2946 Str255 movieName;
2947
2948 OSErr err = m_lib.NewMovieFromFile (
2949 &m_movie,
2950 movieResFile,
2951 &movieResID,
2952 movieName,
2953 newMovieActive,
2954 NULL
2955 ); //wasChanged
2956
2957 //m_lib.GetMoviesStickyError() because it may not find the
2958 //proper codec and play black video and other strange effects,
2959 //not to mention mess up the dynamic backend loading scheme
2960 //of wxMediaCtrl - so it just does what the QuickTime player does
2961 if(err == noErr && m_lib.GetMoviesStickyError() == noErr)
2962 {
2963 m_lib.CloseMovieFile (movieResFile);
2964
2965 FinishLoad();
2966 return true;
2967 }
2968 else
2969 return false;
2970 }
2971
2972
2973 //---------------------------------------------------------------------------
2974 // wxQTMediaBackend::PPRMProc (static)
2975 //
2976 // Called when done PrePrerolling the movie.
2977 // Note that in 99% of the cases this does nothing...
2978 // Anyway we set up the loading timer here to tell us when the movie is done
2979 //---------------------------------------------------------------------------
2980 void wxQTMediaBackend::PPRMProc (Movie theMovie,
2981 OSErr WXUNUSED_UNLESS_DEBUG(theErr),
2982 void* theRefCon)
2983 {
2984 wxASSERT( theMovie );
2985 wxASSERT( theRefCon );
2986 wxASSERT( theErr == noErr );
2987
2988 wxQTMediaBackend* pBE = (wxQTMediaBackend*) theRefCon;
2989
2990 long lTime = pBE->m_lib.GetMovieTime(theMovie,NULL);
2991 Fixed rate = pBE->m_lib.GetMoviePreferredRate(theMovie);
2992 pBE->m_lib.PrerollMovie(theMovie,lTime,rate);
2993 pBE->m_timer = new wxQTLoadTimer(pBE->m_movie, pBE, &pBE->m_lib);
2994 pBE->m_timer->Start(MOVIE_DELAY);
2995 }
2996
2997
2998 //---------------------------------------------------------------------------
2999 // wxQTMediaBackend::Load (URL Version)
3000 //
3001 // 1) Build an escaped URI from location
3002 // 2) Create a handle to store the URI string
3003 // 3) Put the URI string inside the handle
3004 // 4) Make a QuickTime URL data ref from the handle with the URI in it
3005 // 5) Clean up the URI string handle
3006 // 6) Do some prerolling
3007 // 7) Finish Loading
3008 //---------------------------------------------------------------------------
3009 bool wxQTMediaBackend::Load(const wxURI& location)
3010 {
3011 if(m_movie)
3012 Cleanup();
3013
3014 wxString theURI = location.BuildURI();
3015
3016 Handle theHandle = m_lib.NewHandleClear(theURI.length() + 1);
3017 wxASSERT(theHandle);
3018
3019 m_lib.BlockMove(theURI.mb_str(), *theHandle, theURI.length() + 1);
3020
3021 //create the movie from the handle that refers to the URI
3022 OSErr err = m_lib.NewMovieFromDataRef(&m_movie, newMovieActive |
3023 newMovieAsyncOK
3024 /*|newMovieIdleImportOK*/,
3025 NULL, theHandle,
3026 URLDataHandlerSubType);
3027
3028 m_lib.DisposeHandle(theHandle);
3029
3030 if (err == noErr)
3031 {
3032 long timeNow;
3033 Fixed playRate;
3034
3035 timeNow = m_lib.GetMovieTime(m_movie, NULL);
3036 wxASSERT(m_lib.GetMoviesError() == noErr);
3037
3038 playRate = m_lib.GetMoviePreferredRate(m_movie);
3039 wxASSERT(m_lib.GetMoviesError() == noErr);
3040
3041 //
3042 // Note that the callback here is optional,
3043 // but without it PrePrerollMovie can be buggy
3044 // (see Apple ml). Also, some may wonder
3045 // why we need this at all - this is because
3046 // Apple docs say QuickTime streamed movies
3047 // require it if you don't use a Movie Controller,
3048 // which we don't by default.
3049 //
3050 m_lib.PrePrerollMovie(m_movie, timeNow, playRate,
3051 (WXFARPROC)wxQTMediaBackend::PPRMProc,
3052 (void*)this);
3053 return true;
3054 }
3055 else
3056 return false;
3057 }
3058
3059
3060 //---------------------------------------------------------------------------
3061 // wxQTMediaBackend::FinishLoad
3062 //
3063 // 1) Create the movie timer
3064 // 2) Get real size of movie for GetBestSize/sizers
3065 // 3) Set the movie time scale to something usable so that seeking
3066 // etc. will work correctly
3067 // 4) Set our Movie Controller to display the movie if it exists,
3068 // otherwise set the bounds of the Movie
3069 // 5) Refresh parent window
3070 //---------------------------------------------------------------------------
3071 void wxQTMediaBackend::FinishLoad()
3072 {
3073 // Create the playing/streaming timer
3074 m_timer = new wxQTPlayTimer(m_movie, (wxQTMediaBackend*) this, &m_lib);
3075 wxASSERT(m_timer);
3076 m_timer->Start(MOVIE_DELAY, wxTIMER_CONTINUOUS);
3077
3078 //get the real size of the movie
3079 Rect outRect;
3080 memset(&outRect, 0, sizeof(Rect)); //for annoying VC6 warning
3081 m_lib.GetMovieNaturalBoundsRect (m_movie, &outRect);
3082 wxASSERT(m_lib.GetMoviesError() == noErr);
3083
3084 m_bestSize.x = outRect.right - outRect.left;
3085 m_bestSize.y = outRect.bottom - outRect.top;
3086
3087 //
3088 // Handle the movie GWorld
3089 //
3090 if(m_pMC)
3091 {
3092 Point thePoint;
3093 thePoint.h = thePoint.v = 0;
3094 m_lib.MCSetMovie(m_pMC, m_movie,
3095 m_lib.GetNativeWindowPort(m_ctrl->GetHandle()),
3096 thePoint);
3097 m_lib.MCSetVisible(m_pMC, true);
3098 m_bestSize.y += 16;
3099 }
3100 else
3101 {
3102 m_lib.SetMovieGWorld(m_movie,
3103 (CGrafPtr) m_lib.GetNativeWindowPort(m_ctrl->GetHWND()),
3104 NULL);
3105 }
3106
3107 //
3108 // Set the movie to millisecond precision
3109 //
3110 m_lib.SetMovieTimeScale(m_movie, 1000);
3111 wxASSERT(m_lib.GetMoviesError() == noErr);
3112
3113 NotifyMovieLoaded();
3114 }
3115
3116 //---------------------------------------------------------------------------
3117 // wxQTMediaBackend::Play
3118 //
3119 // 1) Start the QT movie
3120 // 2) Start the movie loading timer
3121 //
3122 // NOTE: This will still return success even when
3123 // the movie is still loading, and as mentioned in wxQTLoadTimer
3124 // I don't know of a way to force this to be sync - so if its
3125 // still loading the function will return true but the movie will
3126 // still be in the stopped state
3127 //---------------------------------------------------------------------------
3128 bool wxQTMediaBackend::Play()
3129 {
3130 m_lib.StartMovie(m_movie);
3131 m_bPlaying = true;
3132 return m_lib.GetMoviesError() == noErr;
3133 }
3134
3135 //---------------------------------------------------------------------------
3136 // wxQTMediaBackend::Pause
3137 //
3138 // 1) Stop the movie
3139 // 2) Stop the movie timer
3140 //---------------------------------------------------------------------------
3141 bool wxQTMediaBackend::Pause()
3142 {
3143 m_bPlaying = false;
3144 m_lib.StopMovie(m_movie);
3145 return m_lib.GetMoviesError() == noErr;
3146 }
3147
3148 //---------------------------------------------------------------------------
3149 // wxQTMediaBackend::Stop
3150 //
3151 // 1) Stop the movie
3152 // 2) Stop the movie timer
3153 // 3) Seek to the beginning of the movie
3154 //---------------------------------------------------------------------------
3155 bool wxQTMediaBackend::Stop()
3156 {
3157 m_bPlaying = false;
3158
3159 m_lib.StopMovie(m_movie);
3160 if(m_lib.GetMoviesError() != noErr)
3161 return false;
3162
3163 m_lib.GoToBeginningOfMovie(m_movie);
3164 return m_lib.GetMoviesError() == noErr;
3165 }
3166
3167 //---------------------------------------------------------------------------
3168 // wxQTMediaBackend::GetPlaybackRate
3169 //
3170 // 1) Get the movie playback rate from ::GetMovieRate
3171 //---------------------------------------------------------------------------
3172 double wxQTMediaBackend::GetPlaybackRate()
3173 {
3174 return ( ((double)m_lib.GetMovieRate(m_movie)) / 0x10000);
3175 }
3176
3177 //---------------------------------------------------------------------------
3178 // wxQTMediaBackend::SetPlaybackRate
3179 //
3180 // 1) Convert dRate to Fixed and Set the movie rate through SetMovieRate
3181 //---------------------------------------------------------------------------
3182 bool wxQTMediaBackend::SetPlaybackRate(double dRate)
3183 {
3184 m_lib.SetMovieRate(m_movie, (Fixed) (dRate * 0x10000));
3185 return m_lib.GetMoviesError() == noErr;
3186 }
3187
3188 //---------------------------------------------------------------------------
3189 // wxQTMediaBackend::SetPosition
3190 //
3191 // 1) Create a time record struct (TimeRecord) with appropriate values
3192 // 2) Pass struct to SetMovieTime
3193 //---------------------------------------------------------------------------
3194 bool wxQTMediaBackend::SetPosition(wxLongLong where)
3195 {
3196 //NB: For some reason SetMovieTime does not work
3197 //correctly with the Quicktime Windows SDK (6)
3198 //From Muskelkatermann at the wxForum
3199 //http://www.solidsteel.nl/users/wxwidgets/viewtopic.php?t=2957
3200 //RN - note that I have not verified this but there
3201 //is no harm in calling SetMovieTimeValue instead
3202 #if 0
3203 TimeRecord theTimeRecord;
3204 memset(&theTimeRecord, 0, sizeof(TimeRecord));
3205 theTimeRecord.value.lo = where.GetLo();
3206 theTimeRecord.scale = m_lib.GetMovieTimeScale(m_movie);
3207 theTimeRecord.base = m_lib.GetMovieTimeBase(m_movie);
3208 m_lib.SetMovieTime(m_movie, &theTimeRecord);
3209 #else
3210 m_lib.SetMovieTimeValue(m_movie, where.GetLo());
3211 #endif
3212 if (m_lib.GetMoviesError() != noErr)
3213 return false;
3214
3215 return true;
3216 }
3217
3218 //---------------------------------------------------------------------------
3219 // wxQTMediaBackend::GetPosition
3220 //
3221 // 1) Calls GetMovieTime to get the position we are in in the movie
3222 // in milliseconds (we called
3223 //---------------------------------------------------------------------------
3224 wxLongLong wxQTMediaBackend::GetPosition()
3225 {
3226 return m_lib.GetMovieTime(m_movie, NULL);
3227 }
3228
3229 //---------------------------------------------------------------------------
3230 // wxQTMediaBackend::GetVolume
3231 //
3232 // Gets the volume through GetMovieVolume - which returns a 16 bit short -
3233 //
3234 // +--------+--------+
3235 // + (1) + (2) +
3236 // +--------+--------+
3237 //
3238 // (1) first 8 bits are value before decimal
3239 // (2) second 8 bits are value after decimal
3240 //
3241 // Volume ranges from -1.0 (gain but no sound), 0 (no sound and no gain) to
3242 // 1 (full gain and sound)
3243 //---------------------------------------------------------------------------
3244 double wxQTMediaBackend::GetVolume()
3245 {
3246 short sVolume = m_lib.GetMovieVolume(m_movie);
3247 wxASSERT(m_lib.GetMoviesError() == noErr);
3248
3249 if(sVolume & (128 << 8)) //negative - no sound
3250 return 0.0;
3251
3252 return sVolume/256.0;
3253 }
3254
3255 //---------------------------------------------------------------------------
3256 // wxQTMediaBackend::SetVolume
3257 //
3258 // Sets the volume through SetMovieVolume - which takes a 16 bit short -
3259 //
3260 // +--------+--------+
3261 // + (1) + (2) +
3262 // +--------+--------+
3263 //
3264 // (1) first 8 bits are value before decimal
3265 // (2) second 8 bits are value after decimal
3266 //
3267 // Volume ranges from -1.0 (gain but no sound), 0 (no sound and no gain) to
3268 // 1 (full gain and sound)
3269 //---------------------------------------------------------------------------
3270 bool wxQTMediaBackend::SetVolume(double dVolume)
3271 {
3272 m_lib.SetMovieVolume(m_movie, (short) (dVolume * 256));
3273 return m_lib.GetMoviesError() == noErr;
3274 }
3275
3276 //---------------------------------------------------------------------------
3277 // wxQTMediaBackend::GetDuration
3278 //
3279 // Calls GetMovieDuration
3280 //---------------------------------------------------------------------------
3281 wxLongLong wxQTMediaBackend::GetDuration()
3282 {
3283 return m_lib.GetMovieDuration(m_movie);
3284 }
3285
3286 //---------------------------------------------------------------------------
3287 // wxQTMediaBackend::GetState
3288 //
3289 // Determines the current state - if we are at the beginning we
3290 // are stopped
3291 //---------------------------------------------------------------------------
3292 wxMediaState wxQTMediaBackend::GetState()
3293 {
3294 if (m_bPlaying == true)
3295 return wxMEDIASTATE_PLAYING;
3296 else if ( !m_movie || wxQTMediaBackend::GetPosition() == 0)
3297 return wxMEDIASTATE_STOPPED;
3298 else
3299 return wxMEDIASTATE_PAUSED;
3300 }
3301
3302 //---------------------------------------------------------------------------
3303 // wxQTMediaBackend::Cleanup
3304 //
3305 // Diposes of the movie timer, Disassociates the Movie Controller with
3306 // movie and hides it if it exists, and stops and disposes
3307 // of the QT movie
3308 //---------------------------------------------------------------------------
3309 void wxQTMediaBackend::Cleanup()
3310 {
3311 m_bPlaying = false;
3312
3313 if(m_timer)
3314 {
3315 delete m_timer;
3316 m_timer = NULL;
3317 }
3318
3319 m_lib.StopMovie(m_movie);
3320
3321 if(m_pMC)
3322 {
3323 Point thePoint;
3324 thePoint.h = thePoint.v = 0;
3325 m_lib.MCSetVisible(m_pMC, false);
3326 m_lib.MCSetMovie(m_pMC, NULL, NULL, thePoint);
3327 }
3328
3329 m_lib.DisposeMovie(m_movie);
3330 m_movie = NULL;
3331 }
3332
3333 //---------------------------------------------------------------------------
3334 // wxQTMediaBackend::ShowPlayerControls
3335 //
3336 // Creates a movie controller for the Movie if the user wants it
3337 //---------------------------------------------------------------------------
3338 bool wxQTMediaBackend::ShowPlayerControls(wxMediaCtrlPlayerControls flags)
3339 {
3340 if(m_pMC)
3341 {
3342 //restore old wndproc
3343 wxSetWindowProc((HWND)m_ctrl->GetHWND(), wxWndProc);
3344 m_lib.DisposeMovieController(m_pMC);
3345 m_pMC = NULL;
3346 m_bestSize.y -= 16; //movie controller height
3347 }
3348
3349 if(flags && m_movie)
3350 {
3351 Rect rect;
3352 wxRect wxrect = m_ctrl->GetClientRect();
3353
3354 //make room for controller
3355 if(wxrect.width < 320)
3356 wxrect.width = 320;
3357
3358 rect.top = (short)wxrect.y;
3359 rect.left = (short)wxrect.x;
3360 rect.right = (short)(rect.left + wxrect.width);
3361 rect.bottom = (short)(rect.top + wxrect.height);
3362
3363 if(!m_pMC)
3364 {
3365 m_pMC = m_lib.NewMovieController(m_movie, &rect, mcTopLeftMovie |
3366 // mcScaleMovieToFit |
3367 // mcWithBadge |
3368 mcWithFrame);
3369 m_lib.MCDoAction(m_pMC, 32, (void*)true); //mcActionSetKeysEnabled
3370 m_lib.MCSetActionFilterWithRefCon(m_pMC,
3371 (WXFARPROC)wxQTMediaBackend::MCFilterProc, (void*)this);
3372 m_bestSize.y += 16; //movie controller height
3373
3374 //
3375 // By default the movie controller uses its own color
3376 // pallette for the movie which can be bad on some files -
3377 // so turn it off. Also turn off its frame/border for
3378 // the movie
3379 //
3380 // Also we take care of a couple of the interface flags here
3381 //
3382 long mcFlags = 0;
3383 m_lib.MCDoAction(m_pMC, 39/*mcActionGetFlags*/, (void*)&mcFlags);
3384 mcFlags |= ( //(1<<0)/*mcFlagSuppressMovieFrame*/ |
3385 (1<<3)/*mcFlagsUseWindowPalette*/
3386 | ((flags & wxMEDIACTRLPLAYERCONTROLS_STEP)
3387 ? 0 : (1<<1)/*mcFlagSuppressStepButtons*/)
3388 | ((flags & wxMEDIACTRLPLAYERCONTROLS_VOLUME)
3389 ? 0 : (1<<2)/*mcFlagSuppressSpeakerButton*/)
3390 // | (1<<4) /*mcFlagDontInvalidate*/ //if we take care of repainting ourselves
3391 );
3392 m_lib.MCDoAction(m_pMC, 38/*mcActionSetFlags*/, (void*)mcFlags);
3393
3394 //intercept the wndproc of our control window
3395 wxSetWindowProc((HWND)m_ctrl->GetHWND(),
3396 wxQTMediaBackend::QTWndProc);
3397
3398 //set the user data of our window
3399 wxSetWindowUserData((HWND)m_ctrl->GetHWND(), this);
3400 }
3401 }
3402
3403 NotifyMovieSizeChanged();
3404
3405 return m_lib.GetMoviesError() == noErr;
3406 }
3407
3408 //---------------------------------------------------------------------------
3409 // wxQTMediaBackend::MCFilterProc (static)
3410 //
3411 // Callback for when the movie controller recieves a message
3412 //---------------------------------------------------------------------------
3413 Boolean
3414 wxQTMediaBackend::MCFilterProc(MovieController WXUNUSED(theController),
3415 short action,
3416 void * WXUNUSED(params),
3417 LONG_PTR refCon)
3418 {
3419 if(action != 1) //don't process idle events
3420 {
3421 wxQTMediaBackend* pThis = (wxQTMediaBackend*)refCon;
3422
3423 switch(action)
3424 {
3425 case 8: //play button triggered - MC will set movie to opposite state
3426 //of current - playing ? paused : playing
3427 pThis->m_bPlaying = !(pThis->m_bPlaying);
3428
3429 // NB: Sometimes it doesn't redraw properly -
3430 // if you click on the button but don't move the mouse
3431 // the button will not change its state until you move
3432 // mcActionDraw and Refresh/Update combo do nothing
3433 // to help this unfortunately
3434 break;
3435 default:
3436 break;
3437 }
3438 }
3439 return 0;
3440 }
3441
3442 //---------------------------------------------------------------------------
3443 // wxQTMediaBackend::GetVideoSize
3444 //
3445 // Returns the actual size of the QT movie
3446 //---------------------------------------------------------------------------
3447 wxSize wxQTMediaBackend::GetVideoSize() const
3448 {
3449 return m_bestSize;
3450 }
3451
3452 //---------------------------------------------------------------------------
3453 // wxQTMediaBackend::Move
3454 //
3455 // Sets the bounds of either the Movie or Movie Controller
3456 //---------------------------------------------------------------------------
3457 void wxQTMediaBackend::Move(int WXUNUSED(x), int WXUNUSED(y), int w, int h)
3458 {
3459 if(m_movie)
3460 {
3461 //make room for controller
3462 if(m_pMC)
3463 {
3464 if(w < 320)
3465 w = 320;
3466
3467 Rect theRect = {0, 0, (short)h, (short)w};
3468 m_lib.MCSetControllerBoundsRect(m_pMC, &theRect);
3469 }
3470 else
3471 {
3472 Rect theRect = {0, 0, (short)h, (short)w};
3473 m_lib.SetMovieBox(m_movie, &theRect);
3474 }
3475
3476 wxASSERT(m_lib.GetMoviesError() == noErr);
3477 }
3478 }
3479
3480 //---------------------------------------------------------------------------
3481 // wxQTMediaBackend::OnEraseBackground
3482 //
3483 // Suggestion from Greg Hazel to repaint the movie when idle
3484 // (on pause also)
3485 //
3486 // TODO: We may be repainting too much here - under what exact circumstances
3487 // do we need this? I think Move also repaints correctly for the Movie
3488 // Controller, so in that instance we don't need this either
3489 //---------------------------------------------------------------------------
3490 void wxQTMediaEvtHandler::OnEraseBackground(wxEraseEvent& evt)
3491 {
3492 wxQuickTimeLibrary& m_pLib = m_qtb->m_lib;
3493
3494 if ( m_qtb->m_pMC )
3495 {
3496 // repaint movie controller
3497 m_pLib.MCDoAction(m_qtb->m_pMC, 2 /*mcActionDraw*/,
3498 m_pLib.GetNativeWindowPort(m_hwnd));
3499 }
3500 else // no movie controller
3501 {
3502 if ( m_qtb->m_movie )
3503 {
3504 CGrafPtr port = (CGrafPtr)m_pLib.GetNativeWindowPort(m_hwnd);
3505
3506 m_pLib.BeginUpdate(port);
3507 m_pLib.UpdateMovie(m_qtb->m_movie);
3508 wxASSERT(m_pLib.GetMoviesError() == noErr);
3509 m_pLib.EndUpdate(port);
3510 }
3511 else // no movie
3512 {
3513 // let the system repaint the window
3514 evt.Skip();
3515 }
3516 }
3517 }
3518
3519 //---------------------------------------------------------------------------
3520 // End QT Backend
3521 //---------------------------------------------------------------------------
3522
3523 //in source file that contains stuff you don't directly use
3524 #include "wx/html/forcelnk.h"
3525 FORCE_LINK_ME(basewxmediabackends)
3526
3527 //---------------------------------------------------------------------------
3528 // End wxMediaCtrl Compilation Guard and this file
3529 //---------------------------------------------------------------------------
3530 #endif //wxUSE_MEDIACTRL