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"
27 #include "wx/mac/carbon/mediactrl.h"
31 IMPLEMENT_CLASS(wxMediaCtrl
, wxControl
);
32 IMPLEMENT_DYNAMIC_CLASS(wxMediaEvent
, wxEvent
);
33 DEFINE_EVENT_TYPE(wxEVT_MEDIA_FINISHED
);
35 //uma is for wxMacFSSpec
37 #include "wx/mac/uma.h"
41 //quicktime media layer for mac emulation on pc
45 #include <QuickTimeComponents.h>
50 #define MSWMOVIECHECK if(!m_bLoaded) return 0;
53 //Time between timer calls
54 #define MOVIE_DELAY 50
56 // ------------------------------------------------------------------
57 // wxQTTimer - Handle Asyncronous Playing
58 // ------------------------------------------------------------------
59 class _wxQTTimer
: public wxTimer
62 _wxQTTimer(Movie movie
, wxMediaCtrl
* parent
) :
63 m_movie(movie
), m_bPaused(false), m_parent(parent
)
71 bool GetPaused() {return m_bPaused
;}
72 void SetPaused(bool bPaused
) {m_bPaused
= bPaused
;}
78 if(!IsMovieDone(m_movie
))
79 MoviesTask(m_movie
, MOVIE_DELAY
); //Give QT time to play movie
84 wxASSERT(::GetMoviesError() == noErr
);
85 wxMediaEvent
theEvent(wxEVT_MEDIA_FINISHED
, m_parent
->GetId());
86 m_parent
->GetParent()->ProcessEvent(theEvent
);
94 wxMediaCtrl
* m_parent
;
97 //Determines whether version 6 of QT is installed
98 Boolean
_wxIsQuickTime4Installed (void)
104 error
= Gestalt (gestaltQuickTime
, &result
);
105 return (error
== noErr
) && (((result
>> 16) & 0xffff) >= 0x0400);
111 bool wxMediaCtrl::InitQT ()
113 if (_wxIsQuickTime4Installed())
118 if ((nError
= InitializeQTML(0)) != noErr
)
120 wxFAIL_MSG(wxString::Format(wxT("Couldn't Initialize Quicktime-%i"), nError
));
128 wxFAIL_MSG(wxT("Quicktime is not installed, or Your Version of Quicktime is <= 4."));
133 bool wxMediaCtrl::Create(wxWindow
* parent
, wxWindowID id
, const wxString
& fileName
,
134 const wxPoint
& pos
, const wxSize
& size
,
135 long style
, long WXUNUSED(driver
), const wxString
& name
)
137 if(!DoCreate(parent
, id
, pos
, size
, style
, name
))
140 if(!fileName
.empty())
152 bool wxMediaCtrl::Create(wxWindow
* parent
, wxWindowID id
, const wxURI
& location
,
153 const wxPoint
& pos
, const wxSize
& size
,
154 long style
, long WXUNUSED(driver
), const wxString
& name
)
156 if(!DoCreate(parent
, id
, pos
, size
, style
, name
))
159 if(!location
.IsReference())
171 bool wxMediaCtrl::DoCreate(wxWindow
* parent
, wxWindowID id
,
172 const wxPoint
& pos
, const wxSize
& size
,
173 long style
, const wxString
& name
)
175 //do some window stuff
176 if ( !wxControl::Create(parent
, id
, pos
, size
,
178 MacRemoveBordersFromStyle(style
),
182 wxDefaultValidator
, name
) )
185 //Set our background color to black by default
186 SetBackgroundColour(*wxBLACK
);
191 bool wxMediaCtrl::Load(const wxString
& fileName
)
203 wxMacFilename2FSSpec( fileName
, &sfFile
) ;
205 if (NativePathNameToFSSpec ((char*) fileName
.mb_str(), &sfFile
, 0) != noErr
)
208 if (OpenMovieFile (&sfFile
, &movieResFile
, fsRdPerm
) != noErr
)
211 short movieResID
= 0;
214 err
= NewMovieFromFile (
222 CloseMovieFile (movieResFile
);
232 bool wxMediaCtrl::Load(const wxURI
& location
)
240 wxString theURI
= location
.BuildURI();
244 Handle theHandle
= NewHandleClear(theURI
.length() + 1);
247 BlockMove(theURI
.mb_str(), *theHandle
, theURI
.length() + 1);
249 //create the movie from the handle that refers to the URI
250 err
= NewMovieFromDataRef(&m_movie
, newMovieActive
,
252 URLDataHandlerSubType
);
254 DisposeHandle(theHandle
);
259 //preroll movie for streaming
263 timeNow
= GetMovieTime(m_movie
, NULL
);
264 playRate
= GetMoviePreferredRate(m_movie
);
265 PrePrerollMovie(m_movie
, timeNow
, playRate
, NULL
, NULL
);
266 PrerollMovie(m_movie
, timeNow
, playRate
);
267 SetMovieRate(m_movie
, playRate
);
274 void wxMediaCtrl::FinishLoad()
276 m_timer
= new _wxQTTimer(m_movie
, (wxMediaCtrl
*) this);
279 //get the real size of the movie
281 ::GetMovieNaturalBoundsRect (m_movie
, &outRect
);
282 wxASSERT(::GetMoviesError() == noErr
);
284 m_bestSize
.x
= outRect
.right
- outRect
.left
;
285 m_bestSize
.y
= outRect
.bottom
- outRect
.top
;
288 if(GetMovieIndTrackType(m_movie
, 1, VisualMediaCharacteristic
/*AudioMediaCharacteristic*/, movieTrackCharacteristic
| movieTrackEnabledOnly
) != NULL
)
292 CreatePortAssociation(this->GetHWND(), NULL
, 0L);
294 SetMovieGWorld(m_movie
, (CGrafPtr
)
297 GetNativeWindowPort(this->GetHWND())
299 GetWindowPort((WindowRef
)this->MacGetTopLevelWindowRef())
304 // wxPrintf(wxT("%u\n"), ::GetMovieTimeScale(m_movie));
305 //we want millisecond precision
306 ::SetMovieTimeScale(m_movie
, 1000);
308 m_bLoaded
= (::GetMoviesError() == noErr
);
310 //work around refresh issues
311 wxSize size
= GetParent()->GetSize();
312 GetParent()->SetSize(wxSize(size
.x
+1, size
.y
+1));
313 GetParent()->Refresh();
314 GetParent()->Update();
315 GetParent()->SetSize(size
);
316 GetParent()->Refresh();
317 GetParent()->Update();
320 bool wxMediaCtrl::Play()
323 ::StartMovie(m_movie
);
324 m_timer
->SetPaused(false);
325 m_timer
->Start(MOVIE_DELAY
, wxTIMER_CONTINUOUS
);
326 return ::GetMoviesError() == noErr
;
329 bool wxMediaCtrl::Pause()
332 ::StopMovie(m_movie
);
333 m_timer
->SetPaused(true);
335 return ::GetMoviesError() == noErr
;
338 bool wxMediaCtrl::Stop()
341 m_timer
->SetPaused(false);
344 ::StopMovie(m_movie
);
345 if(::GetMoviesError() != noErr
)
348 ::GoToBeginningOfMovie(m_movie
);
349 return ::GetMoviesError() == noErr
;
352 double wxMediaCtrl::GetPlaybackRate()
355 return ( ((double)::GetMovieRate(m_movie
)) / 0x10000);
358 bool wxMediaCtrl::SetPlaybackRate(double dRate
)
361 ::SetMovieRate(m_movie
, (Fixed
) (dRate
* 0x10000));
362 return ::GetMoviesError() == noErr
;
365 bool wxMediaCtrl::SetPosition(long where
)
368 TimeRecord theTimeRecord
;
369 memset(&theTimeRecord
, 0, sizeof(TimeRecord
));
370 theTimeRecord
.value
.lo
= where
;
371 theTimeRecord
.scale
= ::GetMovieTimeScale(m_movie
);
372 theTimeRecord
.base
= ::GetMovieTimeBase(m_movie
);
373 ::SetMovieTime(m_movie
, &theTimeRecord
);
375 if (::GetMoviesError() != noErr
)
381 long wxMediaCtrl::GetPosition()
384 return ::GetMovieTime(m_movie
, NULL
);
387 long wxMediaCtrl::GetDuration()
390 return ::GetMovieDuration(m_movie
);
393 wxMediaState
wxMediaCtrl::GetState()
395 if ( !m_bLoaded
|| (m_timer
->IsRunning() == false && m_timer
->GetPaused() == false) )
396 return wxMEDIASTATE_STOPPED
;
398 if( m_timer
->IsRunning() == true )
399 return wxMEDIASTATE_PLAYING
;
401 return wxMEDIASTATE_PAUSED
;
404 void wxMediaCtrl::Cleanup()
410 DisposeMovie(m_movie
);
412 //Note that ExitMovies() is not neccessary, but
413 //the docs are fuzzy on whether or not TerminateQTML is
421 wxMediaCtrl::~wxMediaCtrl()
427 wxSize
wxMediaCtrl::DoGetBestSize() const
432 void wxMediaCtrl::DoMoveWindow(int x
, int y
, int w
, int h
)
434 wxControl::DoMoveWindow(x
,y
,w
,h
);
439 Rect theRect
= {y
, x
, y
+h
, x
+w
};
441 Rect theRect
= {0, 0, h
, w
};
443 ::SetMovieBox(m_movie
, &theRect
);
444 wxASSERT(::GetMoviesError() == noErr
);
448 #endif //wxUSE_MOVIECTRL