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