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