chxavsitesupplier.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 524 行
CPP
524 行
/************************************************************************
* 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 sites\n", 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 sites\n", 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 = %d\n", aReason));
StartDSA();
}
void CHXAvSiteSupplier::AbortNow(RDirectScreenAccess::TTerminationReasons aReason)
{
DPRINTF(SYMP_INFO, ("CHXAvSiteSupplier::AbortNow(): reason = %d\n", aReason));
m_pDSA->Cancel();
m_bIsDSAStarted = false;
}
HX_RESULT CHXAvSiteSupplier::PositionChanged (HXxPoint* pPoint)
{
DPRINTF(SYMP_INFO, ("CHXAvSiteSupplier::PositionChanged() %d, %d\n", 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;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?