]>
Commit | Line | Data |
---|---|---|
1a680109 | 1 | ///////////////////////////////////////////////////////////////////////////// |
ff4aedc5 RN |
2 | // Name: mac/carbon/mediactrl.cpp |
3 | // Purpose: Built-in Media Backends for Mac | |
1a680109 | 4 | // Author: Ryan Norton <wxprojects@comcast.net> |
ff4aedc5 | 5 | // Modified by: |
1a680109 RN |
6 | // Created: 11/07/04 |
7 | // RCS-ID: $Id$ | |
3b5023b9 | 8 | // Copyright: (c) 2004-2005 Ryan Norton, portions (c) 2004 Kevin Olliver |
1a680109 RN |
9 | // Licence: wxWindows licence |
10 | ///////////////////////////////////////////////////////////////////////////// | |
11 | ||
ff4aedc5 RN |
12 | //=========================================================================== |
13 | // DECLARATIONS | |
14 | //=========================================================================== | |
15 | ||
16 | //--------------------------------------------------------------------------- | |
17 | // Pre-compiled header stuff | |
18 | //--------------------------------------------------------------------------- | |
19 | ||
20 | #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) | |
21 | #pragma implementation "mediactrl.h" | |
22 | #endif | |
1a680109 RN |
23 | |
24 | // For compilers that support precompilation, includes "wx.h". | |
25 | #include "wx/wxprec.h" | |
26 | ||
27 | #ifdef __BORLANDC__ | |
28 | #pragma hdrstop | |
29 | #endif | |
30 | ||
ff4aedc5 RN |
31 | //--------------------------------------------------------------------------- |
32 | // Includes | |
33 | //--------------------------------------------------------------------------- | |
34 | #include "wx/mediactrl.h" | |
1a680109 | 35 | |
ff4aedc5 RN |
36 | //--------------------------------------------------------------------------- |
37 | // Compilation guard | |
38 | //--------------------------------------------------------------------------- | |
1a680109 RN |
39 | #if wxUSE_MEDIACTRL |
40 | ||
3b5023b9 RN |
41 | //--------------------------------------------------------------------------- |
42 | // Whether or not to use OSX 10.2's CreateMovieControl for native QuickTime | |
43 | // control - i.e. native positioning and event handling etc.. | |
44 | //--------------------------------------------------------------------------- | |
45 | #ifndef wxUSE_CREATEMOVIECONTROL | |
d0ee33f5 WS |
46 | # if defined( __WXMAC_OSX__ ) && ( MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_2 ) |
47 | # define wxUSE_CREATEMOVIECONTROL 1 | |
48 | # else | |
49 | # define wxUSE_CREATEMOVIECONTROL 0 | |
50 | # endif | |
3b5023b9 RN |
51 | #endif |
52 | ||
ff4aedc5 RN |
53 | //=========================================================================== |
54 | // BACKEND DECLARATIONS | |
55 | //=========================================================================== | |
212945de | 56 | |
ff4aedc5 RN |
57 | //--------------------------------------------------------------------------- |
58 | // | |
59 | // wxQTMediaBackend | |
60 | // | |
61 | //--------------------------------------------------------------------------- | |
1a680109 | 62 | |
ff4aedc5 RN |
63 | //--------------------------------------------------------------------------- |
64 | // QT Includes | |
65 | //--------------------------------------------------------------------------- | |
1a680109 | 66 | //uma is for wxMacFSSpec |
1a680109 | 67 | #include "wx/mac/uma.h" |
ff4aedc5 | 68 | #include "wx/timer.h" |
768c6e8b | 69 | #ifndef __DARWIN__ |
1a680109 RN |
70 | #include <Movies.h> |
71 | #include <Gestalt.h> | |
ff4aedc5 | 72 | #include <QuickTimeComponents.h> //Standard QT stuff |
768c6e8b SC |
73 | #else |
74 | #include <QuickTime/QuickTimeComponents.h> | |
75 | #endif | |
1a680109 | 76 | |
3b5023b9 | 77 | //Determines whether version 4 of QT is installed (Pretty much for classic only) |
ff4aedc5 RN |
78 | Boolean _wxIsQuickTime4Installed (void) |
79 | { | |
80 | short error; | |
81 | long result; | |
1a680109 | 82 | |
ff4aedc5 RN |
83 | error = Gestalt (gestaltQuickTime, &result); |
84 | return (error == noErr) && (((result >> 16) & 0xffff) >= 0x0400); | |
85 | } | |
86 | ||
ff2b312f | 87 | class WXDLLIMPEXP_MEDIA wxQTMediaBackend : public wxMediaBackend |
ff4aedc5 RN |
88 | { |
89 | public: | |
90 | ||
91 | wxQTMediaBackend(); | |
92 | ~wxQTMediaBackend(); | |
93 | ||
d0ee33f5 | 94 | virtual bool CreateControl(wxControl* ctrl, wxWindow* parent, |
ff4aedc5 | 95 | wxWindowID id, |
d0ee33f5 | 96 | const wxPoint& pos, |
ff4aedc5 | 97 | const wxSize& size, |
d0ee33f5 | 98 | long style, |
ff4aedc5 RN |
99 | const wxValidator& validator, |
100 | const wxString& name); | |
101 | ||
102 | virtual bool Play(); | |
103 | virtual bool Pause(); | |
104 | virtual bool Stop(); | |
105 | ||
106 | virtual bool Load(const wxString& fileName); | |
107 | virtual bool Load(const wxURI& location); | |
108 | ||
109 | virtual wxMediaState GetState(); | |
110 | ||
111 | virtual bool SetPosition(wxLongLong where); | |
112 | virtual wxLongLong GetPosition(); | |
113 | virtual wxLongLong GetDuration(); | |
114 | ||
115 | virtual void Move(int x, int y, int w, int h); | |
116 | wxSize GetVideoSize() const; | |
117 | ||
118 | virtual double GetPlaybackRate(); | |
119 | virtual bool SetPlaybackRate(double dRate); | |
120 | ||
121 | void Cleanup(); | |
122 | void FinishLoad(); | |
123 | ||
124 | wxSize m_bestSize; //Original movie size | |
20b69855 | 125 | #ifdef __WXMAC_OSX__ |
ff4aedc5 | 126 | struct MovieType** m_movie; //QT Movie handle/instance |
20b69855 SC |
127 | #else |
128 | Movie m_movie ; | |
129 | #endif | |
ff4aedc5 RN |
130 | wxControl* m_ctrl; //Parent control |
131 | bool m_bVideo; //Whether or not we have video | |
132 | class _wxQTTimer* m_timer; //Timer for streaming the movie | |
133 | ||
d0ee33f5 | 134 | DECLARE_DYNAMIC_CLASS(wxQTMediaBackend) |
ff4aedc5 RN |
135 | }; |
136 | ||
137 | ||
138 | //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | |
139 | // | |
140 | // wxQTMediaBackend | |
d0ee33f5 | 141 | // |
ff4aedc5 RN |
142 | //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
143 | ||
144 | IMPLEMENT_DYNAMIC_CLASS(wxQTMediaBackend, wxMediaBackend); | |
1a680109 RN |
145 | |
146 | //Time between timer calls | |
ff4aedc5 | 147 | #define MOVIE_DELAY 100 |
1a680109 | 148 | |
ff4aedc5 | 149 | // -------------------------------------------------------------------------- |
1a680109 | 150 | // wxQTTimer - Handle Asyncronous Playing |
ff4aedc5 | 151 | // -------------------------------------------------------------------------- |
1a680109 RN |
152 | class _wxQTTimer : public wxTimer |
153 | { | |
154 | public: | |
ff4aedc5 | 155 | _wxQTTimer(Movie movie, wxQTMediaBackend* parent) : |
1a680109 RN |
156 | m_movie(movie), m_bPaused(false), m_parent(parent) |
157 | { | |
158 | } | |
159 | ||
160 | ~_wxQTTimer() | |
161 | { | |
162 | } | |
163 | ||
164 | bool GetPaused() {return m_bPaused;} | |
165 | void SetPaused(bool bPaused) {m_bPaused = bPaused;} | |
166 | ||
ff4aedc5 RN |
167 | //----------------------------------------------------------------------- |
168 | // _wxQTTimer::Notify | |
169 | // | |
170 | // 1) Checks to see if the movie is done, and if not continues | |
171 | // streaming the movie | |
172 | // 2) Sends the wxEVT_MEDIA_STOP event if we have reached the end of | |
173 | // the movie. | |
174 | //----------------------------------------------------------------------- | |
1a680109 RN |
175 | void Notify() |
176 | { | |
177 | if (!m_bPaused) | |
178 | { | |
179 | if(!IsMovieDone(m_movie)) | |
d0ee33f5 | 180 | MoviesTask(m_movie, MOVIE_DELAY); |
1a680109 RN |
181 | else |
182 | { | |
d0ee33f5 | 183 | wxMediaEvent theEvent(wxEVT_MEDIA_STOP, |
ff4aedc5 RN |
184 | m_parent->m_ctrl->GetId()); |
185 | m_parent->m_ctrl->ProcessEvent(theEvent); | |
186 | ||
187 | if(theEvent.IsAllowed()) | |
188 | { | |
189 | Stop(); | |
190 | m_parent->Stop(); | |
191 | wxASSERT(::GetMoviesError() == noErr); | |
192 | ||
193 | //send the event to our child | |
d0ee33f5 | 194 | wxMediaEvent theEvent(wxEVT_MEDIA_FINISHED, |
ff4aedc5 RN |
195 | m_parent->m_ctrl->GetId()); |
196 | m_parent->m_ctrl->ProcessEvent(theEvent); | |
197 | } | |
1a680109 RN |
198 | } |
199 | } | |
200 | } | |
201 | ||
202 | protected: | |
ff4aedc5 RN |
203 | Movie m_movie; //Our movie instance |
204 | bool m_bPaused; //Whether we are paused or not | |
205 | wxQTMediaBackend* m_parent; //Backend pointer | |
1a680109 RN |
206 | }; |
207 | ||
ff4aedc5 | 208 | //--------------------------------------------------------------------------- |
e7b97da3 | 209 | // wxQTMediaBackend Constructor |
ff4aedc5 RN |
210 | // |
211 | // Sets m_timer to NULL signifying we havn't loaded anything yet | |
212 | //--------------------------------------------------------------------------- | |
213 | wxQTMediaBackend::wxQTMediaBackend() : m_timer(NULL) | |
1a680109 | 214 | { |
1a680109 RN |
215 | } |
216 | ||
ff4aedc5 RN |
217 | //--------------------------------------------------------------------------- |
218 | // wxQTMediaBackend Destructor | |
219 | // | |
220 | // 1) Cleans up the QuickTime movie instance | |
221 | // 2) Decrements the QuickTime reference counter - if this reaches | |
222 | // 0, QuickTime shuts down | |
223 | // 3) Decrements the QuickTime Windows Media Layer reference counter - | |
224 | // if this reaches 0, QuickTime shuts down the Windows Media Layer | |
225 | //--------------------------------------------------------------------------- | |
226 | wxQTMediaBackend::~wxQTMediaBackend() | |
1a680109 | 227 | { |
ff4aedc5 RN |
228 | if(m_timer) |
229 | Cleanup(); | |
1a680109 | 230 | |
3103e8a9 | 231 | //Note that ExitMovies() is not necessary... |
ff4aedc5 | 232 | ExitMovies(); |
1a680109 RN |
233 | } |
234 | ||
ff4aedc5 RN |
235 | //--------------------------------------------------------------------------- |
236 | // wxQTMediaBackend::CreateControl | |
237 | // | |
238 | // 1) Intializes QuickTime | |
239 | // 2) Creates the control window | |
240 | //--------------------------------------------------------------------------- | |
d0ee33f5 | 241 | bool wxQTMediaBackend::CreateControl(wxControl* ctrl, wxWindow* parent, |
ff4aedc5 | 242 | wxWindowID id, |
d0ee33f5 | 243 | const wxPoint& pos, |
ff4aedc5 | 244 | const wxSize& size, |
d0ee33f5 | 245 | long style, |
ff4aedc5 RN |
246 | const wxValidator& validator, |
247 | const wxString& name) | |
1a680109 | 248 | { |
3b5023b9 | 249 | //Don't bother in Native control mode |
d0ee33f5 | 250 | #if defined( __WXMAC__ ) && TARGET_API_MAC_OSX && ( MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_2 ) |
ff4aedc5 | 251 | if (!_wxIsQuickTime4Installed()) |
1a680109 | 252 | return false; |
3b5023b9 | 253 | #endif |
1a680109 | 254 | |
ff4aedc5 RN |
255 | EnterMovies(); |
256 | ||
257 | // | |
258 | // Create window | |
259 | // By default wxWindow(s) is created with a border - | |
260 | // so we need to get rid of those | |
261 | // | |
262 | // Since we don't have a child window like most other | |
263 | // backends, we don't need wxCLIP_CHILDREN | |
264 | // | |
3b5023b9 | 265 | if ( ! |
d0ee33f5 WS |
266 | |
267 | #if wxUSE_CREATEMOVIECONTROL | |
3dee36ae WS |
268 | ctrl->wxWindow::Create(parent, id, pos, size, |
269 | wxWindow::MacRemoveBordersFromStyle(style), | |
270 | name) | |
ecd20d4a | 271 | #else |
3dee36ae WS |
272 | ctrl->wxControl::Create(parent, id, pos, size, |
273 | wxWindow::MacRemoveBordersFromStyle(style), | |
274 | validator, name) | |
d0ee33f5 | 275 | #endif |
3b5023b9 | 276 | ) |
1a680109 RN |
277 | return false; |
278 | ||
ecd20d4a | 279 | #if wxUSE_VALIDATORS |
3dee36ae | 280 | ctrl->SetValidator(validator); |
ecd20d4a RN |
281 | #endif |
282 | ||
ff4aedc5 | 283 | m_ctrl = ctrl; |
1a680109 RN |
284 | return true; |
285 | } | |
286 | ||
ff4aedc5 RN |
287 | //--------------------------------------------------------------------------- |
288 | // wxQTMediaBackend::Load (file version) | |
289 | // | |
290 | // 1) Get an FSSpec from the Windows path name | |
291 | // 2) Open the movie | |
292 | // 3) Obtain the movie instance from the movie resource | |
3b5023b9 RN |
293 | // 4) Close the movie resource |
294 | // 5) Finish loading | |
ff4aedc5 RN |
295 | //--------------------------------------------------------------------------- |
296 | bool wxQTMediaBackend::Load(const wxString& fileName) | |
1a680109 | 297 | { |
ff4aedc5 | 298 | if(m_timer) |
1a680109 RN |
299 | Cleanup(); |
300 | ||
1a680109 RN |
301 | OSErr err = noErr; |
302 | short movieResFile; | |
303 | FSSpec sfFile; | |
d0ee33f5 WS |
304 | |
305 | //FIXME:wxMacFilename2FSSpec crashes on empty string - | |
099c3b27 RN |
306 | //does it crash on other strings too and should this |
307 | //"fix" be put in the carbon wxSound? | |
308 | if (fileName.empty()) | |
309 | return false; | |
d0ee33f5 | 310 | |
ff4aedc5 | 311 | wxMacFilename2FSSpec( fileName , &sfFile ); |
d0ee33f5 | 312 | |
1a680109 RN |
313 | if (OpenMovieFile (&sfFile, &movieResFile, fsRdPerm) != noErr) |
314 | return false; | |
315 | ||
316 | short movieResID = 0; | |
317 | Str255 movieName; | |
318 | ||
319 | err = NewMovieFromFile ( | |
320 | &m_movie, | |
321 | movieResFile, | |
322 | &movieResID, | |
323 | movieName, | |
324 | newMovieActive, | |
325 | NULL); //wasChanged | |
326 | ||
327 | CloseMovieFile (movieResFile); | |
328 | ||
329 | if (err != noErr) | |
330 | return false; | |
331 | ||
332 | FinishLoad(); | |
333 | ||
ff4aedc5 | 334 | return ::GetMoviesError() == noErr; |
1a680109 RN |
335 | } |
336 | ||
ff4aedc5 | 337 | //--------------------------------------------------------------------------- |
3b5023b9 | 338 | // wxQTMediaBackend::Load (URL Version) |
ff4aedc5 | 339 | // |
3b5023b9 RN |
340 | // 1) Build an escaped URI from location |
341 | // 2) Create a handle to store the URI string | |
342 | // 3) Put the URI string inside the handle | |
343 | // 4) Make a QuickTime URL data ref from the handle with the URI in it | |
344 | // 5) Clean up the URI string handle | |
345 | // 6) Do some prerolling | |
346 | // 7) Finish Loading | |
ff4aedc5 RN |
347 | //--------------------------------------------------------------------------- |
348 | bool wxQTMediaBackend::Load(const wxURI& location) | |
1a680109 | 349 | { |
ff4aedc5 | 350 | if(m_timer) |
1a680109 RN |
351 | Cleanup(); |
352 | ||
1a680109 RN |
353 | wxString theURI = location.BuildURI(); |
354 | ||
355 | OSErr err = noErr; | |
356 | ||
357 | Handle theHandle = NewHandleClear(theURI.length() + 1); | |
358 | wxASSERT(theHandle); | |
359 | ||
360 | BlockMove(theURI.mb_str(), *theHandle, theURI.length() + 1); | |
361 | ||
362 | //create the movie from the handle that refers to the URI | |
d0ee33f5 WS |
363 | err = NewMovieFromDataRef(&m_movie, newMovieActive, |
364 | NULL, theHandle, | |
1a680109 RN |
365 | URLDataHandlerSubType); |
366 | ||
367 | DisposeHandle(theHandle); | |
368 | ||
369 | if (err != noErr) | |
370 | return false; | |
371 | ||
372 | //preroll movie for streaming | |
3b5023b9 | 373 | //TODO:Async this using threads? |
1a680109 RN |
374 | TimeValue timeNow; |
375 | Fixed playRate; | |
376 | timeNow = GetMovieTime(m_movie, NULL); | |
377 | playRate = GetMoviePreferredRate(m_movie); | |
378 | PrePrerollMovie(m_movie, timeNow, playRate, NULL, NULL); | |
379 | PrerollMovie(m_movie, timeNow, playRate); | |
380 | SetMovieRate(m_movie, playRate); | |
381 | ||
382 | FinishLoad(); | |
383 | ||
ff4aedc5 | 384 | return ::GetMoviesError() == noErr; |
1a680109 RN |
385 | } |
386 | ||
ff4aedc5 | 387 | //--------------------------------------------------------------------------- |
e7b97da3 | 388 | // wxQTMediaBackend::FinishLoad |
ff4aedc5 | 389 | // |
3b5023b9 RN |
390 | // 1) Create the movie timer |
391 | // 2) Get real size of movie for GetBestSize/sizers | |
392 | // 3) See if there is video in the movie, and if so then either | |
393 | // SetMovieGWorld if < 10.2 or use Native CreateMovieControl | |
394 | // 4) Set the movie time scale to something usable so that seeking | |
395 | // etc. will work correctly | |
396 | // 5) Refresh parent window | |
ff4aedc5 RN |
397 | //--------------------------------------------------------------------------- |
398 | void wxQTMediaBackend::FinishLoad() | |
1a680109 | 399 | { |
ff4aedc5 | 400 | m_timer = new _wxQTTimer(m_movie, (wxQTMediaBackend*) this); |
1a680109 RN |
401 | wxASSERT(m_timer); |
402 | ||
403 | //get the real size of the movie | |
404 | Rect outRect; | |
405 | ::GetMovieNaturalBoundsRect (m_movie, &outRect); | |
406 | wxASSERT(::GetMoviesError() == noErr); | |
407 | ||
408 | m_bestSize.x = outRect.right - outRect.left; | |
409 | m_bestSize.y = outRect.bottom - outRect.top; | |
3b5023b9 | 410 | |
ff4aedc5 | 411 | //reparent movie/*AudioMediaCharacteristic*/ |
d0ee33f5 WS |
412 | if(GetMovieIndTrackType(m_movie, 1, |
413 | VisualMediaCharacteristic, | |
414 | movieTrackCharacteristic | | |
ff4aedc5 | 415 | movieTrackEnabledOnly) != NULL) |
d0ee33f5 WS |
416 | { |
417 | #if wxUSE_CREATEMOVIECONTROL | |
3dee36ae WS |
418 | // |
419 | //Native CreateMovieControl QT control (Thanks to Kevin Olliver's | |
420 | //wxQTMovie for some of this). | |
421 | // | |
422 | #define GetControlPeer(whatever) ctrl->m_peer | |
423 | wxMediaCtrl* ctrl = (wxMediaCtrl*) m_ctrl; | |
424 | Rect bounds = wxMacGetBoundsForControl(m_ctrl, | |
425 | m_ctrl->GetPosition(), | |
426 | m_ctrl->GetSize()); | |
427 | ||
428 | //Dispose of old control for new one | |
429 | if (GetControlPeer(m_ctrl) && GetControlPeer(m_ctrl)->Ok() ) | |
430 | GetControlPeer(m_ctrl)->Dispose(); | |
431 | ||
432 | //Options- | |
433 | //kMovieControlOptionXXX | |
434 | //HideController - hide the movie controller | |
435 | //LocateTopLeft - movie is pinned to top left rather than centered in the control | |
436 | //EnableEditing - Allows programmatic editing and dragn'drop | |
437 | //HandleEditingHI- Installs event stuff for edit menu - forces EnableEditing also | |
438 | //SetKeysEnabled - Allows keyboard input | |
439 | //ManuallyIdled - app handles movie idling rather than internal timer event loop | |
d0ee33f5 | 440 | ::CreateMovieControl( |
3b5023b9 | 441 | (WindowRef) |
d0ee33f5 WS |
442 | ctrl->MacGetTopLevelWindowRef(), //parent |
443 | &bounds, //control bounds | |
444 | m_movie, //movie handle | |
445 | kMovieControlOptionHideController | |
446 | | kMovieControlOptionLocateTopLeft | |
447 | | kMovieControlOptionSetKeysEnabled | |
3b5023b9 | 448 | // | kMovieControlOptionManuallyIdled |
d0ee33f5 | 449 | , //flags |
ecd20d4a | 450 | ctrl->m_peer->GetControlRefAddr() ); |
d0ee33f5 | 451 | |
ecd20d4a | 452 | ::EmbedControl(ctrl->m_peer->GetControlRef(), (ControlRef)ctrl->GetParent()->GetHandle()); |
3b5023b9 | 453 | #else |
3dee36ae WS |
454 | // |
455 | //"Emulation" | |
456 | // | |
d0ee33f5 WS |
457 | SetMovieGWorld(m_movie, |
458 | (CGrafPtr) | |
ff4aedc5 RN |
459 | GetWindowPort( |
460 | (WindowRef) | |
461 | m_ctrl->MacGetTopLevelWindowRef() | |
d0ee33f5 | 462 | ), |
ff4aedc5 | 463 | nil); |
3b5023b9 | 464 | #endif |
1a680109 RN |
465 | } |
466 | ||
1a680109 RN |
467 | //we want millisecond precision |
468 | ::SetMovieTimeScale(m_movie, 1000); | |
ff4aedc5 RN |
469 | wxASSERT(::GetMoviesError() == noErr); |
470 | ||
471 | // | |
472 | //Here, if the parent of the control has a sizer - we | |
473 | //tell it to recalculate the size of this control since | |
3103e8a9 | 474 | //the user opened a separate media file |
ff4aedc5 RN |
475 | // |
476 | m_ctrl->InvalidateBestSize(); | |
477 | m_ctrl->GetParent()->Layout(); | |
478 | m_ctrl->GetParent()->Refresh(); | |
479 | m_ctrl->GetParent()->Update(); | |
1a680109 RN |
480 | } |
481 | ||
ff4aedc5 | 482 | //--------------------------------------------------------------------------- |
e7b97da3 | 483 | // wxQTMediaBackend::Play |
ff4aedc5 | 484 | // |
3b5023b9 RN |
485 | // 1) Start the QT movie |
486 | // 2) Start the movie loading timer | |
ff4aedc5 RN |
487 | //--------------------------------------------------------------------------- |
488 | bool wxQTMediaBackend::Play() | |
1a680109 | 489 | { |
1a680109 RN |
490 | ::StartMovie(m_movie); |
491 | m_timer->SetPaused(false); | |
492 | m_timer->Start(MOVIE_DELAY, wxTIMER_CONTINUOUS); | |
493 | return ::GetMoviesError() == noErr; | |
494 | } | |
495 | ||
ff4aedc5 | 496 | //--------------------------------------------------------------------------- |
e7b97da3 | 497 | // wxQTMediaBackend::Pause |
ff4aedc5 | 498 | // |
3b5023b9 RN |
499 | // 1) Stop the movie |
500 | // 2) Stop the movie timer | |
ff4aedc5 RN |
501 | //--------------------------------------------------------------------------- |
502 | bool wxQTMediaBackend::Pause() | |
1a680109 | 503 | { |
1a680109 RN |
504 | ::StopMovie(m_movie); |
505 | m_timer->SetPaused(true); | |
506 | m_timer->Stop(); | |
507 | return ::GetMoviesError() == noErr; | |
508 | } | |
509 | ||
ff4aedc5 | 510 | //--------------------------------------------------------------------------- |
e7b97da3 | 511 | // wxQTMediaBackend::Stop |
ff4aedc5 | 512 | // |
3b5023b9 RN |
513 | // 1) Stop the movie |
514 | // 2) Stop the movie timer | |
515 | // 3) Seek to the beginning of the movie | |
ff4aedc5 RN |
516 | //--------------------------------------------------------------------------- |
517 | bool wxQTMediaBackend::Stop() | |
1a680109 | 518 | { |
1a680109 RN |
519 | m_timer->SetPaused(false); |
520 | m_timer->Stop(); | |
521 | ||
522 | ::StopMovie(m_movie); | |
523 | if(::GetMoviesError() != noErr) | |
524 | return false; | |
d0ee33f5 | 525 | |
1a680109 RN |
526 | ::GoToBeginningOfMovie(m_movie); |
527 | return ::GetMoviesError() == noErr; | |
528 | } | |
529 | ||
ff4aedc5 | 530 | //--------------------------------------------------------------------------- |
e7b97da3 | 531 | // wxQTMediaBackend::GetPlaybackRate |
ff4aedc5 | 532 | // |
3b5023b9 | 533 | // 1) Get the movie playback rate from ::GetMovieRate |
ff4aedc5 RN |
534 | //--------------------------------------------------------------------------- |
535 | double wxQTMediaBackend::GetPlaybackRate() | |
1a680109 | 536 | { |
1a680109 RN |
537 | return ( ((double)::GetMovieRate(m_movie)) / 0x10000); |
538 | } | |
539 | ||
ff4aedc5 | 540 | //--------------------------------------------------------------------------- |
e7b97da3 | 541 | // wxQTMediaBackend::SetPlaybackRate |
ff4aedc5 | 542 | // |
3b5023b9 | 543 | // 1) Convert dRate to Fixed and Set the movie rate through SetMovieRate |
ff4aedc5 RN |
544 | //--------------------------------------------------------------------------- |
545 | bool wxQTMediaBackend::SetPlaybackRate(double dRate) | |
1a680109 | 546 | { |
1a680109 RN |
547 | ::SetMovieRate(m_movie, (Fixed) (dRate * 0x10000)); |
548 | return ::GetMoviesError() == noErr; | |
549 | } | |
550 | ||
ff4aedc5 | 551 | //--------------------------------------------------------------------------- |
e7b97da3 | 552 | // wxQTMediaBackend::SetPosition |
ff4aedc5 | 553 | // |
3b5023b9 RN |
554 | // 1) Create a time record struct (TimeRecord) with appropriate values |
555 | // 2) Pass struct to SetMovieTime | |
ff4aedc5 RN |
556 | //--------------------------------------------------------------------------- |
557 | bool wxQTMediaBackend::SetPosition(wxLongLong where) | |
1a680109 | 558 | { |
1a680109 RN |
559 | TimeRecord theTimeRecord; |
560 | memset(&theTimeRecord, 0, sizeof(TimeRecord)); | |
ff4aedc5 | 561 | theTimeRecord.value.lo = where.GetValue(); |
1a680109 RN |
562 | theTimeRecord.scale = ::GetMovieTimeScale(m_movie); |
563 | theTimeRecord.base = ::GetMovieTimeBase(m_movie); | |
564 | ::SetMovieTime(m_movie, &theTimeRecord); | |
565 | ||
566 | if (::GetMoviesError() != noErr) | |
567 | return false; | |
568 | ||
569 | return true; | |
570 | } | |
571 | ||
ff4aedc5 | 572 | //--------------------------------------------------------------------------- |
e7b97da3 | 573 | // wxQTMediaBackend::GetPosition |
ff4aedc5 | 574 | // |
3b5023b9 | 575 | // Calls GetMovieTime |
ff4aedc5 RN |
576 | //--------------------------------------------------------------------------- |
577 | wxLongLong wxQTMediaBackend::GetPosition() | |
1a680109 | 578 | { |
1a680109 RN |
579 | return ::GetMovieTime(m_movie, NULL); |
580 | } | |
581 | ||
ff4aedc5 | 582 | //--------------------------------------------------------------------------- |
e7b97da3 | 583 | // wxQTMediaBackend::GetDuration |
ff4aedc5 | 584 | // |
3b5023b9 | 585 | // Calls GetMovieDuration |
ff4aedc5 RN |
586 | //--------------------------------------------------------------------------- |
587 | wxLongLong wxQTMediaBackend::GetDuration() | |
1a680109 | 588 | { |
1a680109 RN |
589 | return ::GetMovieDuration(m_movie); |
590 | } | |
591 | ||
ff4aedc5 | 592 | //--------------------------------------------------------------------------- |
e7b97da3 | 593 | // wxQTMediaBackend::GetState |
ff4aedc5 | 594 | // |
3b5023b9 RN |
595 | // Determines the current state - the timer keeps track of whether or not |
596 | // we are paused or stopped (if the timer is running we are playing) | |
ff4aedc5 RN |
597 | //--------------------------------------------------------------------------- |
598 | wxMediaState wxQTMediaBackend::GetState() | |
1a680109 | 599 | { |
d0ee33f5 | 600 | if ( !m_timer || (m_timer->IsRunning() == false && |
ff4aedc5 | 601 | m_timer->GetPaused() == false) ) |
1a680109 RN |
602 | return wxMEDIASTATE_STOPPED; |
603 | ||
d0ee33f5 | 604 | if( m_timer->IsRunning() ) |
1a680109 RN |
605 | return wxMEDIASTATE_PLAYING; |
606 | else | |
607 | return wxMEDIASTATE_PAUSED; | |
608 | } | |
609 | ||
ff4aedc5 | 610 | //--------------------------------------------------------------------------- |
e7b97da3 | 611 | // wxQTMediaBackend::Cleanup |
ff4aedc5 | 612 | // |
3b5023b9 RN |
613 | // Diposes of the movie timer, Control if native, and stops and disposes |
614 | // of the QT movie | |
ff4aedc5 RN |
615 | //--------------------------------------------------------------------------- |
616 | void wxQTMediaBackend::Cleanup() | |
1a680109 RN |
617 | { |
618 | delete m_timer; | |
619 | m_timer = NULL; | |
d0ee33f5 WS |
620 | |
621 | #if wxUSE_CREATEMOVIECONTROL | |
ecd20d4a | 622 | DisposeControl(((wxMediaCtrl*)m_ctrl)->m_peer->GetControlRef()); |
3b5023b9 | 623 | #endif |
1a680109 RN |
624 | |
625 | StopMovie(m_movie); | |
626 | DisposeMovie(m_movie); | |
1a680109 RN |
627 | } |
628 | ||
ff4aedc5 | 629 | //--------------------------------------------------------------------------- |
e7b97da3 | 630 | // wxQTMediaBackend::GetVideoSize |
ff4aedc5 | 631 | // |
3b5023b9 | 632 | // Returns the actual size of the QT movie |
ff4aedc5 RN |
633 | //--------------------------------------------------------------------------- |
634 | wxSize wxQTMediaBackend::GetVideoSize() const | |
1a680109 RN |
635 | { |
636 | return m_bestSize; | |
637 | } | |
638 | ||
ff4aedc5 RN |
639 | //--------------------------------------------------------------------------- |
640 | // wxQTMediaBackend::Move | |
641 | // | |
d0ee33f5 | 642 | // We need to do this even when using native qt control because |
4b60077b | 643 | // CreateMovieControl is broken in this regard... |
ff4aedc5 RN |
644 | //--------------------------------------------------------------------------- |
645 | void wxQTMediaBackend::Move(int x, int y, int w, int h) | |
1a680109 | 646 | { |
d0ee33f5 | 647 | #if !wxUSE_CREATEMOVIECONTROL |
ff4aedc5 | 648 | if(m_timer) |
1a680109 | 649 | { |
e7b97da3 RD |
650 | if ( m_ctrl ) |
651 | { | |
652 | m_ctrl->GetParent()->MacWindowToRootWindow(&x, &y); | |
653 | } | |
d0ee33f5 | 654 | |
1a680109 | 655 | Rect theRect = {y, x, y+h, x+w}; |
ff4aedc5 | 656 | |
1a680109 RN |
657 | ::SetMovieBox(m_movie, &theRect); |
658 | wxASSERT(::GetMoviesError() == noErr); | |
659 | } | |
4b60077b RN |
660 | #else |
661 | if(m_timer && m_ctrl) | |
662 | { | |
663 | m_ctrl->GetParent()->MacWindowToRootWindow(&x, &y); | |
664 | ||
665 | ::MoveControl( (ControlRef) m_ctrl->GetHandle(), x, y ); | |
666 | m_ctrl->GetParent()->Refresh(); | |
667 | m_ctrl->GetParent()->Update(); | |
668 | } | |
3b5023b9 | 669 | #endif |
1a680109 RN |
670 | } |
671 | ||
ff4aedc5 RN |
672 | |
673 | //in source file that contains stuff you don't directly use | |
f572d649 | 674 | #include "wx/html/forcelnk.h" |
ff4aedc5 RN |
675 | FORCE_LINK_ME(basewxmediabackends); |
676 | ||
677 | #endif //wxUSE_MEDIACTRL |