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