]>
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 | 300 | |
099c3b27 RN |
301 | //FIXME:wxMacFilename2FSSpec crashes on empty string - |
302 | //does it crash on other strings too and should this | |
303 | //"fix" be put in the carbon wxSound? | |
304 | if (fileName.empty()) | |
305 | return false; | |
306 | ||
ff4aedc5 RN |
307 | wxMacFilename2FSSpec( fileName , &sfFile ); |
308 | ||
1a680109 RN |
309 | if (OpenMovieFile (&sfFile, &movieResFile, fsRdPerm) != noErr) |
310 | return false; | |
311 | ||
312 | short movieResID = 0; | |
313 | Str255 movieName; | |
314 | ||
315 | err = NewMovieFromFile ( | |
316 | &m_movie, | |
317 | movieResFile, | |
318 | &movieResID, | |
319 | movieName, | |
320 | newMovieActive, | |
321 | NULL); //wasChanged | |
322 | ||
323 | CloseMovieFile (movieResFile); | |
324 | ||
325 | if (err != noErr) | |
326 | return false; | |
327 | ||
328 | FinishLoad(); | |
329 | ||
ff4aedc5 | 330 | return ::GetMoviesError() == noErr; |
1a680109 RN |
331 | } |
332 | ||
ff4aedc5 | 333 | //--------------------------------------------------------------------------- |
3b5023b9 | 334 | // wxQTMediaBackend::Load (URL Version) |
ff4aedc5 | 335 | // |
3b5023b9 RN |
336 | // 1) Build an escaped URI from location |
337 | // 2) Create a handle to store the URI string | |
338 | // 3) Put the URI string inside the handle | |
339 | // 4) Make a QuickTime URL data ref from the handle with the URI in it | |
340 | // 5) Clean up the URI string handle | |
341 | // 6) Do some prerolling | |
342 | // 7) Finish Loading | |
ff4aedc5 RN |
343 | //--------------------------------------------------------------------------- |
344 | bool wxQTMediaBackend::Load(const wxURI& location) | |
1a680109 | 345 | { |
ff4aedc5 | 346 | if(m_timer) |
1a680109 RN |
347 | Cleanup(); |
348 | ||
1a680109 RN |
349 | wxString theURI = location.BuildURI(); |
350 | ||
351 | OSErr err = noErr; | |
352 | ||
353 | Handle theHandle = NewHandleClear(theURI.length() + 1); | |
354 | wxASSERT(theHandle); | |
355 | ||
356 | BlockMove(theURI.mb_str(), *theHandle, theURI.length() + 1); | |
357 | ||
358 | //create the movie from the handle that refers to the URI | |
359 | err = NewMovieFromDataRef(&m_movie, newMovieActive, | |
360 | NULL, theHandle, | |
361 | URLDataHandlerSubType); | |
362 | ||
363 | DisposeHandle(theHandle); | |
364 | ||
365 | if (err != noErr) | |
366 | return false; | |
367 | ||
368 | //preroll movie for streaming | |
3b5023b9 | 369 | //TODO:Async this using threads? |
1a680109 RN |
370 | TimeValue timeNow; |
371 | Fixed playRate; | |
372 | timeNow = GetMovieTime(m_movie, NULL); | |
373 | playRate = GetMoviePreferredRate(m_movie); | |
374 | PrePrerollMovie(m_movie, timeNow, playRate, NULL, NULL); | |
375 | PrerollMovie(m_movie, timeNow, playRate); | |
376 | SetMovieRate(m_movie, playRate); | |
377 | ||
378 | FinishLoad(); | |
379 | ||
ff4aedc5 | 380 | return ::GetMoviesError() == noErr; |
1a680109 RN |
381 | } |
382 | ||
ff4aedc5 | 383 | //--------------------------------------------------------------------------- |
e7b97da3 | 384 | // wxQTMediaBackend::FinishLoad |
ff4aedc5 | 385 | // |
3b5023b9 RN |
386 | // 1) Create the movie timer |
387 | // 2) Get real size of movie for GetBestSize/sizers | |
388 | // 3) See if there is video in the movie, and if so then either | |
389 | // SetMovieGWorld if < 10.2 or use Native CreateMovieControl | |
390 | // 4) Set the movie time scale to something usable so that seeking | |
391 | // etc. will work correctly | |
392 | // 5) Refresh parent window | |
ff4aedc5 RN |
393 | //--------------------------------------------------------------------------- |
394 | void wxQTMediaBackend::FinishLoad() | |
1a680109 | 395 | { |
ff4aedc5 | 396 | m_timer = new _wxQTTimer(m_movie, (wxQTMediaBackend*) this); |
1a680109 RN |
397 | wxASSERT(m_timer); |
398 | ||
399 | //get the real size of the movie | |
400 | Rect outRect; | |
401 | ::GetMovieNaturalBoundsRect (m_movie, &outRect); | |
402 | wxASSERT(::GetMoviesError() == noErr); | |
403 | ||
404 | m_bestSize.x = outRect.right - outRect.left; | |
405 | m_bestSize.y = outRect.bottom - outRect.top; | |
3b5023b9 | 406 | |
ff4aedc5 RN |
407 | //reparent movie/*AudioMediaCharacteristic*/ |
408 | if(GetMovieIndTrackType(m_movie, 1, | |
409 | VisualMediaCharacteristic, | |
410 | movieTrackCharacteristic | | |
411 | movieTrackEnabledOnly) != NULL) | |
412 | { | |
3b5023b9 RN |
413 | #if wxUSE_CREATEMOVIECONTROL |
414 | // | |
415 | //Native CreateMovieControl QT control (Thanks to Kevin Olliver's | |
416 | //wxQTMovie for some of this). | |
417 | // | |
ecd20d4a RN |
418 | #define GetControlPeer(whatever) ctrl->m_peer |
419 | wxMediaCtrl* ctrl = (wxMediaCtrl*) m_ctrl; | |
3b5023b9 RN |
420 | Rect bounds = wxMacGetBoundsForControl(m_ctrl, |
421 | m_ctrl->GetPosition(), | |
422 | m_ctrl->GetSize()); | |
7115e540 RN |
423 | |
424 | //Dispose of old control for new one | |
425 | if (GetControlPeer(m_ctrl) && GetControlPeer(m_ctrl)->Ok() ) | |
426 | GetControlPeer(m_ctrl)->Dispose(); | |
427 | ||
3b5023b9 RN |
428 | //Options- |
429 | //kMovieControlOptionXXX | |
430 | //HideController - hide the movie controller | |
431 | //LocateTopLeft - movie is pinned to top left rather than centered in the control | |
432 | //EnableEditing - Allows programmatic editing and dragn'drop | |
433 | //HandleEditingHI- Installs event stuff for edit menu - forces EnableEditing also | |
434 | //SetKeysEnabled - Allows keyboard input | |
435 | //ManuallyIdled - app handles movie idling rather than internal timer event loop | |
436 | ::CreateMovieControl( | |
437 | (WindowRef) | |
ecd20d4a | 438 | ctrl->MacGetTopLevelWindowRef(), //parent |
3b5023b9 RN |
439 | &bounds, //control bounds |
440 | m_movie, //movie handle | |
441 | kMovieControlOptionHideController | |
442 | | kMovieControlOptionLocateTopLeft | |
443 | | kMovieControlOptionSetKeysEnabled | |
444 | // | kMovieControlOptionManuallyIdled | |
445 | , //flags | |
ecd20d4a | 446 | ctrl->m_peer->GetControlRefAddr() ); |
3b5023b9 | 447 | |
ecd20d4a | 448 | ::EmbedControl(ctrl->m_peer->GetControlRef(), (ControlRef)ctrl->GetParent()->GetHandle()); |
3b5023b9 RN |
449 | #else |
450 | // | |
451 | //"Emulation" | |
452 | // | |
ff4aedc5 RN |
453 | SetMovieGWorld(m_movie, |
454 | (CGrafPtr) | |
455 | GetWindowPort( | |
456 | (WindowRef) | |
457 | m_ctrl->MacGetTopLevelWindowRef() | |
458 | ), | |
459 | nil); | |
3b5023b9 | 460 | #endif |
1a680109 RN |
461 | } |
462 | ||
1a680109 RN |
463 | //we want millisecond precision |
464 | ::SetMovieTimeScale(m_movie, 1000); | |
ff4aedc5 RN |
465 | wxASSERT(::GetMoviesError() == noErr); |
466 | ||
467 | // | |
468 | //Here, if the parent of the control has a sizer - we | |
469 | //tell it to recalculate the size of this control since | |
470 | //the user opened a seperate media file | |
471 | // | |
472 | m_ctrl->InvalidateBestSize(); | |
473 | m_ctrl->GetParent()->Layout(); | |
474 | m_ctrl->GetParent()->Refresh(); | |
475 | m_ctrl->GetParent()->Update(); | |
1a680109 RN |
476 | } |
477 | ||
ff4aedc5 | 478 | //--------------------------------------------------------------------------- |
e7b97da3 | 479 | // wxQTMediaBackend::Play |
ff4aedc5 | 480 | // |
3b5023b9 RN |
481 | // 1) Start the QT movie |
482 | // 2) Start the movie loading timer | |
ff4aedc5 RN |
483 | //--------------------------------------------------------------------------- |
484 | bool wxQTMediaBackend::Play() | |
1a680109 | 485 | { |
1a680109 RN |
486 | ::StartMovie(m_movie); |
487 | m_timer->SetPaused(false); | |
488 | m_timer->Start(MOVIE_DELAY, wxTIMER_CONTINUOUS); | |
489 | return ::GetMoviesError() == noErr; | |
490 | } | |
491 | ||
ff4aedc5 | 492 | //--------------------------------------------------------------------------- |
e7b97da3 | 493 | // wxQTMediaBackend::Pause |
ff4aedc5 | 494 | // |
3b5023b9 RN |
495 | // 1) Stop the movie |
496 | // 2) Stop the movie timer | |
ff4aedc5 RN |
497 | //--------------------------------------------------------------------------- |
498 | bool wxQTMediaBackend::Pause() | |
1a680109 | 499 | { |
1a680109 RN |
500 | ::StopMovie(m_movie); |
501 | m_timer->SetPaused(true); | |
502 | m_timer->Stop(); | |
503 | return ::GetMoviesError() == noErr; | |
504 | } | |
505 | ||
ff4aedc5 | 506 | //--------------------------------------------------------------------------- |
e7b97da3 | 507 | // wxQTMediaBackend::Stop |
ff4aedc5 | 508 | // |
3b5023b9 RN |
509 | // 1) Stop the movie |
510 | // 2) Stop the movie timer | |
511 | // 3) Seek to the beginning of the movie | |
ff4aedc5 RN |
512 | //--------------------------------------------------------------------------- |
513 | bool wxQTMediaBackend::Stop() | |
1a680109 | 514 | { |
1a680109 RN |
515 | m_timer->SetPaused(false); |
516 | m_timer->Stop(); | |
517 | ||
518 | ::StopMovie(m_movie); | |
519 | if(::GetMoviesError() != noErr) | |
520 | return false; | |
521 | ||
522 | ::GoToBeginningOfMovie(m_movie); | |
523 | return ::GetMoviesError() == noErr; | |
524 | } | |
525 | ||
ff4aedc5 | 526 | //--------------------------------------------------------------------------- |
e7b97da3 | 527 | // wxQTMediaBackend::GetPlaybackRate |
ff4aedc5 | 528 | // |
3b5023b9 | 529 | // 1) Get the movie playback rate from ::GetMovieRate |
ff4aedc5 RN |
530 | //--------------------------------------------------------------------------- |
531 | double wxQTMediaBackend::GetPlaybackRate() | |
1a680109 | 532 | { |
1a680109 RN |
533 | return ( ((double)::GetMovieRate(m_movie)) / 0x10000); |
534 | } | |
535 | ||
ff4aedc5 | 536 | //--------------------------------------------------------------------------- |
e7b97da3 | 537 | // wxQTMediaBackend::SetPlaybackRate |
ff4aedc5 | 538 | // |
3b5023b9 | 539 | // 1) Convert dRate to Fixed and Set the movie rate through SetMovieRate |
ff4aedc5 RN |
540 | //--------------------------------------------------------------------------- |
541 | bool wxQTMediaBackend::SetPlaybackRate(double dRate) | |
1a680109 | 542 | { |
1a680109 RN |
543 | ::SetMovieRate(m_movie, (Fixed) (dRate * 0x10000)); |
544 | return ::GetMoviesError() == noErr; | |
545 | } | |
546 | ||
ff4aedc5 | 547 | //--------------------------------------------------------------------------- |
e7b97da3 | 548 | // wxQTMediaBackend::SetPosition |
ff4aedc5 | 549 | // |
3b5023b9 RN |
550 | // 1) Create a time record struct (TimeRecord) with appropriate values |
551 | // 2) Pass struct to SetMovieTime | |
ff4aedc5 RN |
552 | //--------------------------------------------------------------------------- |
553 | bool wxQTMediaBackend::SetPosition(wxLongLong where) | |
1a680109 | 554 | { |
1a680109 RN |
555 | TimeRecord theTimeRecord; |
556 | memset(&theTimeRecord, 0, sizeof(TimeRecord)); | |
ff4aedc5 | 557 | theTimeRecord.value.lo = where.GetValue(); |
1a680109 RN |
558 | theTimeRecord.scale = ::GetMovieTimeScale(m_movie); |
559 | theTimeRecord.base = ::GetMovieTimeBase(m_movie); | |
560 | ::SetMovieTime(m_movie, &theTimeRecord); | |
561 | ||
562 | if (::GetMoviesError() != noErr) | |
563 | return false; | |
564 | ||
565 | return true; | |
566 | } | |
567 | ||
ff4aedc5 | 568 | //--------------------------------------------------------------------------- |
e7b97da3 | 569 | // wxQTMediaBackend::GetPosition |
ff4aedc5 | 570 | // |
3b5023b9 | 571 | // Calls GetMovieTime |
ff4aedc5 RN |
572 | //--------------------------------------------------------------------------- |
573 | wxLongLong wxQTMediaBackend::GetPosition() | |
1a680109 | 574 | { |
1a680109 RN |
575 | return ::GetMovieTime(m_movie, NULL); |
576 | } | |
577 | ||
ff4aedc5 | 578 | //--------------------------------------------------------------------------- |
e7b97da3 | 579 | // wxQTMediaBackend::GetDuration |
ff4aedc5 | 580 | // |
3b5023b9 | 581 | // Calls GetMovieDuration |
ff4aedc5 RN |
582 | //--------------------------------------------------------------------------- |
583 | wxLongLong wxQTMediaBackend::GetDuration() | |
1a680109 | 584 | { |
1a680109 RN |
585 | return ::GetMovieDuration(m_movie); |
586 | } | |
587 | ||
ff4aedc5 | 588 | //--------------------------------------------------------------------------- |
e7b97da3 | 589 | // wxQTMediaBackend::GetState |
ff4aedc5 | 590 | // |
3b5023b9 RN |
591 | // Determines the current state - the timer keeps track of whether or not |
592 | // we are paused or stopped (if the timer is running we are playing) | |
ff4aedc5 RN |
593 | //--------------------------------------------------------------------------- |
594 | wxMediaState wxQTMediaBackend::GetState() | |
1a680109 | 595 | { |
ff4aedc5 RN |
596 | if ( !m_timer || (m_timer->IsRunning() == false && |
597 | m_timer->GetPaused() == false) ) | |
1a680109 RN |
598 | return wxMEDIASTATE_STOPPED; |
599 | ||
600 | if( m_timer->IsRunning() == true ) | |
601 | return wxMEDIASTATE_PLAYING; | |
602 | else | |
603 | return wxMEDIASTATE_PAUSED; | |
604 | } | |
605 | ||
ff4aedc5 | 606 | //--------------------------------------------------------------------------- |
e7b97da3 | 607 | // wxQTMediaBackend::Cleanup |
ff4aedc5 | 608 | // |
3b5023b9 RN |
609 | // Diposes of the movie timer, Control if native, and stops and disposes |
610 | // of the QT movie | |
ff4aedc5 RN |
611 | //--------------------------------------------------------------------------- |
612 | void wxQTMediaBackend::Cleanup() | |
1a680109 RN |
613 | { |
614 | delete m_timer; | |
615 | m_timer = NULL; | |
3b5023b9 RN |
616 | |
617 | #if wxUSE_CREATEMOVIECONTROL | |
ecd20d4a | 618 | DisposeControl(((wxMediaCtrl*)m_ctrl)->m_peer->GetControlRef()); |
3b5023b9 | 619 | #endif |
1a680109 RN |
620 | |
621 | StopMovie(m_movie); | |
622 | DisposeMovie(m_movie); | |
1a680109 RN |
623 | } |
624 | ||
ff4aedc5 | 625 | //--------------------------------------------------------------------------- |
e7b97da3 | 626 | // wxQTMediaBackend::GetVideoSize |
ff4aedc5 | 627 | // |
3b5023b9 | 628 | // Returns the actual size of the QT movie |
ff4aedc5 RN |
629 | //--------------------------------------------------------------------------- |
630 | wxSize wxQTMediaBackend::GetVideoSize() const | |
1a680109 RN |
631 | { |
632 | return m_bestSize; | |
633 | } | |
634 | ||
ff4aedc5 RN |
635 | //--------------------------------------------------------------------------- |
636 | // wxQTMediaBackend::Move | |
637 | // | |
4b60077b RN |
638 | // We need to do this even when using native qt control because |
639 | // CreateMovieControl is broken in this regard... | |
ff4aedc5 RN |
640 | //--------------------------------------------------------------------------- |
641 | void wxQTMediaBackend::Move(int x, int y, int w, int h) | |
1a680109 | 642 | { |
3b5023b9 | 643 | #if !wxUSE_CREATEMOVIECONTROL |
ff4aedc5 | 644 | if(m_timer) |
1a680109 | 645 | { |
e7b97da3 RD |
646 | if ( m_ctrl ) |
647 | { | |
648 | m_ctrl->GetParent()->MacWindowToRootWindow(&x, &y); | |
649 | } | |
650 | ||
1a680109 | 651 | Rect theRect = {y, x, y+h, x+w}; |
ff4aedc5 | 652 | |
1a680109 RN |
653 | ::SetMovieBox(m_movie, &theRect); |
654 | wxASSERT(::GetMoviesError() == noErr); | |
655 | } | |
4b60077b RN |
656 | #else |
657 | if(m_timer && m_ctrl) | |
658 | { | |
659 | m_ctrl->GetParent()->MacWindowToRootWindow(&x, &y); | |
660 | ||
661 | ::MoveControl( (ControlRef) m_ctrl->GetHandle(), x, y ); | |
662 | m_ctrl->GetParent()->Refresh(); | |
663 | m_ctrl->GetParent()->Update(); | |
664 | } | |
3b5023b9 | 665 | #endif |
1a680109 RN |
666 | } |
667 | ||
ff4aedc5 RN |
668 | |
669 | //in source file that contains stuff you don't directly use | |
f572d649 | 670 | #include "wx/html/forcelnk.h" |
ff4aedc5 RN |
671 | FORCE_LINK_ME(basewxmediabackends); |
672 | ||
673 | #endif //wxUSE_MEDIACTRL | |
674 | ||
675 | ||
676 | ||
677 | ||
678 |