chxavsitesupplier.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:15k
源码类别:

Symbian

开发平台:

C/C++

  1. /************************************************************************
  2.  * chxavsitesupplier.cpp
  3.  * ---------------------
  4.  *
  5.  * Synopsis:
  6.  * Contains the implementation of the CHXAvSiteSupplier class.  This object 
  7.  * will provide the mechanism by which the core can blit to the screen.
  8.  *
  9.  * Target:
  10.  * Symbian OS
  11.  *
  12.  *
  13.  * (c) 1995-2003 RealNetworks, Inc. Patents pending. All rights reserved.
  14.  *
  15.  *****************************************************************************/
  16. // Standard includes...
  17. // Includes from Helix...
  18. #include "hxcom.h"
  19. #include "hxtypes.h"
  20. #include "hxwintyp.h"
  21. #include "hxwin.h"
  22. #include "hxtick.h"
  23. #include "ihxpckts.h"
  24. #include "hxcomm.h"
  25. #include "minisite.h"
  26. #include "minisymbiansite.h"
  27. // Includes from this project...
  28. #include "chxavplayerui.h"
  29. #include "chxavplayer.h"
  30. #include "chxavplayviewwindow.h"
  31. #include "hxsym_debug.h"
  32. #include "chxavsitesupplier.h"
  33. #define BORDER_WIDTH 1
  34. // IUnknown implementation body...
  35. BEGIN_INTERFACE_LIST(CHXAvSiteSupplier)
  36.     INTERFACE_LIST_ENTRY(IID_IHXSiteSupplier, IHXSiteSupplier)
  37.     END_INTERFACE_LIST
  38. /* 
  39.  * CHXAvSiteSupplier
  40.  * -----------------
  41.  * Ctor.
  42.  *
  43.  */
  44. CHXAvSiteSupplier::CHXAvSiteSupplier() 
  45. :
  46.     m_classFactory(NULL),
  47.     m_pContext(NULL),
  48.     m_sitesManager(NULL),
  49.     m_pDSA(NULL),
  50.     m_pRenderWindow(0),
  51.     m_bIsDSAStarted(false)
  52. {
  53. }
  54. /*
  55.  * ~CHXAvSiteSupplier
  56.  * ------------------
  57.  * Dtor.
  58.  *
  59.  */
  60. CHXAvSiteSupplier::~CHXAvSiteSupplier()
  61. {
  62.     HX_DELETE(m_pDSA);
  63.     HX_RELEASE(m_classFactory);
  64.     HX_RELEASE(m_sitesManager);
  65.     HX_RELEASE(m_pContext);
  66.     HX_ASSERT(m_sitesCreated.IsEmpty());
  67.     m_sitesCreated.RemoveAll();
  68. }
  69. /*
  70.  * ConstructL
  71.  * ----------
  72.  *
  73.  * constuct with IHXPlayer context
  74.  *
  75.  */
  76. void 
  77. CHXAvSiteSupplier::ConstructL(IUnknown* pContext, CCoeControl* pRenderWindow)
  78. {
  79.     HX_ASSERT(pContext);
  80.     HX_ASSERT(pRenderWindow);
  81.  
  82.     m_pRenderWindow = pRenderWindow;
  83.     m_pContext      = pContext;
  84.     if( m_pContext )
  85.     {
  86.         m_pContext->AddRef();
  87.         m_pContext->QueryInterface(IID_IHXSiteManager,(void**)&m_sitesManager);
  88.         m_pContext->QueryInterface(IID_IHXCommonClassFactory, (void**)&m_classFactory);
  89.         HX_ASSERT(m_sitesManager);
  90.         HX_ASSERT(m_classFactory);
  91.     }
  92. }
  93. //
  94. // IHXSiteSupplier::SitesNeeded
  95. //
  96. // Called by player during setup of renderer sites during presentation
  97. // layout (just after play request issued).
  98. //
  99. STDMETHODIMP
  100. CHXAvSiteSupplier::SitesNeeded(UINT32 uRequestID, IHXValues *pProps)
  101. {
  102.     DPRINTF(SYMP_INFO, ("CHXAvSiteSupplier::SitesNeeded()n"));
  103.     HXxWindow* pWin                     = NULL;
  104.     HRESULT             hres            = HXR_OK;
  105.     IHXValues*          pSiteProps      = NULL;
  106.     IHXSiteWindowed*    pSiteWindowed   = NULL;
  107.     IHXBuffer*          pValue          = NULL;
  108.     UINT32              style           = 0;
  109.     IHXSite*            pSite           = NULL;
  110.     TInt                osErr           = KErrNone;
  111.     IHXSite2*           pSite2          = NULL;
  112.     
  113.     HX_ASSERT(m_pRenderWindow);
  114.     CCoeEnv* pCoeEnv  = m_pRenderWindow->ControlEnv();
  115.     HX_ASSERT(pProps);
  116.     
  117.     //Only create one direct screen object and let all the sites share
  118.     //it.
  119.     if( NULL==m_pDSA )
  120.     {
  121.         TRAP(osErr, m_pDSA =
  122.              CDirectScreenAccess::NewL( pCoeEnv->WsSession(),
  123.                                         *pCoeEnv->ScreenDevice(),
  124.                                         *(m_pRenderWindow->DrawableWindow()),
  125.                                         *this
  126.                                         ));
  127.         StartDSA(); 
  128.     }
  129.     
  130.     hres = HXR_FAIL;
  131.     if(SUCCEEDED(m_classFactory->CreateInstance(CLSID_IHXSiteWindowed,
  132.                                                 (void**)&pSiteWindowed)))
  133.         if(SUCCEEDED(pSiteWindowed->QueryInterface(IID_IHXSite,
  134.                                                    (void**)&pSite)))
  135.             hres = pSiteWindowed->QueryInterface(IID_IHXValues,
  136.                                                  (void**)&pSiteProps);
  137.     if (!pProps)
  138.         hres =  HXR_INVALID_PARAMETER;
  139.     
  140.     if (HXR_OK != hres)
  141.     {
  142.         goto exit;
  143.     }
  144.     //We need to figure out what type of site we are supposed to
  145.     //create. We need to "switch" between site user and site
  146.     //properties. So look for the well known site user properties that
  147.     //are mapped onto sites...
  148.     if( SUCCEEDED(pProps->GetPropertyCString("playto",pValue)))
  149.     {
  150.         pSiteProps->SetPropertyCString("channel",pValue);
  151.         HX_RELEASE(pValue);
  152.     }
  153.     else
  154.     {
  155.         if(SUCCEEDED(pProps->GetPropertyCString("name",pValue)))
  156.         {
  157.             pSiteProps->SetPropertyCString("LayoutGroup",pValue);
  158.             HX_RELEASE(pValue);
  159.         }
  160.     }
  161.         
  162.     /*
  163.      * We need to wait until we have set all the properties before
  164.      * we add the site.
  165.      */
  166.     HX_ASSERT(m_sitesManager);
  167.     hres = m_sitesManager->AddSite(pSite);
  168.     if (HXR_OK == hres)
  169.     {
  170.         //Add ourselves as a site watcher..
  171.         pSite->QueryInterface(IID_IHXSite2, (void**)&pSite2 );
  172.         if( pSite2 )
  173.         {
  174.             pSite2->AddPassiveSiteWatcher(this);
  175.             HX_RELEASE(pSite2);
  176.         }
  177.         
  178.         //We only attach a real window to the first site created.
  179.         pWin = new HXxWindow();
  180.         memset( pWin, 0, sizeof(HXxWindow));
  181.         
  182.         pWin->window = m_pRenderWindow->DrawableWindow();
  183.         pWin->iDSA   = m_pDSA;
  184.         
  185.         // Set the clip rect one pixel small all around...
  186.         TRect rect = m_pRenderWindow->Rect();
  187.         pWin->x = 0;
  188.         pWin->y = 0;
  189.         pWin->height = rect.Height();
  190.         pWin->width  = rect.Width();
  191.         
  192.         pWin->clipRect.left   = pWin->clipRect.top = BORDER_WIDTH;
  193.         pWin->clipRect.bottom = pWin->height - BORDER_WIDTH;
  194.         pWin->clipRect.right  = pWin->width - BORDER_WIDTH;
  195.         
  196.         pSiteWindowed->AttachWindow(pWin);
  197.         pSite->AddRef();
  198.         m_sitesCreated.SetAt(uRequestID, pSite);
  199.         DPRINTF(SYMP_INFO, ("CHXAvSiteSupplier::SitesNeeded(): added site; now %ld sitesn", m_sitesCreated.GetCount()));
  200.     }
  201.     
  202. exit:
  203.     if (HXR_OK != hres)
  204.     {
  205.         if( m_pDSA )
  206.             m_pDSA->Cancel();
  207.         HX_DELETE(m_pDSA);
  208.         HX_DELETE(pWin);
  209.     }
  210.     HX_RELEASE(pSiteProps);
  211.     HX_RELEASE(pSiteWindowed);
  212.     HX_RELEASE(pSite);
  213.     return hres;
  214. }
  215. //
  216. // IHXSiteSupplier::SitesNotNeeded
  217. //
  218. // Called when most recent presentation layout is being closed. This is not
  219. // called after IHXPlayer::Stop(). The layout remains persistent until:
  220. //  a) a new play request is issued (even if for exact same url, i.e., replay)
  221. //  b) the player object is closed
  222. //
  223. STDMETHODIMP CHXAvSiteSupplier::SitesNotNeeded(UINT32 uRequestID)
  224. {
  225.     DPRINTF(SYMP_INFO, ("CHXAvSiteSupplier::SitesNotNeeded()n"));
  226.     IHXSite*         pSite         = NULL;
  227.     IHXSiteWindowed* pSiteWindowed = NULL;
  228.     IHXSite2*        pSite2        = NULL;
  229.     
  230.     void *pVoid = NULL;
  231.     if (!m_sitesCreated.Lookup(uRequestID, pVoid))
  232.     {
  233.         return HXR_INVALID_PARAMETER;
  234.     }
  235.     pSite = (IHXSite*)pVoid;
  236.     m_sitesManager->RemoveSite(pSite);
  237.     //Remove ourselves as a passive site watcher..
  238.     pSite->QueryInterface(IID_IHXSite2, (void**)&pSite2 );
  239.     if( pSite2 )
  240.     {
  241.         pSite2->AddPassiveSiteWatcher( (IHXPassiveSiteWatcher*)this);
  242.         HX_RELEASE(pSite2);
  243.     }
  244.     
  245.     // Need to actually do the work on destroying the window
  246.     // and all that jazz.
  247.     pSite->QueryInterface(IID_IHXSiteWindowed,(void**)&pSiteWindowed);
  248.     //Free the window we passed in.
  249.     HXxWindow* pWin = pSiteWindowed->GetWindow();
  250.     pSiteWindowed->Destroy();
  251.     HX_DELETE(pWin);
  252.     HX_RELEASE(pSiteWindowed);
  253.     m_sitesCreated.Remove(uRequestID);
  254.     HX_RELEASE(pSite);
  255.     DPRINTF(SYMP_INFO, ("CHXAvSiteSupplier::SitesNotNeeded(): removed site; now %ld sitesn", m_sitesCreated.GetCount()));
  256.     //If we have no more sites then destroy the direct screen access
  257.     //object so it isn't associated with the playback window that is
  258.     //not around anymore.
  259.     if( m_sitesCreated.IsEmpty())
  260.     {
  261.         m_pDSA->Cancel();
  262.         HX_DELETE(m_pDSA);
  263.     }
  264.     
  265.     return HXR_OK;
  266. }
  267. //
  268. // IHXSiteSupplier::BeginChangeLayout
  269. //
  270. // Called:
  271. //  a) during layout cleanup done when renderers are closed. SitesNotNeeded() is called after this.
  272. //  b) during first presentation layout
  273. //
  274. STDMETHODIMP
  275. CHXAvSiteSupplier::BeginChangeLayout()
  276. {
  277.     DPRINTF(SYMP_INFO, ("CHXAvSiteSupplier::BeginChangeLayout()n"));
  278.     return HXR_OK;
  279. }
  280. //
  281. // IHXSiteSupplier::DoneChangeLayout
  282. //
  283. // Called after SitesNeeded(), after layout is complete.
  284. //
  285. STDMETHODIMP
  286. CHXAvSiteSupplier::DoneChangeLayout()
  287. {
  288.     DPRINTF(SYMP_INFO, ("CHXAvSiteSupplier::DoneChangeLayout()n"));
  289.     return HXR_OK;
  290. }
  291. bool CHXAvSiteSupplier::IsUsingSites() const
  292. {
  293.     return !m_sitesCreated.IsEmpty();
  294. }
  295. TInt CHXAvSiteSupplier::StartDSA()
  296. {
  297.     HX_ASSERT(m_pDSA);
  298.     TRAPD(err, m_pDSA->StartL());
  299.     //HX_ASSERT(KErrNone == err); // err expected when app looses foreground
  300.     m_bIsDSAStarted = (err == KErrNone);
  301.     return err;
  302. }
  303.  
  304. //
  305. // AbortNow() and Restart() are (always?) called in pairs. These are called when
  306. // our render window is covered/uncovered, i.e., whenever we need to recalculate
  307. // our clipping rect. This includes following cases:
  308. //  a) menu goes up
  309. //  b) dialog goes up
  310. //  c) CCoeControl associated with DSA is destroyed
  311. //  d) user presses app switcher key (before fg event)
  312. //
  313. // StartL() will fail in cases (c) and (d)
  314. //
  315. void CHXAvSiteSupplier::Restart(RDirectScreenAccess::TTerminationReasons aReason)
  316. {
  317.     DPRINTF(SYMP_INFO, ("CHXAvSiteSupplier::Restart(): reason = %dn", aReason));
  318.     StartDSA();
  319. }
  320. void CHXAvSiteSupplier::AbortNow(RDirectScreenAccess::TTerminationReasons aReason)
  321. {
  322.     DPRINTF(SYMP_INFO, ("CHXAvSiteSupplier::AbortNow(): reason = %dn", aReason));
  323.     m_pDSA->Cancel();
  324.     m_bIsDSAStarted = false;
  325. }
  326. HX_RESULT CHXAvSiteSupplier::PositionChanged (HXxPoint* pPoint)
  327. {
  328.     DPRINTF(SYMP_INFO, ("CHXAvSiteSupplier::PositionChanged() %d, %dn", pPoint->x, pPoint->y));
  329.     return HXR_OK;
  330. }
  331. namespace
  332. {
  333. HXxRect GetRect(IHXSite* pSite)
  334. {
  335.     HX_ASSERT(pSite);
  336.     HXxSize size;
  337.     pSite->GetSize(size);
  338.     HXxPoint tl;
  339.     pSite->GetPosition(tl);
  340.     HXxRect rect;
  341.     rect.left = tl.x;
  342.     rect.top = tl.y;
  343.     rect.right = rect.left + size.cx;
  344.     rect.bottom = rect.top + size.cy;
  345.     return rect;
  346. }
  347. }
  348. void CHXAvSiteSupplier::RedrawAllSites()
  349. {
  350.     DPRINTF(SYMP_INFO, ("CHXAvSiteSupplier::RedrawAllSites()n"));
  351.     
  352.     if( m_pDSA )
  353.     {
  354.         if( !m_bIsDSAStarted )
  355.         {
  356.             StartDSA();
  357.         }
  358.         if( m_bIsDSAStarted )
  359.         {
  360.             //Grab a sitemanager2 interface from our only player so we can
  361.             //iterate over the sites.
  362.             IHXClientEngine* pEngine       = NULL; 
  363.             IUnknown*        pUnknown      = NULL;
  364.             IHXSiteManager2* pSiteManager2 = NULL;
  365.             IHXSite*         pSite         = NULL;
  366.             ULONG32          nNumSites     = 0;
  367.             
  368.             m_pContext->QueryInterface(IID_IHXClientEngine, (void**)&pEngine);
  369.             HX_ASSERT(pEngine);
  370.     
  371.             if(pEngine)
  372.             {
  373.                 //We should always have only 1 engine in the symbian players.
  374.                 int nPlayerCount = pEngine->GetPlayerCount();
  375.                 HX_ASSERT(nPlayerCount==1);
  376.                 if( nPlayerCount>0)
  377.                 {
  378.                     pEngine->GetPlayer(0, pUnknown);
  379.                     if(pUnknown)
  380.                     {
  381.                         pUnknown->QueryInterface(IID_IHXSiteManager2, (void**) &pSiteManager2);
  382.                         if (pSiteManager2)
  383.                         {
  384.                             pSiteManager2->GetNumberOfSites(nNumSites);
  385.                             for(unsigned int idx = 0; idx< nNumSites; idx++)
  386.                             {
  387.                                 IHXSiteControl* pSiteController = NULL;
  388.                                 pSiteManager2->GetSiteAt(idx, pSite);
  389.                                 pSite->QueryInterface(IID_IHXSiteControl, (void**)&pSiteController);
  390.                                 if( pSiteController )
  391.                                 {
  392.                                     //We want to do the recursive redraw. 
  393.                                     pSiteController->ForceRedrawAll();
  394.                                 }
  395.                                 else
  396.                                 {
  397.                                     //If we don't have tne new
  398.                                     //interface, try doing it the old
  399.                                     //non recursive way.
  400.                                     pSite->DamageRect(GetRect(pSite));
  401.                                     pSite->ForceRedraw();
  402.                                 }
  403.                                 HX_RELEASE(pSiteController);
  404.                             }
  405.                             HX_RELEASE(pSiteManager2);
  406.                         }
  407.                         HX_RELEASE(pUnknown);
  408.                     }
  409.                 }
  410.                 HX_RELEASE(pEngine);
  411.             }
  412.         }
  413.     }
  414. }
  415. void CHXAvSiteSupplier::RestackSites()
  416. {
  417.     HXxPoint point = {0,0};
  418.     HXxSize  size = {0,0};
  419.     TInt     nTotalHeight= 0;
  420.     //Get our windows width and height
  421.     TRect rect = m_pRenderWindow->Rect();
  422.     //The site takes care of any scaling that needs to be done.  The
  423.     //site supplier will take care of centering the site(s). First go
  424.     //through all the sites and get the total height.
  425.     CHXMapLongToObj::Iterator end = m_sitesCreated.End();
  426.     CHXMapLongToObj::Iterator it = m_sitesCreated.Begin();
  427.     for( ; it != end; ++it)
  428.     {
  429.         // First one created gets put on top...
  430.         IHXSite* pSite = (IHXSite*)*it;
  431.         pSite->GetSize(size);
  432.         nTotalHeight  += size.cy;
  433.     }
  434.     
  435.     //Now go through and restack and position sites.
  436.     point.y = (rect.Height()-nTotalHeight)/2;
  437.     if( point.y < 0 )
  438.         point.y = 0;
  439.     
  440.     end = m_sitesCreated.End();
  441.     for(it = m_sitesCreated.Begin(); it != end; ++it)
  442.     {
  443.         // First one created gets put on top...
  444.         IHXSite* pSite = (IHXSite*)*it;
  445.         pSite->GetSize(size);
  446.         point.x = (rect.Width()-size.cx)/2;
  447.         pSite->SetPosition(point);
  448.         point.y += size.cy;     
  449.     }
  450. }
  451. HX_RESULT CHXAvSiteSupplier::SizeChanged( HXxSize* pSize)
  452. {
  453.     DPRINTF(SYMP_INFO, ("CHXAvSiteSupplier::SizeChanged()n"));
  454.     RestackSites();
  455.     return HXR_OK;
  456. }