1 /////////////////////////////////////////////////////////////////////////////
2 // Name: mac/carbon/moviectrl.cpp
3 // Purpose: wxMediaCtrl MAC CARBON QT
4 // Author: Ryan Norton <wxprojects@comcast.net>
8 // Copyright: (c) Ryan Norton
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 //#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13 //#pragma implementation "moviectrl.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
23 #include "wx/mac/carbon/mediactrl.h"
29 IMPLEMENT_CLASS(wxMediaCtrl
, wxControl
);
30 IMPLEMENT_DYNAMIC_CLASS(wxMediaEvent
, wxEvent
);
31 DEFINE_EVENT_TYPE(wxEVT_MEDIA_FINISHED
);
33 //uma is for wxMacFSSpec
35 #include "wx/mac/uma.h"
39 //quicktime media layer for mac emulation on pc
43 #include <QuickTimeComponents.h>
48 #define MSWMOVIECHECK if(!m_bLoaded) return 0;
51 //Time between timer calls
52 #define MOVIE_DELAY 50
54 // ------------------------------------------------------------------
55 // wxQTTimer - Handle Asyncronous Playing
56 // ------------------------------------------------------------------
57 class _wxQTTimer
: public wxTimer
60 _wxQTTimer(Movie movie
, wxMediaCtrl
* parent
) :
61 m_movie(movie
), m_bPaused(false), m_parent(parent
)
69 bool GetPaused() {return m_bPaused
;}
70 void SetPaused(bool bPaused
) {m_bPaused
= bPaused
;}
76 if(!IsMovieDone(m_movie
))
77 MoviesTask(m_movie
, MOVIE_DELAY
); //Give QT time to play movie
82 wxASSERT(::GetMoviesError() == noErr
);
83 wxMediaEvent
theEvent(wxEVT_MEDIA_FINISHED
, m_parent
->GetId());
84 m_parent
->GetParent()->ProcessEvent(theEvent
);
92 wxMediaCtrl
* m_parent
;
95 //Determines whether version 6 of QT is installed
96 Boolean
_wxIsQuickTime4Installed (void)
102 error
= Gestalt (gestaltQuickTime
, &result
);
103 return (error
== noErr
) && (((result
>> 16) & 0xffff) >= 0x0400);
109 bool wxMediaCtrl::InitQT ()
111 if (_wxIsQuickTime4Installed())
116 if ((nError
= InitializeQTML(0)) != noErr
)
118 wxFAIL_MSG(wxString::Format(wxT("Couldn't Initialize Quicktime-%i"), nError
));
126 wxFAIL_MSG(wxT("Quicktime is not installed, or Your Version of Quicktime is <= 4."));
131 bool wxMediaCtrl::Create(wxWindow
* parent
, wxWindowID id
, const wxString
& fileName
,
132 const wxPoint
& pos
, const wxSize
& size
,
133 long style
, long WXUNUSED(driver
), const wxString
& name
)
135 if(!DoCreate(parent
, id
, pos
, size
, style
, name
))
138 if(!fileName
.empty())
150 bool wxMediaCtrl::Create(wxWindow
* parent
, wxWindowID id
, const wxURI
& location
,
151 const wxPoint
& pos
, const wxSize
& size
,
152 long style
, long WXUNUSED(driver
), const wxString
& name
)
154 if(!DoCreate(parent
, id
, pos
, size
, style
, name
))
157 if(!location
.IsReference())
169 bool wxMediaCtrl::DoCreate(wxWindow
* parent
, wxWindowID id
,
170 const wxPoint
& pos
, const wxSize
& size
,
171 long style
, const wxString
& name
)
173 //do some window stuff
174 if ( !wxControl::Create(parent
, id
, pos
, size
,
176 MacRemoveBordersFromStyle(style
),
180 wxDefaultValidator
, name
) )
183 //Set our background color to black by default
184 SetBackgroundColour(*wxBLACK
);
189 bool wxMediaCtrl::Load(const wxString
& fileName
)
201 wxMacFilename2FSSpec( fileName
, &sfFile
) ;
203 if (NativePathNameToFSSpec ((char*) fileName
.mb_str(), &sfFile
, 0) != noErr
)
206 if (OpenMovieFile (&sfFile
, &movieResFile
, fsRdPerm
) != noErr
)
209 short movieResID
= 0;
212 err
= NewMovieFromFile (
220 CloseMovieFile (movieResFile
);
230 bool wxMediaCtrl::Load(const wxURI
& location
)
238 wxString theURI
= location
.BuildURI();
242 Handle theHandle
= NewHandleClear(theURI
.length() + 1);
245 BlockMove(theURI
.mb_str(), *theHandle
, theURI
.length() + 1);
247 //create the movie from the handle that refers to the URI
248 err
= NewMovieFromDataRef(&m_movie
, newMovieActive
,
250 URLDataHandlerSubType
);
252 DisposeHandle(theHandle
);
257 //preroll movie for streaming
261 timeNow
= GetMovieTime(m_movie
, NULL
);
262 playRate
= GetMoviePreferredRate(m_movie
);
263 PrePrerollMovie(m_movie
, timeNow
, playRate
, NULL
, NULL
);
264 PrerollMovie(m_movie
, timeNow
, playRate
);
265 SetMovieRate(m_movie
, playRate
);
272 void wxMediaCtrl::FinishLoad()
274 m_timer
= new _wxQTTimer(m_movie
, (wxMediaCtrl
*) this);
277 //get the real size of the movie
279 ::GetMovieNaturalBoundsRect (m_movie
, &outRect
);
280 wxASSERT(::GetMoviesError() == noErr
);
282 m_bestSize
.x
= outRect
.right
- outRect
.left
;
283 m_bestSize
.y
= outRect
.bottom
- outRect
.top
;
286 if(GetMovieIndTrackType(m_movie
, 1, VisualMediaCharacteristic
/*AudioMediaCharacteristic*/, movieTrackCharacteristic
| movieTrackEnabledOnly
) != NULL
)
290 CreatePortAssociation(this->GetHWND(), NULL
, 0L);
292 SetMovieGWorld(m_movie
, (CGrafPtr
)
295 GetNativeWindowPort(this->GetHWND())
297 GetWindowPort((WindowRef
)this->MacGetTopLevelWindowRef())
302 // wxPrintf(wxT("%u\n"), ::GetMovieTimeScale(m_movie));
303 //we want millisecond precision
304 ::SetMovieTimeScale(m_movie
, 1000);
306 m_bLoaded
= (::GetMoviesError() == noErr
);
308 //work around refresh issues
309 wxSize size
= GetParent()->GetSize();
310 GetParent()->SetSize(wxSize(size
.x
+1, size
.y
+1));
311 GetParent()->Refresh();
312 GetParent()->Update();
313 GetParent()->SetSize(size
);
314 GetParent()->Refresh();
315 GetParent()->Update();
318 bool wxMediaCtrl::Play()
321 ::StartMovie(m_movie
);
322 m_timer
->SetPaused(false);
323 m_timer
->Start(MOVIE_DELAY
, wxTIMER_CONTINUOUS
);
324 return ::GetMoviesError() == noErr
;
327 bool wxMediaCtrl::Pause()
330 ::StopMovie(m_movie
);
331 m_timer
->SetPaused(true);
333 return ::GetMoviesError() == noErr
;
336 bool wxMediaCtrl::Stop()
339 m_timer
->SetPaused(false);
342 ::StopMovie(m_movie
);
343 if(::GetMoviesError() != noErr
)
346 ::GoToBeginningOfMovie(m_movie
);
347 return ::GetMoviesError() == noErr
;
350 double wxMediaCtrl::GetPlaybackRate()
353 return ( ((double)::GetMovieRate(m_movie
)) / 0x10000);
356 bool wxMediaCtrl::SetPlaybackRate(double dRate
)
359 ::SetMovieRate(m_movie
, (Fixed
) (dRate
* 0x10000));
360 return ::GetMoviesError() == noErr
;
363 bool wxMediaCtrl::SetPosition(long where
)
366 TimeRecord theTimeRecord
;
367 memset(&theTimeRecord
, 0, sizeof(TimeRecord
));
368 theTimeRecord
.value
.lo
= where
;
369 theTimeRecord
.scale
= ::GetMovieTimeScale(m_movie
);
370 theTimeRecord
.base
= ::GetMovieTimeBase(m_movie
);
371 ::SetMovieTime(m_movie
, &theTimeRecord
);
373 if (::GetMoviesError() != noErr
)
379 long wxMediaCtrl::GetPosition()
382 return ::GetMovieTime(m_movie
, NULL
);
385 long wxMediaCtrl::GetDuration()
388 return ::GetMovieDuration(m_movie
);
391 wxMediaState
wxMediaCtrl::GetState()
393 if ( !m_bLoaded
|| (m_timer
->IsRunning() == false && m_timer
->GetPaused() == false) )
394 return wxMEDIASTATE_STOPPED
;
396 if( m_timer
->IsRunning() == true )
397 return wxMEDIASTATE_PLAYING
;
399 return wxMEDIASTATE_PAUSED
;
402 void wxMediaCtrl::Cleanup()
408 DisposeMovie(m_movie
);
410 //Note that ExitMovies() is not neccessary, but
411 //the docs are fuzzy on whether or not TerminateQTML is
419 wxMediaCtrl::~wxMediaCtrl()
425 wxSize
wxMediaCtrl::DoGetBestSize() const
430 void wxMediaCtrl::DoMoveWindow(int x
, int y
, int w
, int h
)
432 wxControl::DoMoveWindow(x
,y
,w
,h
);
437 Rect theRect
= {y
, x
, y
+h
, x
+w
};
439 Rect theRect
= {0, 0, h
, w
};
441 ::SetMovieBox(m_movie
, &theRect
);
442 wxASSERT(::GetMoviesError() == noErr
);
446 #endif //wxUSE_MOVIECTRL