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