chxavsitesupplier.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:15k
- /************************************************************************
- * chxavsitesupplier.cpp
- * ---------------------
- *
- * Synopsis:
- * Contains the implementation of the CHXAvSiteSupplier class. This object
- * will provide the mechanism by which the core can blit to the screen.
- *
- * Target:
- * Symbian OS
- *
- *
- * (c) 1995-2003 RealNetworks, Inc. Patents pending. All rights reserved.
- *
- *****************************************************************************/
- // Standard includes...
- // Includes from Helix...
- #include "hxcom.h"
- #include "hxtypes.h"
- #include "hxwintyp.h"
- #include "hxwin.h"
- #include "hxtick.h"
- #include "ihxpckts.h"
- #include "hxcomm.h"
- #include "minisite.h"
- #include "minisymbiansite.h"
- // Includes from this project...
- #include "chxavplayerui.h"
- #include "chxavplayer.h"
- #include "chxavplayviewwindow.h"
- #include "hxsym_debug.h"
- #include "chxavsitesupplier.h"
- #define BORDER_WIDTH 1
- // IUnknown implementation body...
- BEGIN_INTERFACE_LIST(CHXAvSiteSupplier)
- INTERFACE_LIST_ENTRY(IID_IHXSiteSupplier, IHXSiteSupplier)
- END_INTERFACE_LIST
- /*
- * CHXAvSiteSupplier
- * -----------------
- * Ctor.
- *
- */
- CHXAvSiteSupplier::CHXAvSiteSupplier()
- :
- m_classFactory(NULL),
- m_pContext(NULL),
- m_sitesManager(NULL),
- m_pDSA(NULL),
- m_pRenderWindow(0),
- m_bIsDSAStarted(false)
- {
- }
- /*
- * ~CHXAvSiteSupplier
- * ------------------
- * Dtor.
- *
- */
- CHXAvSiteSupplier::~CHXAvSiteSupplier()
- {
- HX_DELETE(m_pDSA);
- HX_RELEASE(m_classFactory);
- HX_RELEASE(m_sitesManager);
- HX_RELEASE(m_pContext);
- HX_ASSERT(m_sitesCreated.IsEmpty());
- m_sitesCreated.RemoveAll();
- }
- /*
- * ConstructL
- * ----------
- *
- * constuct with IHXPlayer context
- *
- */
- void
- CHXAvSiteSupplier::ConstructL(IUnknown* pContext, CCoeControl* pRenderWindow)
- {
- HX_ASSERT(pContext);
- HX_ASSERT(pRenderWindow);
-
- m_pRenderWindow = pRenderWindow;
- m_pContext = pContext;
- if( m_pContext )
- {
- m_pContext->AddRef();
- m_pContext->QueryInterface(IID_IHXSiteManager,(void**)&m_sitesManager);
- m_pContext->QueryInterface(IID_IHXCommonClassFactory, (void**)&m_classFactory);
- HX_ASSERT(m_sitesManager);
- HX_ASSERT(m_classFactory);
- }
- }
- //
- // IHXSiteSupplier::SitesNeeded
- //
- // Called by player during setup of renderer sites during presentation
- // layout (just after play request issued).
- //
- STDMETHODIMP
- CHXAvSiteSupplier::SitesNeeded(UINT32 uRequestID, IHXValues *pProps)
- {
- DPRINTF(SYMP_INFO, ("CHXAvSiteSupplier::SitesNeeded()n"));
- HXxWindow* pWin = NULL;
- HRESULT hres = HXR_OK;
- IHXValues* pSiteProps = NULL;
- IHXSiteWindowed* pSiteWindowed = NULL;
- IHXBuffer* pValue = NULL;
- UINT32 style = 0;
- IHXSite* pSite = NULL;
- TInt osErr = KErrNone;
- IHXSite2* pSite2 = NULL;
-
- HX_ASSERT(m_pRenderWindow);
- CCoeEnv* pCoeEnv = m_pRenderWindow->ControlEnv();
- HX_ASSERT(pProps);
-
- //Only create one direct screen object and let all the sites share
- //it.
- if( NULL==m_pDSA )
- {
- TRAP(osErr, m_pDSA =
- CDirectScreenAccess::NewL( pCoeEnv->WsSession(),
- *pCoeEnv->ScreenDevice(),
- *(m_pRenderWindow->DrawableWindow()),
- *this
- ));
- StartDSA();
- }
-
- hres = HXR_FAIL;
- if(SUCCEEDED(m_classFactory->CreateInstance(CLSID_IHXSiteWindowed,
- (void**)&pSiteWindowed)))
- if(SUCCEEDED(pSiteWindowed->QueryInterface(IID_IHXSite,
- (void**)&pSite)))
- hres = pSiteWindowed->QueryInterface(IID_IHXValues,
- (void**)&pSiteProps);
- if (!pProps)
- hres = HXR_INVALID_PARAMETER;
-
- if (HXR_OK != hres)
- {
- goto exit;
- }
- //We need to figure out what type of site we are supposed to
- //create. We need to "switch" between site user and site
- //properties. So look for the well known site user properties that
- //are mapped onto sites...
- if( SUCCEEDED(pProps->GetPropertyCString("playto",pValue)))
- {
- pSiteProps->SetPropertyCString("channel",pValue);
- HX_RELEASE(pValue);
- }
- else
- {
- if(SUCCEEDED(pProps->GetPropertyCString("name",pValue)))
- {
- pSiteProps->SetPropertyCString("LayoutGroup",pValue);
- HX_RELEASE(pValue);
- }
- }
-
- /*
- * We need to wait until we have set all the properties before
- * we add the site.
- */
- HX_ASSERT(m_sitesManager);
- hres = m_sitesManager->AddSite(pSite);
- if (HXR_OK == hres)
- {
- //Add ourselves as a site watcher..
- pSite->QueryInterface(IID_IHXSite2, (void**)&pSite2 );
- if( pSite2 )
- {
- pSite2->AddPassiveSiteWatcher(this);
- HX_RELEASE(pSite2);
- }
-
- //We only attach a real window to the first site created.
- pWin = new HXxWindow();
- memset( pWin, 0, sizeof(HXxWindow));
-
- pWin->window = m_pRenderWindow->DrawableWindow();
- pWin->iDSA = m_pDSA;
-
- // Set the clip rect one pixel small all around...
- TRect rect = m_pRenderWindow->Rect();
- pWin->x = 0;
- pWin->y = 0;
- pWin->height = rect.Height();
- pWin->width = rect.Width();
-
- pWin->clipRect.left = pWin->clipRect.top = BORDER_WIDTH;
- pWin->clipRect.bottom = pWin->height - BORDER_WIDTH;
- pWin->clipRect.right = pWin->width - BORDER_WIDTH;
-
- pSiteWindowed->AttachWindow(pWin);
- pSite->AddRef();
- m_sitesCreated.SetAt(uRequestID, pSite);
- DPRINTF(SYMP_INFO, ("CHXAvSiteSupplier::SitesNeeded(): added site; now %ld sitesn", m_sitesCreated.GetCount()));
- }
-
- exit:
- if (HXR_OK != hres)
- {
- if( m_pDSA )
- m_pDSA->Cancel();
- HX_DELETE(m_pDSA);
- HX_DELETE(pWin);
- }
- HX_RELEASE(pSiteProps);
- HX_RELEASE(pSiteWindowed);
- HX_RELEASE(pSite);
- return hres;
- }
- //
- // IHXSiteSupplier::SitesNotNeeded
- //
- // Called when most recent presentation layout is being closed. This is not
- // called after IHXPlayer::Stop(). The layout remains persistent until:
- // a) a new play request is issued (even if for exact same url, i.e., replay)
- // b) the player object is closed
- //
- STDMETHODIMP CHXAvSiteSupplier::SitesNotNeeded(UINT32 uRequestID)
- {
- DPRINTF(SYMP_INFO, ("CHXAvSiteSupplier::SitesNotNeeded()n"));
- IHXSite* pSite = NULL;
- IHXSiteWindowed* pSiteWindowed = NULL;
- IHXSite2* pSite2 = NULL;
-
- void *pVoid = NULL;
- if (!m_sitesCreated.Lookup(uRequestID, pVoid))
- {
- return HXR_INVALID_PARAMETER;
- }
- pSite = (IHXSite*)pVoid;
- m_sitesManager->RemoveSite(pSite);
- //Remove ourselves as a passive site watcher..
- pSite->QueryInterface(IID_IHXSite2, (void**)&pSite2 );
- if( pSite2 )
- {
- pSite2->AddPassiveSiteWatcher( (IHXPassiveSiteWatcher*)this);
- HX_RELEASE(pSite2);
- }
-
- // Need to actually do the work on destroying the window
- // and all that jazz.
- pSite->QueryInterface(IID_IHXSiteWindowed,(void**)&pSiteWindowed);
- //Free the window we passed in.
- HXxWindow* pWin = pSiteWindowed->GetWindow();
- pSiteWindowed->Destroy();
- HX_DELETE(pWin);
- HX_RELEASE(pSiteWindowed);
- m_sitesCreated.Remove(uRequestID);
- HX_RELEASE(pSite);
- DPRINTF(SYMP_INFO, ("CHXAvSiteSupplier::SitesNotNeeded(): removed site; now %ld sitesn", m_sitesCreated.GetCount()));
- //If we have no more sites then destroy the direct screen access
- //object so it isn't associated with the playback window that is
- //not around anymore.
- if( m_sitesCreated.IsEmpty())
- {
- m_pDSA->Cancel();
- HX_DELETE(m_pDSA);
- }
-
- return HXR_OK;
- }
- //
- // IHXSiteSupplier::BeginChangeLayout
- //
- // Called:
- // a) during layout cleanup done when renderers are closed. SitesNotNeeded() is called after this.
- // b) during first presentation layout
- //
- STDMETHODIMP
- CHXAvSiteSupplier::BeginChangeLayout()
- {
- DPRINTF(SYMP_INFO, ("CHXAvSiteSupplier::BeginChangeLayout()n"));
- return HXR_OK;
- }
- //
- // IHXSiteSupplier::DoneChangeLayout
- //
- // Called after SitesNeeded(), after layout is complete.
- //
- STDMETHODIMP
- CHXAvSiteSupplier::DoneChangeLayout()
- {
- DPRINTF(SYMP_INFO, ("CHXAvSiteSupplier::DoneChangeLayout()n"));
- return HXR_OK;
- }
- bool CHXAvSiteSupplier::IsUsingSites() const
- {
- return !m_sitesCreated.IsEmpty();
- }
- TInt CHXAvSiteSupplier::StartDSA()
- {
- HX_ASSERT(m_pDSA);
- TRAPD(err, m_pDSA->StartL());
- //HX_ASSERT(KErrNone == err); // err expected when app looses foreground
- m_bIsDSAStarted = (err == KErrNone);
- return err;
- }
-
- //
- // AbortNow() and Restart() are (always?) called in pairs. These are called when
- // our render window is covered/uncovered, i.e., whenever we need to recalculate
- // our clipping rect. This includes following cases:
- // a) menu goes up
- // b) dialog goes up
- // c) CCoeControl associated with DSA is destroyed
- // d) user presses app switcher key (before fg event)
- //
- // StartL() will fail in cases (c) and (d)
- //
- void CHXAvSiteSupplier::Restart(RDirectScreenAccess::TTerminationReasons aReason)
- {
- DPRINTF(SYMP_INFO, ("CHXAvSiteSupplier::Restart(): reason = %dn", aReason));
- StartDSA();
- }
- void CHXAvSiteSupplier::AbortNow(RDirectScreenAccess::TTerminationReasons aReason)
- {
- DPRINTF(SYMP_INFO, ("CHXAvSiteSupplier::AbortNow(): reason = %dn", aReason));
- m_pDSA->Cancel();
- m_bIsDSAStarted = false;
- }
- HX_RESULT CHXAvSiteSupplier::PositionChanged (HXxPoint* pPoint)
- {
- DPRINTF(SYMP_INFO, ("CHXAvSiteSupplier::PositionChanged() %d, %dn", pPoint->x, pPoint->y));
- return HXR_OK;
- }
- namespace
- {
- HXxRect GetRect(IHXSite* pSite)
- {
- HX_ASSERT(pSite);
- HXxSize size;
- pSite->GetSize(size);
- HXxPoint tl;
- pSite->GetPosition(tl);
- HXxRect rect;
- rect.left = tl.x;
- rect.top = tl.y;
- rect.right = rect.left + size.cx;
- rect.bottom = rect.top + size.cy;
- return rect;
- }
- }
- void CHXAvSiteSupplier::RedrawAllSites()
- {
- DPRINTF(SYMP_INFO, ("CHXAvSiteSupplier::RedrawAllSites()n"));
-
- if( m_pDSA )
- {
- if( !m_bIsDSAStarted )
- {
- StartDSA();
- }
- if( m_bIsDSAStarted )
- {
- //Grab a sitemanager2 interface from our only player so we can
- //iterate over the sites.
- IHXClientEngine* pEngine = NULL;
- IUnknown* pUnknown = NULL;
- IHXSiteManager2* pSiteManager2 = NULL;
- IHXSite* pSite = NULL;
- ULONG32 nNumSites = 0;
-
- m_pContext->QueryInterface(IID_IHXClientEngine, (void**)&pEngine);
- HX_ASSERT(pEngine);
-
- if(pEngine)
- {
- //We should always have only 1 engine in the symbian players.
- int nPlayerCount = pEngine->GetPlayerCount();
- HX_ASSERT(nPlayerCount==1);
- if( nPlayerCount>0)
- {
- pEngine->GetPlayer(0, pUnknown);
- if(pUnknown)
- {
- pUnknown->QueryInterface(IID_IHXSiteManager2, (void**) &pSiteManager2);
- if (pSiteManager2)
- {
- pSiteManager2->GetNumberOfSites(nNumSites);
- for(unsigned int idx = 0; idx< nNumSites; idx++)
- {
- IHXSiteControl* pSiteController = NULL;
- pSiteManager2->GetSiteAt(idx, pSite);
- pSite->QueryInterface(IID_IHXSiteControl, (void**)&pSiteController);
- if( pSiteController )
- {
- //We want to do the recursive redraw.
- pSiteController->ForceRedrawAll();
- }
- else
- {
- //If we don't have tne new
- //interface, try doing it the old
- //non recursive way.
- pSite->DamageRect(GetRect(pSite));
- pSite->ForceRedraw();
- }
- HX_RELEASE(pSiteController);
- }
- HX_RELEASE(pSiteManager2);
- }
- HX_RELEASE(pUnknown);
- }
- }
- HX_RELEASE(pEngine);
- }
- }
- }
- }
- void CHXAvSiteSupplier::RestackSites()
- {
- HXxPoint point = {0,0};
- HXxSize size = {0,0};
- TInt nTotalHeight= 0;
- //Get our windows width and height
- TRect rect = m_pRenderWindow->Rect();
- //The site takes care of any scaling that needs to be done. The
- //site supplier will take care of centering the site(s). First go
- //through all the sites and get the total height.
- CHXMapLongToObj::Iterator end = m_sitesCreated.End();
- CHXMapLongToObj::Iterator it = m_sitesCreated.Begin();
- for( ; it != end; ++it)
- {
- // First one created gets put on top...
- IHXSite* pSite = (IHXSite*)*it;
- pSite->GetSize(size);
- nTotalHeight += size.cy;
- }
-
- //Now go through and restack and position sites.
- point.y = (rect.Height()-nTotalHeight)/2;
- if( point.y < 0 )
- point.y = 0;
-
- end = m_sitesCreated.End();
- for(it = m_sitesCreated.Begin(); it != end; ++it)
- {
- // First one created gets put on top...
- IHXSite* pSite = (IHXSite*)*it;
- pSite->GetSize(size);
- point.x = (rect.Width()-size.cx)/2;
- pSite->SetPosition(point);
- point.y += size.cy;
- }
- }
- HX_RESULT CHXAvSiteSupplier::SizeChanged( HXxSize* pSize)
- {
- DPRINTF(SYMP_INFO, ("CHXAvSiteSupplier::SizeChanged()n"));
- RestackSites();
- return HXR_OK;
- }