+//---------------------------------------------------------------------------
+// wxQTMediaBackend::GetDownloadTotal
+//---------------------------------------------------------------------------
+wxLongLong wxQTMediaBackend::GetDownloadTotal()
+{
+ return wxQTMediaBackend::GetDataSizeFromStart(
+ ::GetMovieDuration(m_movie)
+ );
+}
+
+//---------------------------------------------------------------------------
+// wxQTMediaBackend::MacVisibilityChanged
+//
+// The main problem here is that Windows quicktime, for example,
+// renders more directly to a HWND. Mac quicktime does not do this
+// and instead renders to the port of the WindowRef/WindowPtr on top
+// of everything else/all other windows.
+//
+// So, for example, if you were to have a CreateTabsControl/wxNotebook
+// and change pages, even if you called HIViewSetVisible/SetControlVisibility
+// directly the movie will still continue playing on top of everything else
+// if you went to a different tab.
+//
+// Note that another issue, and why we call MCSetControllerPort instead
+// of SetMovieGWorld directly, is that in addition to rendering on
+// top of everything else the last created controller steals mouse and
+// other input from everything else in the window, including other
+// controllers. Setting the port of it releases this behaviour.
+//---------------------------------------------------------------------------
+void wxQTMediaBackend::MacVisibilityChanged()
+{
+ if(!m_mc || !m_ctrl->m_bLoaded)
+ return; //not initialized yet
+
+ if(m_ctrl->MacIsReallyShown())
+ {
+ //The window is being shown again, so set the GWorld of the
+ //controller back to the port of the parent WindowRef
+ WindowRef wrTLW =
+ (WindowRef) m_ctrl->MacGetTopLevelWindowRef();
+
+ ::MCSetControllerPort(m_mc, (CGrafPtr) GetWindowPort(wrTLW));
+ wxASSERT(::GetMoviesError() == noErr);
+ }
+ else
+ {
+ //We are being hidden - set the GWorld of the controller
+ //to the offscreen GWorld
+ ::MCSetControllerPort(m_mc, m_movieWorld);
+ wxASSERT(::GetMoviesError() == noErr);
+ }
+}
+
+//---------------------------------------------------------------------------
+// wxQTMediaBackend::OnEraseBackground
+//
+// Suggestion from Greg Hazel to repaint the movie when idle
+// (on pause also)
+//---------------------------------------------------------------------------
+void wxQTMediaEvtHandler::OnEraseBackground(wxEraseEvent& evt)
+{
+ // Work around Nasty OSX drawing bug:
+ // http://lists.apple.com/archives/QuickTime-API/2002/Feb/msg00311.html
+ WindowRef wrTLW = (WindowRef) m_qtb->m_ctrl->MacGetTopLevelWindowRef();
+
+ RgnHandle region = ::MCGetControllerBoundsRgn(m_qtb->m_mc);
+ ::MCInvalidate(m_qtb->m_mc, wrTLW, region);
+ ::MCIdle(m_qtb->m_mc);
+}
+
+//---------------------------------------------------------------------------
+// wxQTMediaBackend::PPRMProc (static)
+//
+// Called when done PrePrerolling the movie.
+// Note that in 99% of the cases this does nothing...
+// Anyway we set up the loading timer here to tell us when the movie is done
+//---------------------------------------------------------------------------
+pascal void wxQTMediaBackend::PPRMProc(
+ Movie theMovie,
+ OSErr WXUNUSED_UNLESS_DEBUG(theErr),
+ void* theRefCon)
+{
+ wxASSERT( theMovie );
+ wxASSERT( theRefCon );
+ wxASSERT( theErr == noErr );
+
+ wxQTMediaBackend* pBE = (wxQTMediaBackend*) theRefCon;
+
+ long lTime = ::GetMovieTime(theMovie,NULL);
+ Fixed rate = ::GetMoviePreferredRate(theMovie);
+ ::PrerollMovie(theMovie,lTime,rate);
+ pBE->m_timer = new wxQTMediaLoadTimer(pBE);
+ pBE->m_timer->Start(MOVIE_DELAY);
+}
+
+//---------------------------------------------------------------------------
+// wxQTMediaBackend::MCFilterProc (static)
+//
+// Callback for when the movie controller recieves a message
+//---------------------------------------------------------------------------
+pascal Boolean wxQTMediaBackend::MCFilterProc(
+ MovieController WXUNUSED(theController),
+ short action,
+ void * WXUNUSED(params),
+ long refCon)
+{
+ wxQTMediaBackend* pThis = (wxQTMediaBackend*)refCon;
+
+ switch (action)
+ {
+ case 1:
+ // don't process idle events
+ break;
+
+ case 8:
+ // play button triggered - MC will set movie to opposite state
+ // of current - playing ? paused : playing
+ pThis->m_bPlaying = !(pThis->m_bPlaying);
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+//---------------------------------------------------------------------------
+// wxQTMediaBackend::WindowEventHandler [static]
+//
+// Event callback for the top level window of our control that passes
+// messages to our moviecontroller so it can receive mouse clicks etc.
+//---------------------------------------------------------------------------
+pascal OSStatus wxQTMediaBackend::WindowEventHandler(
+ EventHandlerCallRef inHandlerCallRef,
+ EventRef inEvent,
+ void *inUserData)
+{
+ wxQTMediaBackend* be = (wxQTMediaBackend*) inUserData;
+
+ // Only process keyboard messages on this window if it actually
+ // has focus, otherwise it will steal keystrokes from other windows!
+ // As well as when it is not loaded properly as it
+ // will crash in MCIsPlayerEvent
+ if((GetEventClass(inEvent) == kEventClassKeyboard &&
+ wxWindow::FindFocus() != be->m_ctrl)
+ || !be->m_ctrl->m_bLoaded)
+ return eventNotHandledErr;
+
+ // Pass the event onto the movie controller
+ EventRecord theEvent;
+ ConvertEventRefToEventRecord( inEvent, &theEvent );
+ OSStatus err;
+
+ // TODO: Apple says MCIsPlayerEvent is depreciated and
+ // MCClick, MCKey, MCIdle etc. should be used
+ // (RN: Of course that's what they say about
+ // CreateMovieControl and HIMovieView as well, LOL!)
+ err = ::MCIsPlayerEvent( be->m_mc, &theEvent );
+
+ // Pass on to other event handlers if not handled- i.e. wx
+ if (err != noErr)
+ return noErr;
+ else
+ return eventNotHandledErr;
+}