smldoc.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:673k
源码类别:

Symbian

开发平台:

Visual C++

  1.     }
  2. }
  3. void CSmilDocumentRenderer::queueRegionForRecompute(CSmilBasicRegion* pRegion)
  4. {
  5.     if (pRegion && m_pAnimRegionRecomputeMap)
  6.     {
  7.         m_pAnimRegionRecomputeMap->SetAt((void*) pRegion, (void*) pRegion);
  8.     }
  9. }
  10. void CSmilDocumentRenderer::removePendingAnimationRedraw(IHXSite* pSite)
  11. {
  12.     if (pSite && m_pAnimSiteRedrawMap)
  13.     {
  14.         // XXXMEH - TODO - right now, if we have done a SetSize()
  15.         // or SetPostion() on a site, then we remove any pending
  16.         // ForceRedraw() on that site. However, both SetSize and
  17.         // SetPosition() force redraws on other sites as well,
  18.         // like the parent and siblings. We should optimize those
  19.         // out as well, but we need a reliable way of determining
  20.         // if those sites are going to get redrawn.
  21.         m_pAnimSiteRedrawMap->RemoveKey((void*) pSite);
  22.     }
  23. }
  24. void CSmilDocumentRenderer::turnSiteCompositionModeON()
  25. {
  26.     MLOG_ANIM(m_pErrorMessages,"turnSiteCompositionModeON()tm_ulCurrentTime=%luttick=%lun",
  27.               m_ulCurrentTime, HX_GET_BETTERTICKCOUNT());
  28.     if (m_pRootLayout && m_pRootLayout->m_pSite)
  29.     {
  30.         IHXSiteComposition* pSiteComp = NULL;
  31.         m_pRootLayout->m_pSite->QueryInterface(IID_IHXSiteComposition, (void**) &pSiteComp);
  32.         if (pSiteComp)
  33.         {
  34.             pSiteComp->SetCompositionMode(TRUE);
  35.         }
  36.         HX_RELEASE(pSiteComp);
  37.     }
  38. }
  39. void CSmilDocumentRenderer::turnSiteCompositionModeOFF()
  40. {
  41.     MLOG_ANIM(m_pErrorMessages,"turnSiteCompositionModeOFF()tm_ulCurrentTime=%luttick=%lun",
  42.               m_ulCurrentTime, HX_GET_BETTERTICKCOUNT());
  43.     if (m_pRootLayout && m_pRootLayout->m_pSite)
  44.     {
  45.         IHXSiteComposition* pSiteComp = NULL;
  46.         m_pRootLayout->m_pSite->QueryInterface(IID_IHXSiteComposition, (void**) &pSiteComp);
  47.         if (pSiteComp)
  48.         {
  49.             pSiteComp->SetCompositionMode(FALSE);
  50.         }
  51.         HX_RELEASE(pSiteComp);
  52.     }
  53. }
  54. void CSmilDocumentRenderer::lockSiteComposition()
  55. {
  56.     MLOG_ANIM(m_pErrorMessages,"lockSiteComposition()tm_ulCurrentTime=%luttick=%lun",
  57.               m_ulCurrentTime, HX_GET_BETTERTICKCOUNT());
  58.     if (m_pRootLayout && m_pRootLayout->m_pSite)
  59.     {
  60.         IHXSiteComposition* pSiteComp = NULL;
  61.         m_pRootLayout->m_pSite->QueryInterface(IID_IHXSiteComposition, (void**) &pSiteComp);
  62.         if (pSiteComp)
  63.         {
  64.             pSiteComp->LockComposition();
  65.         }
  66.         HX_RELEASE(pSiteComp);
  67.     }
  68. }
  69. void CSmilDocumentRenderer::unlockSiteComposition()
  70. {
  71.     MLOG_ANIM(m_pErrorMessages,"unlockSiteComposition()tm_ulCurrentTime=%luttick=%lun",
  72.               m_ulCurrentTime, HX_GET_BETTERTICKCOUNT());
  73.     if (m_pRootLayout && m_pRootLayout->m_pSite)
  74.     {
  75.         IHXSiteComposition* pSiteComp = NULL;
  76.         m_pRootLayout->m_pSite->QueryInterface(IID_IHXSiteComposition, (void**) &pSiteComp);
  77.         if (pSiteComp)
  78.         {
  79.             pSiteComp->UnlockComposition();
  80.         }
  81.         HX_RELEASE(pSiteComp);
  82.     }
  83. }
  84. void CSmilDocumentRenderer::bltSiteComposition()
  85. {
  86.     MLOG_ANIM(m_pErrorMessages,"bltSiteComposition()tm_ulCurrentTime=%luttick=%lun",
  87.               m_ulCurrentTime, HX_GET_BETTERTICKCOUNT());
  88.     if (m_pRootLayout && m_pRootLayout->m_pSite)
  89.     {
  90.         IHXSiteComposition* pSiteComp = NULL;
  91.         m_pRootLayout->m_pSite->QueryInterface(IID_IHXSiteComposition, (void**) &pSiteComp);
  92.         if (pSiteComp)
  93.         {
  94.             pSiteComp->BltComposition();
  95.         }
  96.         HX_RELEASE(pSiteComp);
  97.     }
  98. }
  99. BOOL CSmilDocumentRenderer::isSiteCompositionLocked()
  100. {
  101.     BOOL bRet = FALSE;
  102.     if (m_pRootLayout && m_pRootLayout->m_pSite)
  103.     {
  104.         IHXSiteComposition* pSiteComp = NULL;
  105.         m_pRootLayout->m_pSite->QueryInterface(IID_IHXSiteComposition, (void**) &pSiteComp);
  106.         if (pSiteComp)
  107.         {
  108.             bRet = pSiteComp->IsCompositionLocked();
  109.         }
  110.         HX_RELEASE(pSiteComp);
  111.     }
  112.     return bRet;
  113. }
  114. BOOL CSmilDocumentRenderer::isSiteCompositionModeON()
  115. {
  116.     BOOL bRet = FALSE;
  117.     if (m_pRootLayout && m_pRootLayout->m_pSite)
  118.     {
  119.         IHXSiteComposition* pSiteComp = NULL;
  120.         m_pRootLayout->m_pSite->QueryInterface(IID_IHXSiteComposition, (void**) &pSiteComp);
  121.         if (pSiteComp)
  122.         {
  123.             bRet = pSiteComp->IsCompositionMode();
  124.         }
  125.         HX_RELEASE(pSiteComp);
  126.     }
  127.     return bRet;
  128. }
  129. void CSmilDocumentRenderer::GoToURLWithParamCheck(const char*        pszURL,
  130.                                                   const char*        pszTarget,
  131.                                                   const char*        pszSendTo,
  132.                                                   IHXHyperNavigate* pHyper,
  133.                                                   CSmilElement*      pElement,
  134.                                                   IUnknown*          pContext,
  135.   BOOL      bUserInvoked,
  136.                                                   BOOL               bHint)
  137. {
  138.     if (pszURL && pHyper && pElement && pContext)
  139.     {
  140.         // Are there any <rn:param> children of
  141.         // this <area> tag?
  142. BOOL bHasParamChildren = hasParamChildren(pElement, FALSE);
  143.         IHXCommonClassFactory* pFact = NULL;
  144.         pContext->QueryInterface(IID_IHXCommonClassFactory, (void**) &pFact);
  145.         if (pFact)
  146.         {
  147.             IHXValues* pParams = NULL;
  148.             pFact->CreateInstance(CLSID_IHXValues, (void**) &pParams);
  149.             if (pParams)
  150.             {
  151. if (bHasParamChildren)
  152. {
  153.     // Add the name/value pairs from all
  154.     // <rn:param> children to the IHXValues
  155.     addParamProperties(pElement, pParams, pContext, FALSE);
  156. }
  157. // /Add the sendTo value, if there is one:
  158. if (pszSendTo)
  159. {
  160.     addStringProperty(pParams, pContext, "sendTo", pszSendTo);
  161. }
  162. // /Fixes open-outside-of-media-pane version of PR 84160:
  163. pParams->SetPropertyULONG32("AutoActivated",
  164. (ULONG32)(!bUserInvoked));
  165.                 if (bHint)
  166.                 {
  167.                     // Add "begin" parameter
  168.                     pParams->SetPropertyULONG32("begin", pElement->m_ulDelay);
  169.                     // QI for IHXHyperNavigateHint
  170.                     IHXHyperNavigateHint* pHint = NULL;
  171.                     pHyper->QueryInterface(IID_IHXHyperNavigateHint, (void**) &pHint);
  172.                     if (pHint)
  173.                     {
  174.                         // Now call IHXHyperNavigateHint::Hint()
  175.                         pHint->Hint(pszURL, pszTarget, pParams);
  176.                     }
  177.                     HX_RELEASE(pHint);
  178.                 }
  179.                 else
  180.                 {
  181.                     // QI for IHXHyperNavigate2
  182.                     IHXHyperNavigate2* pNav2 = NULL;
  183.                     pHyper->QueryInterface(IID_IHXHyperNavigate2, (void**) &pNav2);
  184.                     if (pNav2)
  185.                     {
  186.                         // Now call IHXHyperNavigate2::Execute()
  187.                         pNav2->Execute(pszURL, pszTarget, NULL, NULL, pParams);
  188.                     }
  189.                     else
  190.                     {
  191.                         // We couldn't get IHXHyperNavigate2, so 
  192.                         // just use IHXHyperNavigate.
  193.                         pHyper->GoToURL(pszURL, pszTarget);
  194.                     }
  195.                     HX_RELEASE(pNav2);
  196.                 }
  197.             }
  198.             HX_RELEASE(pParams);
  199.         }
  200.         HX_RELEASE(pFact);
  201.     }
  202. }
  203. UINT16 CSmilDocumentRenderer::getCurrentGroup()
  204. {
  205.     UINT16 usRet = 0;
  206.     if (m_pParent)
  207.     {
  208.         IHXPlayer* pPlayer = m_pParent->getPlayer();
  209.         if (pPlayer)
  210.         {
  211.            IHXGroupManager* pGroupManager = NULL;
  212.            pPlayer->QueryInterface(IID_IHXGroupManager, (void**) &pGroupManager);
  213.            if (pGroupManager)
  214.            {
  215.                pGroupManager->GetCurrentGroup(usRet);
  216.            }
  217.            HX_RELEASE(pGroupManager);
  218.         }
  219.     }
  220.     return usRet;
  221. }
  222. void CSmilDocumentRenderer::deleteExternalMediaMarkerList()
  223. {
  224.     if (m_pExternalMediaMarkerList)
  225.     {
  226.         LISTPOSITION pos = m_pExternalMediaMarkerList->GetHeadPosition();
  227.         while (pos)
  228.         {
  229.             CExternalMediaMarkerInfo* pInfo =
  230.                 (CExternalMediaMarkerInfo*) m_pExternalMediaMarkerList->GetNext(pos);
  231.             HX_DELETE(pInfo);
  232.         }
  233.         m_pExternalMediaMarkerList->RemoveAll();
  234.         HX_DELETE(m_pExternalMediaMarkerList);
  235.     }
  236. }
  237. CExternalMediaMarkerInfo* CSmilDocumentRenderer::getExternalMediaMarkerInfo(const char* pszURL)
  238. {
  239.     CExternalMediaMarkerInfo* pRet = NULL;
  240.     if (pszURL && m_pExternalMediaMarkerList)
  241.     {
  242.         LISTPOSITION pos = m_pExternalMediaMarkerList->GetHeadPosition();
  243.         while (pos)
  244.         {
  245.             CExternalMediaMarkerInfo* pInfo =
  246.                 (CExternalMediaMarkerInfo*) m_pExternalMediaMarkerList->GetNext(pos);
  247.             if (pInfo &&
  248.                 (!strcmp(pInfo->m_pszAddTrackURL, pszURL) ||
  249.                  !strcmp(pInfo->m_pszRendererURL, pszURL)))
  250.             {
  251.                 pRet = pInfo;
  252.                 break;
  253.             }
  254.         }
  255.     }
  256.     return pRet;
  257. }
  258. BOOL CSmilDocumentRenderer::isIDMappedToExternalMediaMarkerFile(CExternalMediaMarkerInfo* pInfo,
  259.                                                                 const char*               pszID)
  260. {
  261.     BOOL bRet = FALSE;
  262.     if (pInfo && pInfo->m_pIDList && pszID)
  263.     {
  264.         LISTPOSITION pos = pInfo->m_pIDList->GetHeadPosition();
  265.         while (pos)
  266.         {
  267.             char* pID = (char*) pInfo->m_pIDList->GetNext(pos);
  268.             if (pID && !strcmp(pID, pszID))
  269.             {
  270.                 bRet = TRUE;
  271.                 break;
  272.             }
  273.         }
  274.     }
  275.     return bRet;
  276. }
  277. HX_RESULT
  278. CSmilDocumentRenderer::closeOldRenderers(BOOL bAll)
  279. {
  280.     if (m_pDelayedRendererCloseList)
  281.     {
  282. LISTPOSITION pos = m_pDelayedRendererCloseList->GetHeadPosition();
  283. while (pos)
  284. {
  285.     SMILDelayedRendererClose* pClose = 
  286. (SMILDelayedRendererClose*)m_pDelayedRendererCloseList->GetAt(pos);
  287.     if (bAll || pClose->m_uGroup != m_uCurrentGroupIndex)
  288.     {
  289. if (bAll)
  290. {
  291.     // If we are not closing all, then the Site SHOULD allready be hidden.
  292.     CSmilBasicRegion* pRegion = getRegionByID(pClose->m_pSiteInfo->m_regionID);
  293.     IHXSite* pRegionSite = NULL;
  294.     if (pRegion->m_eBackgroundColorType == CSS2TypeTransparent)
  295.     {
  296. pRegionSite = pClose->m_pSiteInfo->m_pRegionSite;
  297.     }
  298.     
  299.     showSite(pClose->m_pSiteInfo->m_pRendererSite, FALSE);
  300.     showSite(pRegionSite, FALSE);
  301. }
  302. actualRendererClosed(pClose->m_pRenderer, pClose->m_pInfo);
  303. HX_RELEASE(pClose->m_pRenderer);
  304. HX_RELEASE(pClose->m_pInfo);
  305. pos = m_pDelayedRendererCloseList->RemoveAt(pos);
  306. HX_DELETE(pClose);
  307.     }
  308.     else
  309.     {
  310. m_pDelayedRendererCloseList->GetNext(pos);
  311.     }
  312. }
  313.     }
  314.     return HXR_OK;
  315. }
  316. STDMETHODIMP
  317. CSmilDocumentRenderer::RendererClosed(IHXRenderer* pRenderer, 
  318.       IHXValues* pInfo)
  319. {
  320.     HX_RESULT ret = HXR_OK;
  321.     UINT32 ulGroupIndex = 0;
  322.     UINT32 ulTrackIndex = 0;
  323.     SMILSiteInfo* pSiteInfo = NULL;
  324.     SMILGroupInfo* pGroupInfo = NULL;
  325.     SMILPlayToAssoc* pPlayToAssoc = NULL;
  326.     pInfo->GetPropertyULONG32("GroupIndex", ulGroupIndex);
  327.     pInfo->GetPropertyULONG32("TrackIndex", ulTrackIndex);
  328.     IHXBuffer* pBuffer = NULL;
  329.     if (HXR_OK == pInfo->GetPropertyCString("id", pBuffer))
  330.     {
  331. pPlayToAssoc = getPlayToAssocByMedia((const char*)pBuffer->GetBuffer());
  332.     }
  333.     HX_RELEASE(pBuffer);
  334.     if (!pPlayToAssoc)
  335.     {
  336. // XXX HP we shouldn't be here
  337. HX_ASSERT(FALSE);
  338. pPlayToAssoc = getPlayToAssoc((UINT16)ulGroupIndex, (UINT16)ulTrackIndex);
  339.     }
  340.     // RemoveTrack() has been called on this track
  341.     if (pPlayToAssoc && pPlayToAssoc->m_bRemovePending)
  342.     {
  343. ret = actualRendererClosed(pRenderer, pInfo);
  344.     }
  345.     else if (m_pSiteInfoByRendererMap &&
  346.      m_pSiteInfoByRendererMap->Lookup(pRenderer, (void*&)pSiteInfo))
  347.     {
  348. if (!pSiteInfo->m_bNoRegion &&
  349.     m_pGroupInfoMap &&
  350.     m_pGroupInfoMap->Lookup(ulGroupIndex, (void*&)pGroupInfo))
  351. {
  352.     // check to see if this site ended at the end of this group,
  353.     // if it did, we will delay actually closing the renderer 
  354.     // until after the next group is started... That way we can
  355.     // keep a site arround if there is a transition...
  356.     if (pSiteInfo->m_ulDuration == pGroupInfo->m_ulDuration)
  357.     {
  358. SMILDelayedRendererClose* pClose = new SMILDelayedRendererClose;
  359. if (pClose)
  360. {
  361.     pClose->m_uGroup = (UINT16)ulGroupIndex;
  362.     pClose->m_pRenderer = pRenderer;
  363.     pClose->m_pRenderer->AddRef();
  364.     pClose->m_pInfo = pInfo;
  365.     pClose->m_pInfo->AddRef();
  366.     pClose->m_pSiteInfo = pSiteInfo;
  367.     if (!m_pDelayedRendererCloseList)
  368.     {
  369. m_pDelayedRendererCloseList = new CHXSimpleList;
  370.     }
  371.     if (m_pDelayedRendererCloseList)
  372.     {
  373. m_pDelayedRendererCloseList->AddTail(pClose);
  374.     }
  375.     else
  376.     {
  377. ret = HXR_OUTOFMEMORY;
  378.     }
  379. }
  380. else
  381. {
  382.     ret = HXR_OUTOFMEMORY;
  383. }
  384.     }
  385.     else
  386.     {
  387. ret = actualRendererClosed(pRenderer, pInfo);
  388.     }
  389. }
  390.    else
  391. {
  392.     // if there is no group info, just close the renderer.
  393.     ret = actualRendererClosed(pRenderer, pInfo);
  394. }
  395.     }
  396.     else
  397.     {
  398. // if there is no site info, just close the renderer.
  399. ret = actualRendererClosed(pRenderer, pInfo);
  400.     }
  401.    return ret;
  402. }
  403. HX_RESULT
  404. CSmilDocumentRenderer::actualRendererClosed(IHXRenderer* pRenderer, 
  405.     IHXValues* pInfo)
  406. {
  407.     UINT32 ulGroupIndex = 0;
  408.     UINT32 ulTrackIndex = 0;
  409.     UINT32 ulStreamNumber = 0;
  410.     CHXSimpleList* pRendererList = NULL;
  411.     SMILSiteInfo* pSiteInfo = NULL;
  412.     SMILPlayToAssoc* pPlayToAssoc = NULL;
  413.     pInfo->GetPropertyULONG32("GroupIndex", ulGroupIndex);
  414.     pInfo->GetPropertyULONG32("TrackIndex", ulTrackIndex);
  415.     pInfo->GetPropertyULONG32("StreamNumber", ulStreamNumber);
  416.     if (m_pPlayToAssocList)
  417.     {
  418. IHXBuffer* pBuffer = NULL;
  419. if (HXR_OK == pInfo->GetPropertyCString("id", pBuffer))
  420. {
  421.     pPlayToAssoc = getPlayToAssocByMedia((const char*)pBuffer->GetBuffer());
  422. }
  423. HX_RELEASE(pBuffer);
  424. if (!pPlayToAssoc)
  425. {
  426.     // XXX HP we shouldn't be here
  427.     HX_ASSERT(FALSE);
  428.     pPlayToAssoc = getPlayToAssoc((UINT16)ulGroupIndex, (UINT16)ulTrackIndex);
  429. }
  430. if (pPlayToAssoc)
  431. {
  432.     pPlayToAssoc->m_sourceMap.Lookup(ulStreamNumber, (void*&) pRendererList);
  433.             // Remove any event sinks set up on this renderer
  434.             addRemoveEventSink((const char*) pPlayToAssoc->m_id, FALSE);
  435.             // Remove this renderer from the map
  436.             removeRendererFromMap((const char*) pPlayToAssoc->m_id);
  437. }
  438.     }
  439. //{FILE* f1 = ::fopen("c:\temp\out.txt", "a+"); ::fprintf(f1, "RendererClosed pRenderer=%lun", pRenderer);::fclose(f1);}
  440.     if (m_pSiteInfoByRendererMap && 
  441. m_pSiteInfoByRendererMap->Lookup(pRenderer, (void*&) pSiteInfo))
  442.     {
  443. RemoveEvents(ulGroupIndex, pSiteInfo->m_pRendererSite);
  444. m_pSiteInfoByRendererMap->RemoveKey((void*)pRenderer);
  445. CSmilBasicRegion* pRegion = getRegionByID(pSiteInfo->m_regionID);
  446. IHXSite* pRegionSite = NULL;
  447. if (pRegion && pRegion->m_eBackgroundColorType == CSS2TypeTransparent)
  448. {
  449.     pRegionSite = pSiteInfo->m_pRegionSite;
  450. }
  451. #ifdef XXX_HIDE_SITES_ON_CLOSE
  452. showSite(pSiteInfo->m_pRendererSite, FALSE);
  453. // we only want to hide the region if there is no more 
  454. // renderer site shares the same region
  455. if (!pRendererList || pRendererList->GetCount() == 1)
  456. {
  457.     IHXSite* pRegionSite = NULL;
  458.     if (!pRegion->m_bBgColorSet)
  459.     {
  460. pRegionSite = pSiteInfo->m_pRegionSite;
  461.     }    
  462.     showSite(pRegionSite, FALSE);
  463. }
  464. #endif
  465.         // Hide the site, since we're about to blow
  466.         // it away anyway.
  467. showSite(pSiteInfo->m_pRendererSite, FALSE);
  468. m_pSiteMgr->RemoveSite(pSiteInfo->m_pRendererSite);
  469. pSiteInfo->m_pRendererSite->DetachWatcher();
  470.         // Get the site watcher from the site watcher map
  471.         if (m_pSiteWatcherMap)
  472.         {
  473.             void* pVoid = NULL;
  474.             if (m_pSiteWatcherMap->Lookup((void*) pSiteInfo->m_pRendererSite, pVoid) &&
  475.                 pVoid)
  476.             {
  477.                 // Get the CSmilSiteWatcher pointer
  478.                 CSmilSiteWatcher* pWatcher = (CSmilSiteWatcher*) pVoid;
  479.                 // Remove the site watcher from the site watcher map
  480.                 m_pSiteWatcherMap->RemoveKey((void*) pSiteInfo->m_pRendererSite);
  481.                 // Remove the site watcher from the map
  482.                 if (pPlayToAssoc)
  483.                 {
  484.                     removeRendererSiteWatcherFromMap((const char*) pPlayToAssoc->m_id);
  485.                 }
  486.                 // Release our ref on the site watcher
  487.                 HX_RELEASE(pWatcher);
  488.             }
  489.         }
  490. if(pRegion &&
  491.     pRegion->m_pSite)
  492. {
  493.     pRegion->m_pSite->DestroyChild(pSiteInfo->m_pRendererSite);
  494. }
  495.         //XXXgfw this is too fix PR56050. This release deletes the
  496.         //site but a pointer is left to it in m_pChildRendererSiteList
  497.         //This list is iterated through inside of resetRendererSites
  498.         //and SetSize is called a site that doesn't exist.
  499.         //
  500.         //So, this is my fix without knowing much about this code. :-)
  501.         if( pRegion && pSiteInfo )
  502.         {
  503.             pRegion->removeRendererSiteChild(pSiteInfo->m_pRendererSite);
  504.         }
  505.         // Remove the site from the map
  506.         if (pPlayToAssoc)
  507.         {
  508.             removeRendererSiteFromMap((const char*) pPlayToAssoc->m_id);
  509.         }
  510.         
  511. HX_RELEASE(pSiteInfo->m_pRendererSite);
  512.         // remove the site info struct from m_pSiteInfoList
  513.         // but *don't* delete it yet - we will do that down
  514.         // at the bottom of this method
  515.         removeSiteInfo(pSiteInfo);
  516.     }
  517.     if (pPlayToAssoc)
  518.     {
  519. LISTPOSITION    pos;
  520. SMILSourceInfo* pSMILSourceInfo = NULL;
  521. if (pRendererList)
  522. {
  523.     CHXSimpleList::Iterator  i = pRendererList->Begin();
  524.     for (; i != pRendererList->End(); ++i)
  525.     {
  526. pSMILSourceInfo = (SMILSourceInfo*) (*i);
  527. if (pSMILSourceInfo->m_pRenderer == pRenderer)
  528. {
  529.     pos = pRendererList->Find(pSMILSourceInfo);
  530.     pRendererList->RemoveAt(pos);   
  531.     if (pSMILSourceInfo->m_pRendererEventHook)
  532.     {
  533. // get to the site manager and set an event hook
  534. IHXEventHookMgr* pHookMgr = NULL;
  535. if(HXR_OK == m_pSiteMgr->QueryInterface(IID_IHXEventHookMgr, 
  536. (void**)&pHookMgr))
  537. {
  538.     pHookMgr->RemoveHook(pSMILSourceInfo->m_pRendererEventHook, 
  539.  pSMILSourceInfo->m_pRendererEventHook->GetChannelName(), 0);
  540. }
  541. pHookMgr->Release();
  542.     }
  543.     
  544.     HX_RELEASE(pSMILSourceInfo->m_pRendererEventHook);
  545.     HX_RELEASE(pSMILSourceInfo->m_pStream);
  546.     HX_RELEASE(pSMILSourceInfo->m_pRenderer);
  547.     HX_DELETE(pSMILSourceInfo);
  548.     break;
  549. }
  550.     }
  551.     if (pRendererList->GetCount())
  552.     {
  553. pSMILSourceInfo = (SMILSourceInfo*)pRendererList->GetHead();
  554.     
  555. pPlayToAssoc->m_tunerName = pSMILSourceInfo->m_tunerName;
  556. pPlayToAssoc->m_childTunerName = pSMILSourceInfo->m_childTunerName;
  557. pPlayToAssoc->m_ulDelay = pSMILSourceInfo->m_ulDelay;
  558. pPlayToAssoc->m_ulDuration = pSMILSourceInfo->m_ulDuration;
  559. pPlayToAssoc->m_pRendererEventHook = pSMILSourceInfo->m_pRendererEventHook;
  560.     }
  561. }
  562. if (pPlayToAssoc->m_pSiteInfoList->GetCount() > 0 &&
  563.     pSiteInfo)
  564. {
  565.     pos = pPlayToAssoc->m_pSiteInfoList->Find(pSiteInfo);
  566.     if (pos)
  567.     {
  568. pPlayToAssoc->m_pSiteInfoList->RemoveAt(pos);
  569.     }
  570.             HX_DELETE(pSiteInfo);
  571. }
  572.     }
  573.     return HXR_OK;
  574. }
  575. HX_RESULT CSmilDocumentRenderer::addSiteForRenderer(SMILPlayToAssoc* pPlayToAssoc,
  576.                                                     SMILSourceInfo*  pSMILSourceInfo,
  577.                                                     IHXRenderer*    pRenderer,
  578.                                                     BOOL             bNoRegion)
  579. {
  580.     HX_RESULT retVal = HXR_OK;
  581.     if (m_pRootLayout)
  582.     {
  583.         // We need to decide whether this renderer is playing to
  584.         // a single region (where the <ref>'s "region" attribute
  585.         // is a <region> id) or multiple regions (where the <ref>'s
  586.         // "region" attribute is a <region> regionName)
  587.         //
  588.         // Try to get a region by regionID
  589.         CSmilBasicRegion* pRegion = getRegionByID(pPlayToAssoc->m_playTo);
  590.         if (pRegion)
  591.         {
  592.             // We got a region by region id, so use that
  593.             retVal = addSiteForRendererByRegion(pPlayToAssoc, pSMILSourceInfo,
  594.                                                 pRenderer, bNoRegion, pRegion);
  595.         }
  596.         else
  597.         {
  598.             // We couldn't get a region by region id, so try
  599.             // and get regions by regionName
  600.             pRegion = getFirstRegionByName(pPlayToAssoc->m_playTo);
  601.             while (pRegion && SUCCEEDED(retVal))
  602.             {
  603.                 // We got a region by region id, so use that
  604.                 retVal = addSiteForRendererByRegion(pPlayToAssoc, pSMILSourceInfo,
  605.                                                     pRenderer, bNoRegion, pRegion);
  606.                 if (SUCCEEDED(retVal))
  607.                 {
  608.                     pRegion = getNextRegionByName(pPlayToAssoc->m_playTo);
  609.                 }
  610.             }
  611.         }
  612.     }
  613.     else
  614.     {
  615.         retVal = HXR_FAIL;
  616.     }
  617.     return retVal;
  618. }
  619. HX_RESULT CSmilDocumentRenderer::addSiteForRendererByRegion(SMILPlayToAssoc*  pPlayToAssoc,
  620.                                                             SMILSourceInfo*   pSMILSourceInfo,
  621.                                                             IHXRenderer*     pRenderer,
  622.                                                             BOOL              bNoRegion,
  623.                                                             CSmilBasicRegion* pRegion)
  624. {
  625.     HX_RESULT retVal = HXR_OK;
  626.     if(pPlayToAssoc && pSMILSourceInfo &&
  627.        pRenderer    && pRegion && pRegion->m_pSite &&
  628.        m_pSiteMgr)
  629.     {
  630.         // First create a child of the region site
  631.         IHXSite* pRendererSite = NULL;
  632.         retVal = pRegion->m_pSite->CreateChild(pRendererSite);
  633.         if (SUCCEEDED(retVal))
  634.         {
  635.             // Now decide if we need to show the renderer site
  636.             if(pSMILSourceInfo->m_ulDelay > 0)
  637.             {
  638.                 // show site after m_ulDelay
  639.                 showSite(pRendererSite, FALSE);
  640.             }
  641.             else 
  642.             {
  643.                 // show it now, don't wait for first time sync
  644.                 // unless there is a begin transition, this prevents
  645.                 // the site from being shown and then clipped back.
  646.                 if (pPlayToAssoc->m_beginTransition.GetLength() == 0)
  647.                 {
  648.                     // There is no transition, so show everything
  649.                     showSite(pRegion->m_pSite, TRUE);
  650.                     showSite(pRendererSite, TRUE);
  651.                 }
  652.                 else
  653.                 {
  654.                     // There IS a transition, so make the
  655.                     // renderer site invisible. This should stop the
  656.                     // flashing we see at the beginning of 
  657.                     // crossfades.
  658.                     showSite(pRendererSite, FALSE);
  659.                 }
  660.             }
  661.             // Put this site into this region's list
  662.             // of child renderer sites
  663.             pRegion->addRendererSiteChild(pRendererSite);
  664.             // Add to the media id to site map
  665.             addRendererSiteToMap((const char*) pPlayToAssoc->m_id,
  666.                                  pRendererSite);
  667.             // Now create a site watcher for this renderer site
  668.             CSmilSiteWatcher* pRendererWatch = new CSmilSiteWatcher(this,
  669.                                                                     pRegion->m_region,
  670.                                                                     TRUE,
  671.                                                                     pPlayToAssoc->m_id);
  672.             if (pRendererWatch)
  673.             {
  674.                 // AddRef the watcher
  675.                 pRendererWatch->AddRef();
  676.                 // Get the top-level box
  677.                 CSmilBasicBox* pTopBox = getTopLevelBox(pRegion);
  678.                 if (pTopBox &&
  679.                     pTopBox->m_eResizeBehavior == ResizeZoom &&
  680.                     !m_bDoNotZoom)
  681.                 {
  682.                     // Initialize the watcher with the current zoom factor. This
  683.                     // is important if the player STARTS up in some other zoom
  684.                     // mode besides original size.
  685.                     pRendererWatch->SetZoomScaleFactors(pRegion->m_dZoomScaleFactorX,
  686.                                                         pRegion->m_dZoomScaleFactorY);
  687.                     // Set the resize behavior
  688.                     pRendererWatch->SetResizeBehavior(pTopBox->m_eResizeBehavior);
  689.                 }
  690.                 // Attach the watcher to the renderer site
  691.                 retVal = pRendererSite->AttachWatcher(pRendererWatch);
  692.                 if (SUCCEEDED(retVal))
  693.                 {
  694.                     // Create the site watcher map if necessary
  695.                     if (!m_pSiteWatcherMap)
  696.                     {
  697.                         m_pSiteWatcherMap = new CHXMapPtrToPtr();
  698.                     }
  699.                     if (m_pSiteWatcherMap)
  700.                     {
  701.                         // Add the site watcher to the site watcher map
  702.                         m_pSiteWatcherMap->SetAt((void*) pRendererSite,
  703.                                                  (void*) pRendererWatch);
  704.                         // Add to the media id to site watcher map
  705.                         addRendererSiteWatcherToMap((const char*) pPlayToAssoc->m_id,
  706.                                                     pRendererWatch);
  707.                         // /We need to set the "sensitivity" of the renderer
  708.                         // site (see SMIL 2.0 Interop Media test #3.1):
  709.                         if (pPlayToAssoc->m_id.GetLength() > 0  && m_pSmilParser)
  710.                         {
  711.                             CSmilElement* pElement = m_pSmilParser->findElement(pPlayToAssoc->m_id);
  712.                             HX_ASSERT(pElement);
  713.                             ULONG32 ulSensitivityStrLen = 0;
  714.                             if (pElement &&
  715.                                 pElement->m_sensitivityToMouseEvents.GetLength() > 0)
  716.                             {
  717.                                 setSiteProperty(pRendererSite,
  718.                                                 "sensitivity",
  719.                                                 (const char*) pElement->m_sensitivityToMouseEvents);
  720.                             }
  721.                         }
  722.                         // Set "channel" in the site's properties
  723.                         retVal = setSiteProperty(pRendererSite,
  724.                                                  "channel",
  725.                                                  pSMILSourceInfo->m_childTunerName);
  726.                         if (SUCCEEDED(retVal))
  727.                         {
  728. //                            setSiteProperty(pRendererSite,
  729. //                                            "playto",
  730. //                                            pSMILSourceInfo->m_childTunerName);
  731.                             // Add the site to the site manager
  732.                             retVal = m_pSiteMgr->AddSite(pRendererSite);
  733.                             if (SUCCEEDED(retVal))
  734.                             {
  735.                                 // Check the showBackground property on the region. If it is
  736.                                 // "always", then go ahead and show the site. If not, we'll
  737.                                 // hide it and let the show event show it
  738.                                 if (pRegion->m_pSmilRegion &&
  739.                                     pRegion->m_pSmilRegion->m_eShowBackground == ShowBackgroundWhenActive)
  740.                                 {
  741.                                     // showBackground is "whenActive", so we hide
  742.                                     // the site.
  743.                                     showSite(pRegion->m_pSite, FALSE);
  744.                                 }
  745.                                 else
  746.                                 {
  747.                                     // showBackground is "always", so we force the
  748.                                     // site to be shown
  749.                                     showSite(pRegion->m_pSite, TRUE);
  750.                                 }
  751.                                 // in any case, stick the event on the list...
  752.                                 UINT32 ulShowTime = pSMILSourceInfo->m_ulDelay;
  753.                                 CSmilShowSiteEvent* pShowEvent = 
  754.                                     new CSmilShowSiteEvent(pPlayToAssoc->m_uGroupIndex,
  755.                                                            ulShowTime,
  756.                                                            pRendererSite,
  757.                                                            pRegion->m_pSite,
  758.                                                            TRUE,
  759.                                                            FALSE,
  760.                                                            this,
  761.                                                            pPlayToAssoc->m_id,
  762.                                                            pRegion->m_region,
  763.                                                            pRegion->m_eShowBackground);
  764.                                 insertEvent(pShowEvent);
  765.                                 // Compute the time at which to remove the element. Here
  766.                                 // we take fill behavior into account.
  767.                                 UINT32 ulRemoveTime = 0;
  768.                                 HX_RESULT rv = m_pSmilParser->computeRemoveTime((const char*) pPlayToAssoc->m_id,
  769.                                                                                 ulRemoveTime);
  770.                                 if (FAILED(rv))
  771.                                 {
  772.                                     // We couldn't currently compute the remove
  773.                                     // time, so we set it way out, assuming it will
  774.                                     // get pulled back later
  775.                                     ulRemoveTime = WAY_IN_THE_FUTURE;
  776.                                 }
  777.                                 // Get the fill behavior for this media
  778.                                 FillType eFill = getMediaFillBehavior((const char*) pPlayToAssoc->m_id);
  779.                                 BOOL bIgnorHide = FALSE;
  780.                                 SMILGroupInfo* pGroupInfo = 0;
  781.                                 if (m_pGroupInfoMap &&
  782.                                     m_pGroupInfoMap->Lookup(pPlayToAssoc->m_uGroupIndex, 
  783.                                     (void*&)pGroupInfo))
  784.                                 {
  785.                                     if (pGroupInfo->m_bDurationSet)
  786.                                     {
  787.                                         if (pGroupInfo->m_ulDuration == ulRemoveTime &&
  788.                                             eFill                    != FillRemove)
  789.                                         {
  790.                                             bIgnorHide = TRUE;
  791.                                         }
  792.                                     }
  793.                                 }
  794.     
  795.                                 // XXXMEH - we will go ahead and schedule the hide
  796.                                 // for after the duration IF we know what the duration is.
  797.                                 // This would essentially be fill="remove" behavior. Later,
  798.                                 // when our parent duration gets updated in handleFillTimeUpdate()
  799.                                 // we will move this event forward or backwards if necessary.
  800.                                 // XXXMEH - we should also check our parent's duration here.
  801.                                 // If the parent has an explicit dur, then it will already be
  802.                                 // resolved and may cut off the child.
  803.                                 if (!pPlayToAssoc->m_bLiveSource)
  804.                                 {
  805.                                     CSmilShowSiteEvent* pHideEvent = 
  806.                                         new CSmilShowSiteEvent(pPlayToAssoc->m_uGroupIndex,
  807.                                                                ulRemoveTime, 
  808.                                                                pRendererSite,
  809.                                                                pRegion->m_pSite,
  810.                                                                FALSE,
  811.                                                                bIgnorHide,
  812.                                                                this,
  813.                                                                pPlayToAssoc->m_id,
  814.                                                                pRegion->m_region,
  815.                                                                pRegion->m_eShowBackground);
  816.                                     insertEvent(pHideEvent);
  817.                                     // Set the event time into the element
  818.                                     setElementRemoveTime(pPlayToAssoc->m_id, ulRemoveTime);
  819.                                 }
  820.                                 SMILSiteInfo* pSiteInfo     = new SMILSiteInfo;
  821.                                 pSiteInfo->m_pRendererSite  = pRendererSite;
  822.                                 pSiteInfo->m_pRegionSite    = pRegion->m_pSite;
  823.                                 pSiteInfo->m_uGroupIndex    = pPlayToAssoc->m_uGroupIndex;
  824.                                 pSiteInfo->m_ulDelay        = pSMILSourceInfo->m_ulDelay;
  825.                                 pSiteInfo->m_ulDuration     = pSMILSourceInfo->m_ulDuration +
  826.                                                               pSMILSourceInfo->m_ulDelay;
  827. pSiteInfo->m_ulResumeTime   = 0;
  828.                                 pSiteInfo->m_bRemoveSite    = pPlayToAssoc->m_bRemoveSite;
  829.                                 pSiteInfo->m_bNoRegion      = bNoRegion;
  830.                                 pSiteInfo->m_regionID       = pPlayToAssoc->m_playTo;
  831.                                 pSiteInfo->m_pRenderer      = pRenderer;
  832.                                 pSiteInfo->m_ulLexicalOrder = pPlayToAssoc->m_ulLexicalOrder;
  833.                                 pSiteInfo->m_MediaID        = pPlayToAssoc->m_id;
  834.                                 pSiteInfo->m_lZIndex        = 0;
  835.                                 // Look up any z-index override on the media element
  836.                                 CSmilSource* pSrc = getSource(pPlayToAssoc->m_id);
  837.                                 if (pSrc &&
  838.                                     pSrc->m_eZIndexType != CSS2TypeAuto)
  839.                                 {
  840.                                     pSiteInfo->m_lZIndex = pSrc->m_lZIndex;
  841.                                 }
  842.                                 pPlayToAssoc->m_pSiteInfoList->AddTail(pSiteInfo);
  843.                                 insertSiteInfo(pSiteInfo);
  844.     
  845.                                 m_pSiteInfoByRendererMap->SetAt(pRenderer, pSiteInfo);
  846.     
  847.                                 // If the rn:backgroundOpacity or rn:mediaOpacity attributes
  848.                                 // are set, then set those properties into the site.
  849.                                 if (pSrc)
  850.                                 {
  851.                                     if (pSrc->m_bBackgroundOpacitySpecified)
  852.                                     {
  853.                                         setSitePropertyULONG32(pRendererSite,
  854.                                                                "backgroundOpacity",
  855.                                                                pSrc->m_ulBackgroundOpacity);
  856.                                     }
  857.                                     if (pSrc->m_bMediaOpacitySpecified)
  858.                                     {
  859.                                         setSitePropertyULONG32(pRendererSite,
  860.                                                                "mediaOpacity",
  861.                                                                pSrc->m_ulMediaOpacity);
  862.                                     }
  863.                                 }
  864. #if defined(HELIX_FEATURE_SMIL2_TRANSITIONS)
  865.                                 // schedule a start transition if there is one...
  866.                                 if (pPlayToAssoc->m_beginTransition.GetLength() > 0)
  867.                                 {
  868.                                     // Create a begin transition event
  869.                                     CSmilTransitionEvent* pTransEvent = new CSmilTransitionEvent(pSMILSourceInfo->m_ulDelay,
  870.                                                                                                  pPlayToAssoc,
  871.                                                                                                  pSiteInfo,
  872.                                                                                                  TRUE,
  873.                                                                                                  this);
  874.                                     // Insert this event in the event queue
  875.                                     insertEvent(pTransEvent);
  876.                                 }
  877.                                 // schedule an end transition if there is one.
  878.                                 if (pPlayToAssoc->m_endTransition.GetLength() > 0 &&
  879.                                     !pPlayToAssoc->m_bLiveSource)
  880.                                 {
  881.                                     CSmilTransitionInfo* pTInfo = getTransition(pPlayToAssoc->m_endTransition);
  882.                                     if (pTInfo)
  883.                                     {
  884.                                         CSmilTransitionEvent* pTransEvent =
  885.                                             new CSmilTransitionEvent(pSMILSourceInfo->m_ulDelay +
  886.                                                                      pSMILSourceInfo->m_ulDuration -
  887.                                                                      pTInfo->m_pTrans->m_ulDuration,
  888.                                                                      pPlayToAssoc,
  889.                                                                      pSiteInfo,
  890.                                                                      FALSE,
  891.                                                                      this);
  892.                                         insertEvent(pTransEvent);
  893.                                     }
  894.                                 }
  895. #endif /* #if defined(HELIX_FEATURE_SMIL2_TRANSITIONS) */
  896.                             }
  897.                         }
  898.                     }
  899.                     else
  900.                     {
  901.                         retVal = HXR_OUTOFMEMORY;
  902.                     }
  903.                 }
  904.             }
  905.             else
  906.             {
  907.                 retVal = HXR_FAIL;
  908.             }
  909.         }
  910.     }
  911.     else
  912.     {
  913.         retVal = HXR_FAIL;
  914.     }
  915.     return retVal;
  916. }
  917. HX_RESULT CSmilDocumentRenderer::setSiteProperty(IHXSite*   pSite,
  918.                                                  const char* pszKey,
  919.                                                  const char* pszValue)
  920. {
  921.     MLOG_LAYOUT(m_pErrorMessages,
  922.                 "setSiteProperty(0x%08x,%s,%s) m_ulCurrentTime=%lu tick=%lun",
  923.                 pSite, pszKey, pszValue, m_ulCurrentTime, HX_GET_BETTERTICKCOUNT());
  924.     HX_RESULT retVal = HXR_FAIL;
  925.     if (pSite && m_pContext && pszKey && pszValue)
  926.     {
  927.         IHXValues* pValues = NULL;
  928.         pSite->QueryInterface(IID_IHXValues, (void**) &pValues);
  929.         if (pValues)
  930.         {
  931.             IHXCommonClassFactory* pFactory = NULL;
  932.             m_pContext->QueryInterface(IID_IHXCommonClassFactory, (void**) &pFactory);
  933.             if (pFactory)
  934.             {
  935.                 IHXBuffer* pBuffer = NULL;
  936.                 pFactory->CreateInstance(CLSID_IHXBuffer, (void**) &pBuffer);
  937.                 if (pBuffer)
  938.                 {
  939.                     retVal = pBuffer->Set((const UCHAR*) pszValue,
  940.                                           strlen(pszValue) + 1);
  941.                     if (SUCCEEDED(retVal))
  942.                     {
  943.                         retVal = pValues->SetPropertyCString(pszKey,
  944.                                                              pBuffer);
  945.                     }
  946.                 }
  947.                 HX_RELEASE(pBuffer);
  948.             }
  949.             HX_RELEASE(pFactory);
  950.         }
  951.         HX_RELEASE(pValues);
  952.     }
  953.     return retVal;
  954. }
  955. HX_RESULT CSmilDocumentRenderer::setSitePropertyULONG32(IHXSite*   pSite,
  956.                                                         const char* pszKey,
  957.                                                         UINT32      ulValue)
  958. {
  959.     MLOG_LAYOUT(m_pErrorMessages,
  960.                 "setSitePropertyULONG32(0x%08x,%s,%lu) m_ulCurrentTime=%lu tick=%lun",
  961.                 pSite, pszKey, ulValue, m_ulCurrentTime, HX_GET_BETTERTICKCOUNT());
  962.     HX_RESULT retVal = HXR_FAIL;
  963.     if (pSite && m_pContext && pszKey)
  964.     {
  965.         IHXValues* pValues = NULL;
  966.         retVal = pSite->QueryInterface(IID_IHXValues, (void**) &pValues);
  967.         if (SUCCEEDED(retVal))
  968.         {
  969.             retVal = pValues->SetPropertyULONG32(pszKey, ulValue);
  970.         }
  971.         HX_RELEASE(pValues);
  972.     }
  973.     return retVal;
  974. }
  975. HX_RESULT CSmilDocumentRenderer::getSiteProperty(IHXSite*        pSite,
  976.                                                  const char*      pszKey,
  977.                                                  REF(IHXBuffer*) rpValueStr)
  978. {
  979.     HX_RESULT retVal = HXR_FAIL;
  980.     if (pSite && m_pContext && pszKey)
  981.     {
  982.         IHXValues* pValues = NULL;
  983.         pSite->QueryInterface(IID_IHXValues, (void**) &pValues);
  984.         if (pValues)
  985.         {
  986.             HX_RELEASE(rpValueStr);
  987.             retVal = pValues->GetPropertyCString(pszKey, rpValueStr);
  988.         }
  989.         HX_RELEASE(pValues);
  990.     }
  991.     return retVal;
  992. }
  993. HX_RESULT
  994. CSmilDocumentRenderer::insertIntoZOrderList(CHXSimpleList* pList, 
  995.     SMILSiteInfo* pInfo)
  996. {
  997.     LISTPOSITION lPos = pList->GetHeadPosition();
  998.     LISTPOSITION lPrev = lPos;
  999.     // /Helps fix PR 81510 (& duplicate PR 83796): use resume time instead
  1000.     // of delay if it's more recent than delay meaning it got paused and
  1001.     // needs to come to the front when it resumes (in an excl):
  1002.     ULONG32 ulNewSiteRelevantDelay = pInfo->m_ulDelay;
  1003.     if (pInfo->m_ulResumeTime > ulNewSiteRelevantDelay)
  1004.     {
  1005. ulNewSiteRelevantDelay = pInfo->m_ulResumeTime;
  1006.     }
  1007.     BOOL bInserted = FALSE;
  1008.     while(lPos)
  1009.     {
  1010. SMILSiteInfo* pThisInfo = (SMILSiteInfo*)pList->GetNext(lPos);
  1011. // /Helps fix PR 81510 (& duplicate PR 83796) by using resume time
  1012. // in case it got paused and needs to come to the front when it
  1013. // resumes in an excl:
  1014. ULONG32 ulThisSiteRelevantDelay = pThisInfo->m_ulDelay;
  1015. if (pThisInfo->m_ulResumeTime > ulThisSiteRelevantDelay)
  1016. {
  1017.     ulThisSiteRelevantDelay = pThisInfo->m_ulResumeTime;
  1018. }
  1019. if (pThisInfo->m_uGroupIndex != pInfo->m_uGroupIndex)
  1020. {
  1021.     if (pThisInfo->m_uGroupIndex > pInfo->m_uGroupIndex)
  1022.     {
  1023. pList->InsertBefore(lPrev, pInfo);
  1024. bInserted = TRUE;
  1025. break;
  1026.     }
  1027. }
  1028. else if (ulThisSiteRelevantDelay == ulNewSiteRelevantDelay &&
  1029.     pThisInfo->m_ulLexicalOrder > pInfo->m_ulLexicalOrder)
  1030. {
  1031.     pList->InsertBefore(lPrev, pInfo);
  1032.     bInserted = TRUE;
  1033.     break;
  1034. }
  1035. else if (ulThisSiteRelevantDelay > ulNewSiteRelevantDelay)
  1036. {
  1037.     pList->InsertBefore(lPrev, pInfo);
  1038.     bInserted = TRUE;
  1039.     break;
  1040. }
  1041. lPrev = lPos;
  1042.     }
  1043.     if(!bInserted)
  1044.     {
  1045. // not inserted, stick it on the end of the list
  1046. pList->AddTail(pInfo);
  1047.     }
  1048.     return HXR_OK;
  1049. }
  1050. HX_RESULT CSmilDocumentRenderer::setRendererZOrder(SMILSiteInfo* pSiteInfo)
  1051. {
  1052.     HX_RESULT retVal = HXR_OK;
  1053.     if (pSiteInfo && !pSiteInfo->m_bNoRegion && m_pSiteInfoList)
  1054.     {
  1055.         if (getNumberOfChildSites(pSiteInfo->m_pRegionSite) > 1)
  1056.         {
  1057.             // Create a list of all sites that have the same
  1058.             // region as us.
  1059.             CHXSimpleList commonRegionList;
  1060.             LISTPOSITION pos = m_pSiteInfoList->GetHeadPosition();
  1061.             while (pos)
  1062.             {
  1063.                 SMILSiteInfo* pInfo = (SMILSiteInfo*) m_pSiteInfoList->GetNext(pos);
  1064.                 if (pInfo && pInfo->m_pRegionSite == pSiteInfo->m_pRegionSite)
  1065.                 {
  1066.                     insertIntoZOrderList(&commonRegionList, pInfo);
  1067.                 }
  1068.             }
  1069.             // Run through and set the z-index in increasing order
  1070.             INT32 lOrder = 0;
  1071.             pos          = commonRegionList.GetHeadPosition();
  1072.             while (pos)
  1073.             {
  1074.                 SMILSiteInfo* pInfo = (SMILSiteInfo*) commonRegionList.GetNext(pos);
  1075.                 if (pInfo)
  1076.                 {
  1077.                     setSiteZIndex(pInfo->m_pRendererSite, lOrder++);
  1078.                 }
  1079.             }
  1080.         }
  1081.     }
  1082.     return retVal;
  1083. }
  1084. /*
  1085.  * IHXGroupSink methods
  1086.  */
  1087. STDMETHODIMP
  1088. CSmilDocumentRenderer::GroupAdded(UINT16 uGroupIndex,
  1089. IHXGroup* pGroup)
  1090. {
  1091.     if(!m_pGroupInfoMap)
  1092.     {
  1093. m_pGroupInfoMap = new CHXMapLongToObj;
  1094.     }
  1095.     // save group info
  1096.     SMILGroupInfo* pGroupInfo = 0;
  1097.     if(!m_pGroupInfoMap->Lookup(uGroupIndex, (void*&)pGroupInfo))
  1098.     {
  1099. IHXPlayer* pPlayer = m_pParent->getPlayer();
  1100. IHXGroupManager* pMgr = 0;
  1101. UINT32 ulTotalTracks = 0;
  1102. UINT32 ulDuration = 0;
  1103. if(HXR_OK == pPlayer->QueryInterface(IID_IHXGroupManager, 
  1104.      (void**)&pMgr))
  1105. {
  1106.     IHXGroup* pGroup = NULL;
  1107.     IHXGroup2* pGroup2 = NULL;
  1108.     if (HXR_OK == pMgr->GetGroup(uGroupIndex, pGroup) &&
  1109. HXR_OK == pGroup->QueryInterface(IID_IHXGroup2, (void**)&pGroup2))
  1110.     {
  1111. IHXValues* pGroupProperties = NULL;
  1112. pGroup2->GetPersistentComponentProperties(m_ulPersistentComponentID,
  1113.   pGroupProperties);
  1114. if(pGroupProperties)
  1115. {
  1116.     pGroupProperties->GetPropertyULONG32("total_tracks", 
  1117. ulTotalTracks);
  1118.     pGroupProperties->GetPropertyULONG32("duration", 
  1119. ulDuration);
  1120. }
  1121. HX_RELEASE(pGroupProperties);
  1122.     }
  1123.     HX_RELEASE(pGroup2);
  1124.     HX_RELEASE(pGroup);
  1125. }
  1126. HX_RELEASE(pMgr);
  1127. pGroupInfo = new SMILGroupInfo;
  1128. pGroupInfo->m_nTracks = (int)ulTotalTracks;
  1129. pGroupInfo->m_nTracksAdded = 0;
  1130. pGroupInfo->m_nTrackDurationsSet = 0;
  1131. pGroupInfo->m_ulDuration = ulDuration;
  1132. // if we have an explicit duration on the source, say that
  1133. // we have allready got all the track durations set
  1134. if (pGroupInfo->m_ulDuration)
  1135. {
  1136.     pGroupInfo->m_bDurationSet = TRUE;
  1137.     pGroupInfo->m_ulDuration += m_pSmilParser->m_ulPersistentComponentDelay;
  1138.     PersistentDurationSet(pGroupInfo->m_ulDuration,
  1139.   m_pSmilParser->m_ulPersistentComponentDelay,
  1140.   FALSE);
  1141. }
  1142. else
  1143. {
  1144.     pGroupInfo->m_bDurationSet = FALSE;
  1145. }
  1146. (*m_pGroupInfoMap)[uGroupIndex] = pGroupInfo;
  1147.     }
  1148.     else
  1149.     {
  1150. pGroupInfo->m_nTracksAdded++;
  1151.     }
  1152.     return HXR_OK;
  1153. }
  1154. STDMETHODIMP
  1155. CSmilDocumentRenderer::GroupRemoved(UINT16 uGroupIndex,
  1156.  IHXGroup* pGroup)
  1157. {
  1158.     return HXR_OK;
  1159. }
  1160. STDMETHODIMP
  1161. CSmilDocumentRenderer::AllGroupsRemoved()
  1162. {
  1163.     return HXR_NOTIMPL;
  1164. }
  1165. STDMETHODIMP
  1166. CSmilDocumentRenderer::TrackAdded(UINT16 uGroupIndex,
  1167.        UINT16 uTrackIndex,
  1168.        IHXValues* pTrack)
  1169. {
  1170.     MLOG_SRC(m_pErrorMessages,"TrackAdded(%u,%u,0x%08x)n",
  1171.              uGroupIndex, uTrackIndex, pTrack);
  1172.     if(pTrack)
  1173.     {
  1174. IHXBuffer* pBuf = 0;
  1175. const char* pID = 0;
  1176. const char* pRepeatID = 0;
  1177. const char* pRegionName = 0;
  1178. const char* pBeginTransition = NULL;
  1179. const char* pEndTransition = NULL;
  1180. UINT32 ulDelay = 0;
  1181. if(HXR_OK == pTrack->GetPropertyCString("id", pBuf))
  1182. {
  1183.     pID = (const char*)pBuf->GetBuffer();
  1184.     pBuf->Release();
  1185. }
  1186. if(HXR_OK == pTrack->GetPropertyCString("repeatid", pBuf))
  1187. {
  1188.     pRepeatID = (const char*)pBuf->GetBuffer();
  1189.     pBuf->Release();
  1190. }
  1191. if(HXR_OK == pTrack->GetPropertyCString("region", pBuf))
  1192. {
  1193.     pRegionName = (const char*)pBuf->GetBuffer();
  1194.     pBuf->Release();
  1195. }
  1196. if(HXR_OK == pTrack->GetPropertyCString("beginTransition", pBuf))
  1197. {
  1198.     pBeginTransition = (const char*)pBuf->GetBuffer();
  1199.     pBuf->Release();
  1200. }
  1201. if(HXR_OK == pTrack->GetPropertyCString("endTransition", pBuf))
  1202. {
  1203.     pEndTransition = (const char*)pBuf->GetBuffer();
  1204.     pBuf->Release();
  1205. }
  1206.         // If this is an external media marker file, then
  1207.         // save the group and track index
  1208.         BOOL bXMMSource = FALSE;
  1209. if(HXR_OK == pTrack->GetPropertyCString("ExternalMarkerFile", pBuf))
  1210. {
  1211.             bXMMSource = TRUE;
  1212.             pBuf->Release();
  1213.             pTrack->GetPropertyCString("url", pBuf);
  1214.             CExternalMediaMarkerInfo* pInfo = getExternalMediaMarkerInfo((const char*) pBuf->GetBuffer());
  1215.             if (pInfo)
  1216.             {
  1217.                 pInfo->m_usGroupIndex = uGroupIndex;
  1218.                 pInfo->m_usTrackIndex = uTrackIndex;
  1219.             }
  1220.     pBuf->Release();
  1221. }
  1222. UINT32 num = 0;
  1223. pTrack->GetPropertyULONG32("lexicalNum", num);
  1224. if(HXR_OK == pTrack->GetPropertyCString("playto", pBuf))
  1225. {
  1226.     const char* pPlayTo = (const char*)pBuf->GetBuffer();
  1227.     setPlayToAssoc(uGroupIndex, uTrackIndex, pID, pRepeatID, pPlayTo, pRegionName, 
  1228. pBeginTransition, pEndTransition, num, bXMMSource);
  1229.     pBuf->Release();
  1230. }
  1231. else // non-windowed renderer
  1232. {
  1233.     setPlayToAssoc(uGroupIndex, uTrackIndex, pID, pRepeatID, 0, pRegionName, 
  1234. pBeginTransition, pEndTransition, num, bXMMSource);
  1235. }
  1236. SMILPlayToAssoc* pAssoc = getPlayToAssoc(uGroupIndex, uTrackIndex);
  1237. if(pAssoc)
  1238. {
  1239.             if (m_pSmilParser)
  1240.             {
  1241.                 CSmilElement* pElement = m_pSmilParser->findElement(pID);
  1242.                 if (pElement)
  1243.                 {
  1244.                     if (pElement->m_eActualFill == FillFreeze ||
  1245.                         pElement->m_eActualFill == FillHold   ||
  1246.                         pElement->m_eErase      == EraseNever)
  1247.                     {
  1248.                         pAssoc->m_bRemoveSite = FALSE;
  1249.                     }
  1250.                 }
  1251.                 
  1252.             }
  1253. }
  1254. SMILGroupInfo* pGroupInfo = 0;
  1255. if(m_pGroupInfoMap->Lookup(uGroupIndex, (void*&)pGroupInfo))
  1256. {
  1257.     pGroupInfo->m_nTracksAdded++;
  1258. }
  1259.     }
  1260.     return HXR_OK;
  1261. }
  1262. STDMETHODIMP
  1263. CSmilDocumentRenderer::TrackRemoved(UINT16 uGroupIndex,
  1264.     UINT16 uTrackIndex,
  1265.     IHXValues* pTrack)
  1266. {
  1267.     HX_RESULT hr = HXR_OK;
  1268.     UINT32 ulDurationPlayed = 0;
  1269.     SMILPlayToAssoc* pPlayToAssoc = getPlayToAssoc(uGroupIndex, uTrackIndex);
  1270.     if (!pPlayToAssoc)
  1271.     {
  1272. hr = HXR_UNEXPECTED;
  1273. goto cleanup;
  1274.     }
  1275.     HX_ASSERT(pPlayToAssoc->m_bRemovePending);
  1276.     // caculate the actual duration this track has been played
  1277.     if (uGroupIndex == m_uCurrentGroupIndex)
  1278.     {
  1279. if (m_ulCurrentTime > pPlayToAssoc->m_ulDelay)
  1280. {
  1281.     ulDurationPlayed = m_ulCurrentTime - pPlayToAssoc->m_ulDelay;
  1282. }
  1283.     }
  1284.     hr = m_pSmilParser->trackRemoved(pPlayToAssoc->m_id, ulDurationPlayed);
  1285.     removeTracksPlayToAssoc(uGroupIndex, uTrackIndex);
  1286.     // process the updated sources 
  1287.     if (HXR_OK == hr)
  1288.     {
  1289. hr = handleElements();
  1290.     }
  1291. cleanup:
  1292.     return hr;
  1293. }
  1294. STDMETHODIMP
  1295. CSmilDocumentRenderer::TrackStarted(UINT16 uGroupIndex,
  1296.  UINT16 uTrackIndex,
  1297.  IHXValues* pTrack)
  1298. {
  1299.     if(m_bSettingFragment)
  1300.     {
  1301. // find out if all tracks for this group have been
  1302. // added, then go ahead and seek
  1303. UINT16 uFragmentGroup = m_pSmilParser->getFragmentGroup(m_pFragment);
  1304. if(uFragmentGroup == uGroupIndex)
  1305. {
  1306.     SMILGroupInfo* pGroupInfo = 0;
  1307.     m_nFragmentTracks++;
  1308.     if(m_pGroupInfoMap->Lookup(uFragmentGroup, (void*&)pGroupInfo))
  1309.     {
  1310. if(pGroupInfo->m_nTracks == m_nFragmentTracks)
  1311. {
  1312.     // /Set offset here, and then call seek on the player
  1313.     // in this's OnBegin() method which is when the player
  1314.     // is fully initialized and ready to be seeked:
  1315.                     BOOL bTmp = m_bFragFoundAndResolved;
  1316.     m_ulFragmentTimeOffset =
  1317. m_pSmilParser->getFragmentOffset(m_pFragment,
  1318. bTmp /*<--Passed by reference.*/);
  1319.                     m_bFragFoundAndResolved = bTmp;
  1320.     m_bSettingFragment = FALSE;
  1321. }
  1322.     }
  1323. }
  1324.     }
  1325.     // /Fire off the "beginEvent" event for the associated element:
  1326.     HX_RESULT rslt = HXR_OK;
  1327.     SMILPlayToAssoc* pPlayToAssoc =
  1328.     getPlayToAssoc(uGroupIndex, uTrackIndex);
  1329.     if (pPlayToAssoc)
  1330.     {
  1331. // /Fixes PR 79300: need to set m_bIsDeferredInExcl to FALSE now that
  1332. // it has started playing, otherwise siblings will calculate their
  1333. // post-deferred begins as indefinite:
  1334. CSmilElement* pThisElement = m_pSmilParser->findElement(
  1335. pPlayToAssoc->m_id);
  1336. if (pThisElement  &&  pThisElement->m_bIsDeferredInExcl)
  1337. {
  1338.     pThisElement->m_bIsDeferredInExcl = FALSE;
  1339.     pThisElement->m_ulTimeDeferralOccurred = (UINT32)-1;
  1340.     // /Fixes PR 86103: we need to force re-compute of end time hide
  1341.     // event since the end time, during the defer period, has been
  1342.     // treated as indefinite|unresolved:
  1343.     pThisElement->checkElementFillBehavior();
  1344. }
  1345. rslt = m_pSmilParser->tryToResolveBeginEndEvents("beginEvent",
  1346. (const char*)pPlayToAssoc->m_id,
  1347. // /XXXEH- hack until core calls us at time when track media
  1348. // actually starts playing (which is at track's delay, not
  1349. // at group's begin); the following hack at least gets the
  1350. // right ballpark, but subsequent real-time adjustments to
  1351. // this track's begin time (like if it doesn't end up playing
  1352. // at all) will result in incorrect playback in some cases:
  1353. pPlayToAssoc->m_ulDelay +// /XXXEH <-hack:remove w/fixed core
  1354. // /XXXEH- ...and use m_ulCurrentTime instead of 0, below:
  1355. 0 /*m_ulCurrentTime*/);
  1356. if SUCCEEDED(rslt)
  1357. {
  1358.     handleElements();
  1359. }
  1360.     }
  1361.     return rslt;
  1362. }
  1363. STDMETHODIMP
  1364. CSmilDocumentRenderer::TrackStopped(UINT16 uGroupIndex,
  1365.  UINT16 uTrackIndex,
  1366.  IHXValues* pTrack)
  1367. {
  1368.     HX_RESULT rslt = HXR_OK;
  1369.     SMILPlayToAssoc* pPlayToAssoc =
  1370.     getPlayToAssoc(uGroupIndex, uTrackIndex);
  1371.     if (pPlayToAssoc)
  1372.     {
  1373. rslt = m_pSmilParser->tryToResolveBeginEndEvents("endEvent",
  1374. (const char*)pPlayToAssoc->m_id, m_ulCurrentTime);
  1375. // /For any paused elements in an excl awaiting this element
  1376. // finishing, we need to call this so they know they can resume:
  1377. HX_RESULT rsltResume =
  1378. m_pSmilParser->tryToResolveBeginEndEvents("resumeEvent",
  1379. (const char*)pPlayToAssoc->m_id, m_ulCurrentTime);
  1380. HX_ASSERT(HXR_OK == rsltResume);
  1381. // /Helps fix PR 85885: for any deferred elements that were deferred
  1382. // while another was already deferred in an excl awaiting this element
  1383. // finishing, we need to call this so they know they can begin:
  1384. HX_RESULT rsltUndefer =
  1385. m_pSmilParser->tryToResolveBeginEndEvents("undeferEvent",
  1386. (const char*)pPlayToAssoc->m_id, m_ulCurrentTime);
  1387. HX_ASSERT(HXR_OK == rsltUndefer);
  1388. // /This "fixes" PR 69639 (although I have no idea why it broke in
  1389. // the first place; perhaps the core used to call TrackRemoved() and
  1390. // now it doesn't?  If so, that would explain it.   If element gets
  1391. // played all the way through, then gets re-started, a new track is
  1392. // created and thus a new track# is assigned, so we need to remove
  1393. // the playToAssoc so pausing of the track happens on the correct
  1394. // one (via element-id-based lookup of track index):
  1395. // /Setting this flag instead of removing track's playtoAssoc fixes
  1396. // PR 69975:
  1397. pPlayToAssoc->m_bTrackStopped = TRUE;
  1398. if SUCCEEDED(rslt)
  1399. {
  1400.     if (!m_pHandlePendingSchedulingCallback)
  1401.       {
  1402. m_pHandlePendingSchedulingCallback = new HandlePendingSchedulingCallback;
  1403. m_pHandlePendingSchedulingCallback->m_pSmilDocumentRenderer = this;
  1404. m_pHandlePendingSchedulingCallback->AddRef();
  1405.     }
  1406.     if (m_pHandlePendingSchedulingCallback->m_bIsCallbackPending)
  1407.     {
  1408. m_pScheduler->Remove(m_pHandlePendingSchedulingCallback->m_PendingHandle);
  1409.       }
  1410.         
  1411.     m_pHandlePendingSchedulingCallback->m_bIsCallbackPending = TRUE;
  1412.     m_pHandlePendingSchedulingCallback->m_PendingHandle = 
  1413.     m_pScheduler->RelativeEnter(m_pHandlePendingSchedulingCallback, 0);
  1414. }
  1415.     }
  1416.     return rslt;
  1417. }
  1418. STDMETHODIMP
  1419. CSmilDocumentRenderer::CurrentGroupSet(UINT16 uGroupIndex,
  1420.     IHXGroup* pGroup)
  1421. {
  1422.     INT16   uPrevGroupIndex = m_uCurrentGroupIndex;
  1423.     m_uCurrentGroupIndex = (INT16)uGroupIndex;
  1424.     m_ulCurrentTime = 0;
  1425.     if(uPrevGroupIndex != -1)
  1426.     {
  1427. closeOldRenderers(FALSE);
  1428. m_pSmilParser->resetTimeline();
  1429. removeGroupEvents(uPrevGroupIndex);
  1430. removeActiveTransitions();
  1431. #if defined(HELIX_FEATURE_SMIL2_ANIMATION)
  1432.         removeActiveAnimations();
  1433. #endif /* #if defined(HELIX_FEATURE_SMIL2_ANIMATION) */
  1434. removeGroupsPlayToAssoc(uPrevGroupIndex);
  1435. m_ulEventListPosition = 0;
  1436. if(m_pStatusMessage)
  1437. {
  1438.     m_pStatusMessage->SetStatus(NULL);
  1439. }
  1440. // make hide events for sites from the last Group
  1441. addOldRendererHideEvents(uGroupIndex);
  1442.     }
  1443. // XXXMEH - temp remove
  1444. #if 0
  1445.     // Schedule the animate events for this group if
  1446.     // the group index is not 0. If it is 0, then these
  1447.     // events have already been scheduled in handleAnimate()
  1448.     if (m_pAnimationMap && uGroupIndex != 0)
  1449.     {
  1450.         POSITION pos = m_pAnimationMap->GetStartPosition();
  1451.         while (pos)
  1452.         {
  1453.             const char* pszKey = NULL;
  1454.             void*       pVoid  = NULL;
  1455.             m_pAnimationMap->GetNextAssoc(pos, pszKey, pVoid);
  1456.             if (pszKey && pVoid)
  1457.             {
  1458.                 // Cast from the void*
  1459.                 CSmilAnimateElement* pAnimate = (CSmilAnimateElement*) pVoid;
  1460.                 // Is this animation element in the current group?
  1461.                 if (pAnimate->m_pNode &&
  1462.                     pAnimate->m_pNode->m_nGroup == uGroupIndex)
  1463.                 {
  1464.                     // We need to schedule an animate event
  1465.                     CSmilAnimateEvent* pEvent = new CSmilAnimateEvent(pAnimate->m_pNode->m_nGroup,
  1466.                                                                       pAnimate->m_ulDelay,
  1467.                                                                       FALSE,
  1468.                                                                       pAnimate,
  1469.                                                                       this,
  1470.                                                                       m_pSmilParser);
  1471.                     if (pEvent)
  1472.                     {
  1473.                         // Put the event only the timeline
  1474.                         insertEvent(pEvent);
  1475.                     }
  1476.                 }
  1477.             }
  1478.         }
  1479.     }
  1480. #endif
  1481.     return HXR_OK;
  1482. }
  1483. STDMETHODIMP
  1484. CSmilDocumentRenderer::PrefetchTrackAdded(UINT16 uGroupIndex,
  1485.   UINT16 uPrefetchTrackId,
  1486.   IHXValues* pTrack)
  1487. {
  1488.     return HXR_OK;
  1489. }
  1490. STDMETHODIMP
  1491. CSmilDocumentRenderer::PrefetchTrackRemoved(UINT16 uGroupIndex,
  1492.     UINT16 uPrefetchTrackId,
  1493.     IHXValues* pTrack)
  1494. {
  1495.     return HXR_OK;
  1496. }
  1497. STDMETHODIMP
  1498. CSmilDocumentRenderer::PrefetchTrackDone(UINT16     uGroupIndex,
  1499.       UINT16     uPrefetchTrackId,
  1500.  HX_RESULT  status)
  1501. {
  1502.     HX_RESULT rslt = HXR_OK;
  1503.     CHXString* pId;
  1504.     HX_ASSERT(m_pPrefetchTrackElementMap);
  1505.     if (m_pPrefetchTrackElementMap  &&
  1506.     m_pPrefetchTrackElementMap->Lookup(uPrefetchTrackId,
  1507.     (void*&)pId))
  1508.     {
  1509. // /This does nothing if duration is already a valid amount.
  1510. // Returns HXR_FAILED if resetDuration() is not called on the element.
  1511. HX_RESULT rsltOfDurationSetting =
  1512. m_pSmilParser->handlePrefetchFinished(*pId,
  1513. 0==m_ulCurrentTime? 100:m_ulCurrentTime);
  1514. if (SUCCEEDED(rsltOfDurationSetting))
  1515. {
  1516.     handleElements();
  1517. }
  1518. rslt = m_pSmilParser->tryToResolveBeginEndEvents("endEvent",
  1519. *pId, m_ulCurrentTime);
  1520. if SUCCEEDED(rslt)
  1521. {
  1522.     if (!m_pHandlePendingSchedulingCallback)
  1523.       {
  1524. m_pHandlePendingSchedulingCallback = new HandlePendingSchedulingCallback;
  1525. m_pHandlePendingSchedulingCallback->m_pSmilDocumentRenderer = this;
  1526. m_pHandlePendingSchedulingCallback->AddRef();
  1527.     }
  1528.     if (m_pHandlePendingSchedulingCallback->m_bIsCallbackPending)
  1529.     {
  1530. m_pScheduler->Remove(m_pHandlePendingSchedulingCallback->m_PendingHandle);
  1531.       }
  1532.         
  1533.     m_pHandlePendingSchedulingCallback->m_bIsCallbackPending = TRUE;
  1534.     m_pHandlePendingSchedulingCallback->m_PendingHandle = 
  1535.     m_pScheduler->RelativeEnter(m_pHandlePendingSchedulingCallback, 0);
  1536. }
  1537.     }
  1538.     
  1539.     return HXR_OK;
  1540. }
  1541. HX_RESULT
  1542. CSmilDocumentRenderer::addOldRendererHideEvents(UINT16 uGroupIndex)
  1543. {
  1544.     CHXSimpleList regions;
  1545.     if (m_pDelayedRendererCloseList)
  1546.     {
  1547. CHXSimpleList::Iterator i = m_pDelayedRendererCloseList->Begin();
  1548. for (;i != m_pDelayedRendererCloseList->End(); ++i)
  1549. {
  1550.     SMILDelayedRendererClose* pClose = (SMILDelayedRendererClose*)(*i);
  1551.     CSmilBasicRegion* pRegion = getRegionByID(pClose->m_pSiteInfo->m_regionID);
  1552.     regions.AddTail(pRegion);
  1553.     IHXSite* pRegionSite = NULL;
  1554.     if (pRegion->m_eBackgroundColorType == CSS2TypeTransparent)
  1555.     {
  1556. pRegionSite = pRegion->m_pSite;
  1557.     }
  1558.             CSmilShowSiteEvent* pHideEvent = 
  1559.                 new CSmilShowSiteEvent(uGroupIndex,
  1560.                                        0,
  1561.                                        pClose->m_pSiteInfo->m_pRendererSite,
  1562.                                        pRegionSite,
  1563.                                        FALSE);
  1564.     
  1565.     insertEvent(pHideEvent);
  1566.             // Set the event time into the element
  1567.             setElementRemoveTime(pHideEvent->getMediaID(), pHideEvent->m_ulEventTime);
  1568. }
  1569.     }
  1570.     
  1571.     // hide any "transparent" sites, that are not going to be hidden at 
  1572.     // the start of the next presentation.
  1573.     if(m_pRegionMap)
  1574.     {
  1575. CHXMapStringToOb::Iterator i = m_pRegionMap->Begin();
  1576. for(; i != m_pRegionMap->End(); ++i)
  1577. {
  1578.     CSmilBasicRegion* pRegion = (CSmilBasicRegion*)(*i);
  1579.     if(!pRegion->m_bNested && 
  1580.        pRegion->m_eBackgroundColorType == CSS2TypeTransparent &&
  1581.                !regions.Find(pRegion))
  1582.     {
  1583. showSite(pRegion->m_pSite, FALSE);
  1584.     }
  1585. }
  1586.     }
  1587.     return HXR_OK;
  1588. }
  1589. void
  1590. CSmilDocumentRenderer::removeGroupEvents(UINT16 uGroupIndex)
  1591. {
  1592.     if(m_pEventList)
  1593.     {
  1594. LISTPOSITION lPos = m_pEventList->GetHeadPosition();
  1595. while(lPos)
  1596. {
  1597.     // handle all events at or before ulTimeValue
  1598.     CSmilLayoutEvent* pEvent = (CSmilLayoutEvent*)m_pEventList->GetAt(lPos);
  1599.     if(pEvent->m_uGroupIndex == uGroupIndex)
  1600.     {
  1601. delete(pEvent);
  1602. lPos = m_pEventList->RemoveAt(lPos);
  1603.     }
  1604.     else
  1605.     {
  1606. m_pEventList->GetNext(lPos);
  1607.     }
  1608. }
  1609.     }
  1610. }
  1611. void
  1612. CSmilDocumentRenderer::removeActiveTransitions()
  1613. {
  1614.     if(m_pActiveTransitions)
  1615.     {
  1616. LISTPOSITION lPos = m_pActiveTransitions->GetHeadPosition();
  1617. while(lPos)
  1618. {
  1619.     SMILTransitionState* pState = (SMILTransitionState*)
  1620. m_pActiveTransitions->GetAt(lPos);
  1621.     doTransition(lPos, pState->m_ulEndTime);
  1622.     lPos = m_pActiveTransitions->RemoveAt(lPos);
  1623.     HX_DELETE(pState);
  1624. }
  1625.     }
  1626. }
  1627. #if defined(HELIX_FEATURE_SMIL2_ANIMATION)
  1628. void CSmilDocumentRenderer::removeActiveAnimations()
  1629. {
  1630.     if(m_pActiveAnimations)
  1631.     {
  1632.         if (atLeastOneActiveAnimation(m_ulCurrentTime))
  1633.         {
  1634.             if (!isSiteCompositionModeON())
  1635.             {
  1636.                 turnSiteCompositionModeON();
  1637.             }
  1638.         }
  1639.         // m_pAnimSiteRedrawMap is a list of sites
  1640.         // which need to ForceRedraw() as a result on an
  1641.         // animation on this time sync.
  1642.         if (!m_pAnimSiteRedrawMap)
  1643.         {
  1644.             m_pAnimSiteRedrawMap = new CHXMapPtrToPtr();
  1645.         }
  1646.         if (m_pAnimSiteRedrawMap)
  1647.         {
  1648.             m_pAnimSiteRedrawMap->RemoveAll();
  1649.         }
  1650.         // m_pAnimRegionRecomputeMap is a list of sites
  1651.         // which need to ForceRedraw() as a result on an
  1652.         // animation on this time sync.
  1653.         if (!m_pAnimRegionRecomputeMap)
  1654.         {
  1655.             m_pAnimRegionRecomputeMap = new CHXMapPtrToPtr();
  1656.         }
  1657.         if (m_pAnimRegionRecomputeMap)
  1658.         {
  1659.             m_pAnimRegionRecomputeMap->RemoveAll();
  1660.         }
  1661.         // m_pAnimTopLayoutMap is a collection of topLayout's
  1662.         // which have been animated programmatically and
  1663.         // need resizing.
  1664.         if (m_pAnimTopLayoutMap)
  1665.         {
  1666.             m_pAnimTopLayoutMap->RemoveAll();
  1667.         }
  1668.         // If there is a soundlevel animation going on, then
  1669.         // we need to try to grab the mutex
  1670.         if (m_pSoundLevelMutex) m_pSoundLevelMutex->Lock();
  1671.         // Clear the animate root layout flag
  1672.         m_bAnimateRootLayout = FALSE;
  1673.         LISTPOSITION lPos = m_pActiveAnimations->GetHeadPosition();
  1674.         while(lPos)
  1675.         {
  1676.             CSmilAnimateInfo* pInfo = (CSmilAnimateInfo*)
  1677.                 m_pActiveAnimations->GetNext(lPos);
  1678.             // Restore the original value
  1679.             setValue(pInfo, pInfo->m_pUnder, pInfo->m_pDepend, TRUE);
  1680.             // XXXMEH - if this is a soundLevel animation, then
  1681.             // we need to turn off the animation
  1682.             if (pInfo->m_pSandwich->GetAttributeName() == kAttrNameSoundLevel)
  1683.             {
  1684.                 finishSoundLevelAnimation(pInfo);
  1685.             }
  1686.             // Now we need to delete this info object
  1687.             HX_DELETE(pInfo);
  1688.         }
  1689.         m_pActiveAnimations->RemoveAll();
  1690.         // If there was a soundlevel animation going on, then
  1691.         // we can release the mutex
  1692.         if (m_pSoundLevelMutex) m_pSoundLevelMutex->Unlock();
  1693.         // Assign any new values
  1694.         // Recompute the root-layout if necessary
  1695.         if (m_bAnimateRootLayout && m_pRootLayout && m_pRootLayout->m_pRoot)
  1696.         {
  1697.             HXxSize cNewRootSize = {0, 0};
  1698.             cNewRootSize.cx = (INT32) floor(m_pRootLayout->m_pRoot->m_dWidth  + 0.5);
  1699.             cNewRootSize.cy = (INT32) floor(m_pRootLayout->m_pRoot->m_dHeight + 0.5);
  1700.             SiteSizeChanged(m_pRootLayout->m_pSite, &cNewRootSize);
  1701.         }
  1702. #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT)
  1703.         // Animate any topLayout's
  1704.         if (m_pAnimTopLayoutMap &&
  1705.             m_pAnimTopLayoutMap->GetCount() > 0)
  1706.         {
  1707.             POSITION mpos = m_pAnimTopLayoutMap->GetStartPosition();
  1708.             while (mpos)
  1709.             {
  1710.                 void* pKey = NULL;
  1711.                 void* pVal = NULL;
  1712.                 m_pAnimTopLayoutMap->GetNextAssoc(mpos, pKey, pVal);
  1713.                 if (pKey)
  1714.                 {
  1715.                     CSmilBasicViewport* pVP = (CSmilBasicViewport*) pKey;
  1716.                     if (pVP && pVP->m_pPort)
  1717.                     {
  1718.                         HXxSize cNewRootSize = {0, 0};
  1719.                         cNewRootSize.cx = (INT32) floor(pVP->m_pPort->m_dWidth  + 0.5);
  1720.                         cNewRootSize.cy = (INT32) floor(pVP->m_pPort->m_dHeight + 0.5);
  1721.                         SiteSizeChanged(pVP->m_pSite, &cNewRootSize);
  1722.                     }
  1723.                 }
  1724.             }
  1725.             // Clear the map
  1726.             m_pAnimTopLayoutMap->RemoveAll();
  1727.         }
  1728. #endif /* #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT) */
  1729.         // We've collected all the regions for which
  1730.         // we need to call recomputeBoxLayout()
  1731.         if (m_pAnimRegionRecomputeMap)
  1732.         {
  1733.             POSITION mpos = m_pAnimRegionRecomputeMap->GetStartPosition();
  1734.             while (mpos)
  1735.             {
  1736.                 void* pKey = NULL;
  1737.                 void* pVal = NULL;
  1738.                 m_pAnimRegionRecomputeMap->GetNextAssoc(mpos, pKey, pVal);
  1739.                 if (pKey)
  1740.                 {
  1741.                     CSmilBasicRegion* pRegion = (CSmilBasicRegion*) pKey;
  1742.                     recomputeBoxLayout(pRegion, TRUE);
  1743.                 }
  1744.             }
  1745.             // Clear the map
  1746.             m_pAnimRegionRecomputeMap->RemoveAll();
  1747.         }
  1748.         // We've collected all the sites which need
  1749.         // a ForceRedraw(), so do that now
  1750.         if (m_pAnimSiteRedrawMap)
  1751.         {
  1752.             POSITION mpos = m_pAnimSiteRedrawMap->GetStartPosition();
  1753.             while (mpos)
  1754.             {
  1755.                 void* pKey = NULL;
  1756.                 void* pVal = NULL;
  1757.                 m_pAnimSiteRedrawMap->GetNextAssoc(mpos, pKey, pVal);
  1758.                 if (pKey)
  1759.                 {
  1760.                     IHXSite* pSite = (IHXSite*) pKey;
  1761.                     forceFullRedraw(pSite);
  1762.                 }
  1763.             }
  1764.             // Clear the map
  1765.             m_pAnimSiteRedrawMap->RemoveAll();
  1766.         }
  1767.         unlockSiteComposition();
  1768.         bltSiteComposition();
  1769.         lockSiteComposition();
  1770.     }
  1771.     if (isSiteCompositionModeON())
  1772.     {
  1773.         turnSiteCompositionModeOFF();
  1774.     }
  1775. }
  1776. #endif /* #if defined(HELIX_FEATURE_SMIL2_ANIMATION) */
  1777. #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT)
  1778. void CSmilDocumentRenderer::removeViewports()
  1779. {
  1780.     if (m_pViewportList)
  1781.     {
  1782.         LISTPOSITION pos = m_pViewportList->GetHeadPosition();
  1783.         while (pos)
  1784.         {
  1785.             CSmilBasicViewport* pPort =
  1786.                 (CSmilBasicViewport*) m_pViewportList->GetNext(pos);
  1787.             HX_DELETE(pPort);
  1788.         }
  1789.         m_pViewportList->RemoveAll();
  1790.     }
  1791. }
  1792. #endif /* #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT) */
  1793. #if defined(HELIX_FEATURE_SMIL2_ANIMATION)
  1794. HX_RESULT CSmilDocumentRenderer::addAnimation(CAnimationSandwichLayer* pLayer)
  1795. {
  1796.     MLOG_ANIM(m_pErrorMessages,"addAnimation() targEl=%s m_ulCurrentTime=%lu tick=%lun",
  1797.               (const char*) pLayer->GetTargetElementID(),
  1798.               m_ulCurrentTime, HX_GET_BETTERTICKCOUNT());
  1799.     HX_RESULT retVal = HXR_OK;
  1800.     if (pLayer)
  1801.     {
  1802.         // If there is a soundlevel animation going on, then
  1803.         // we need to try to grab the mutex
  1804.         if (m_pSoundLevelMutex) m_pSoundLevelMutex->Lock();
  1805.         // If there isn't an active animation list, then
  1806.         // create one
  1807.         if (!m_pActiveAnimations)
  1808.         {
  1809.             m_pActiveAnimations = new CHXSimpleList();
  1810.         }
  1811.         if (m_pActiveAnimations)
  1812.         {
  1813.             // Run through the list and see if there are any
  1814.             // existing animations of this element's attribute.
  1815.             CSmilAnimateInfo* pInfo = NULL;
  1816.             BOOL              bNew  = TRUE;
  1817.             const char*       pszID = pLayer->GetTargetElementID();
  1818.             LISTPOSITION      pos   = m_pActiveAnimations->GetHeadPosition();
  1819.             while (pos)
  1820.             {
  1821.                 CSmilAnimateInfo* pListInfo =
  1822.                     (CSmilAnimateInfo*) m_pActiveAnimations->GetNext(pos);
  1823.                 if (pListInfo && pListInfo->m_pSandwich)
  1824.                 {
  1825.                     const char* pszListID = pListInfo->m_pSandwich->GetTargetElementID();
  1826.                     if (pszID && pszListID)
  1827.                     {
  1828.                         if (!strcmp(pszID, pszListID) &&
  1829.                             pLayer->GetAttributeName() == pListInfo->m_pSandwich->GetAttributeName())
  1830.                         {
  1831.                             // This is the sandwich we're looking for
  1832.                             pInfo = pListInfo;
  1833.                             bNew  = FALSE;
  1834.                             break;
  1835.                         }
  1836.                     }
  1837.                 }
  1838.             }
  1839.             // Are we already animating this attribute?
  1840.             if (bNew)
  1841.             {
  1842.                 // We didn't find an existing CSmilAnimateInfo, so
  1843.                 // we need to create one and put it on the list
  1844.                 pInfo = new CSmilAnimateInfo();
  1845.                 if (pInfo)
  1846.                 {
  1847.                     // Create a sandwich
  1848.                     pInfo->m_pSandwich = new CAnimationSandwich(pLayer->GetTargetElementID(),
  1849.                                                                 pLayer->GetTargetElementTag(),
  1850.                                                                 pLayer->GetAttributeName());
  1851.                     if (pInfo->m_pSandwich)
  1852.                     {
  1853.                         // Add this layer to the sandwich
  1854.                         retVal = pInfo->m_pSandwich->AddLayer(pLayer);
  1855.                         if (SUCCEEDED(retVal))
  1856.                         {
  1857.                             // Save the underlying value
  1858.                             HX_DELETE(pInfo->m_pUnder);
  1859.                             retVal = getUnderlyingValue(pInfo, pInfo->m_pUnder);
  1860.                             if (SUCCEEDED(retVal))
  1861.                             {
  1862.                                 HX_DELETE(pInfo->m_pDepend);
  1863.                                 retVal = getDependentValue(pInfo, pInfo->m_pDepend);
  1864.                                 if (SUCCEEDED(retVal))
  1865.                                 {
  1866.                                     // Now put this on the list
  1867.                                     m_pActiveAnimations->AddTail((void*) pInfo);
  1868.                                     // XXMEH - if this is a soundLevel animation,
  1869.                                     // we have to tell the core to start calling us
  1870.                                     if (pLayer->GetAttributeName() == kAttrNameSoundLevel)
  1871.                                     {
  1872.                                         // First we need to create the mutex
  1873.                                         if (!m_pSoundLevelMutex && m_pParent)
  1874.                                         {
  1875.                                             IHXCommonClassFactory* pFactory =
  1876.                                                 m_pParent->getFactory();
  1877.                                             if (pFactory)
  1878.                                             {
  1879.                                                 pFactory->CreateInstance(CLSID_IHXMutex,
  1880.                                                                          (void**) &m_pSoundLevelMutex);
  1881.                                             }
  1882.                                             // If we just created the mutex, the
  1883.                                             // we need to lock it
  1884.                                             if (m_pSoundLevelMutex) m_pSoundLevelMutex->Lock();
  1885.                                         }
  1886.                                         // And now we can start the animation
  1887.                                         startSoundLevelAnimation(pInfo);
  1888.                                     }
  1889.                                 }
  1890.                             }
  1891.                         }
  1892.                     }
  1893.                     else
  1894.                     {
  1895.                         retVal = HXR_OUTOFMEMORY;
  1896.                     }
  1897.                 }
  1898.                 else
  1899.                 {
  1900.                     retVal = HXR_OUTOFMEMORY;
  1901.                 }
  1902.                 if (FAILED(retVal))
  1903.                 {
  1904.                     HX_DELETE(pInfo);
  1905.                 }
  1906.             }
  1907.             else
  1908.             {
  1909.                 // There was already an existing CSmilAnimateInfo, so 
  1910.                 // we just need to add this layer to it
  1911.                 if (pInfo && pInfo->m_pSandwich)
  1912.                 {
  1913.                     // Is this a soundLevel animation?
  1914.                     if (pLayer->GetAttributeName() == kAttrNameSoundLevel)
  1915.                     {
  1916.                         // We are about to add a layer to an existing
  1917.                         // soundLevel animation. Since soundLevel animations
  1918.                         // get their information about 2s ahead of time, then
  1919.                         // we need to stop this animation and cause another
  1920.                         // rewind by starting a new animation. So first
  1921.                         // we need to stop this current animation. Note
  1922.                         // that we set bUseCurrentLevel to TRUE so that
  1923.                         // we will end the soundLevel animation with
  1924.                         // the value at the current level instead of
  1925.                         // reverting to the animation's underlying value.
  1926.                         finishSoundLevelAnimation(pInfo, TRUE);
  1927.                     }
  1928.                     retVal = pInfo->m_pSandwich->AddLayer(pLayer);
  1929.                     if (SUCCEEDED(retVal))
  1930.                     {
  1931.                         // Is this a soundLevel animation?
  1932.                         if (pLayer->GetAttributeName() == kAttrNameSoundLevel)
  1933.                         {
  1934.                             // If this is a soundLevel animation, then we have
  1935.                             // just added an additional layer to an existing
  1936.                             // soundLevel animation. Therefore, we should
  1937.                             // restart a soundLevel animation.
  1938.                             startSoundLevelAnimation(pInfo);
  1939.                         }
  1940.                     }
  1941.                 }
  1942.                 else
  1943.                 {
  1944.                     retVal = HXR_FAIL;
  1945.                 }
  1946.             }
  1947.         }
  1948.         else
  1949.         {
  1950.             retVal = HXR_OUTOFMEMORY;
  1951.         }
  1952.         // If there is a soundlevel animation going on,
  1953.         // then release the mutex
  1954.         if (m_pSoundLevelMutex) m_pSoundLevelMutex->Unlock();
  1955.     }
  1956.     else
  1957.     {
  1958.         retVal = HXR_FAIL;
  1959.     }
  1960.     return retVal;
  1961. }
  1962. HX_RESULT CSmilDocumentRenderer::removeAnimation(CSmilAnimateElement* pAnimate)
  1963. {
  1964.     HX_RESULT retVal = HXR_OK;
  1965.     if (pAnimate)
  1966.     {
  1967.         // If there is a soundlevel animation going on, then
  1968.         // we need to try to grab the mutex
  1969.         if (m_pSoundLevelMutex) m_pSoundLevelMutex->Lock();
  1970.         // Does this animation begin on an event?
  1971.         BOOL bBeginOnEvent = pAnimate->hasEventBasedBeginTime();
  1972.         // Does this animation end on an event?
  1973.         BOOL bEndOnEvent = pAnimate->hasEventBasedEndTime();
  1974.         // If we end on an event AND we have fill="freeze"
  1975.         // behavior, then we don't want to end, but rather
  1976.         // shorten the active duration to be the current time.
  1977.         // Then we will automatically go into a freeze state.
  1978.         if (bEndOnEvent &&
  1979.             pAnimate->m_eActualFill == FillFreeze)
  1980.         {
  1981.             // Find the right animation layer
  1982.             LISTPOSITION pos = m_pActiveAnimations->GetHeadPosition();
  1983.             while (pos)
  1984.             {
  1985.                 CSmilAnimateInfo* pInfo =
  1986.                     (CSmilAnimateInfo*) m_pActiveAnimations->GetNext(pos);
  1987.                 if (pInfo &&
  1988.                     pInfo->m_pSandwich &&
  1989.                     pInfo->m_pSandwich->MatchingSandwich(pAnimate))
  1990.                 {
  1991.                     // Freeze all layers in this sandwich which come
  1992.                     // from this animate element and are currently active.
  1993.                     pInfo->m_pSandwich->FreezeLayers(pAnimate->m_pNode->m_id, m_ulCurrentTime);
  1994.                 }
  1995.             }
  1996.         }
  1997.         else if (!bBeginOnEvent ||
  1998.                  (bEndOnEvent && pAnimate->m_eActualFill == FillRemove))
  1999.         {
  2000.             if (m_pActiveAnimations &&
  2001.                 m_pActiveAnimations->GetCount() > 0)
  2002.             {
  2003.                 if (!isSiteCompositionModeON())
  2004.                 {
  2005.                     turnSiteCompositionModeON();
  2006.                 }
  2007.                 // m_pAnimSiteRedrawMap is a list of sites
  2008.                 // which need to ForceRedraw() as a result on an
  2009.                 // animation on this time sync.
  2010.                 if (!m_pAnimSiteRedrawMap)
  2011.                 {
  2012.                     m_pAnimSiteRedrawMap = new CHXMapPtrToPtr();
  2013.                 }
  2014.                 if (m_pAnimSiteRedrawMap)
  2015.                 {
  2016.                     m_pAnimSiteRedrawMap->RemoveAll();
  2017.                 }
  2018.                 // m_pAnimRegionRecomputeMap is a list of sites
  2019.                 // which need to ForceRedraw() as a result on an
  2020.                 // animation on this time sync.
  2021.                 if (!m_pAnimRegionRecomputeMap)
  2022.                 {
  2023.                     m_pAnimRegionRecomputeMap = new CHXMapPtrToPtr();
  2024.                 }
  2025.                 if (m_pAnimRegionRecomputeMap)
  2026.                 {
  2027.                     m_pAnimRegionRecomputeMap->RemoveAll();
  2028.                 }
  2029.                 // m_pAnimTopLayoutMap is a collection of topLayout's
  2030.                 // which have been animated programmatically and
  2031.                 // need resizing.
  2032.                 if (m_pAnimTopLayoutMap)
  2033.                 {
  2034.                     m_pAnimTopLayoutMap->RemoveAll();
  2035.                 }
  2036.                 // Clear the animate root layout flag
  2037.                 m_bAnimateRootLayout = FALSE;
  2038.                 // Run through the active animations
  2039.                 LISTPOSITION pos = m_pActiveAnimations->GetHeadPosition();
  2040.                 while (pos)
  2041.                 {
  2042.                     CSmilAnimateInfo* pInfo =
  2043.                         (CSmilAnimateInfo*) m_pActiveAnimations->GetAt(pos);
  2044.                     if (pInfo && pInfo->m_pSandwich &&
  2045.                         pInfo->m_pSandwich->MatchingSandwich(pAnimate))
  2046.                     {
  2047.                         // Remove this animate element from this sandwich. 
  2048.                         pInfo->m_pSandwich->RemoveLayer(pAnimate->m_pNode->m_id);
  2049.                         // Are there any layers left in this sandwich?
  2050.                         if (pInfo->m_pSandwich->GetNumLayers())
  2051.                         {
  2052.                             m_pActiveAnimations->GetNext(pos);
  2053.                         }
  2054.                         else
  2055.                         {
  2056.                             // There are no more layers left in the
  2057.                             // sandwich, so this animation is done. So,
  2058.                             // we need to restore whatever original values
  2059.                             // were present
  2060.                             setValue(pInfo, pInfo->m_pUnder, pInfo->m_pDepend, TRUE);
  2061.                             // XXXMEH - if this is a soundLevel animation, then
  2062.                             // we need to turn off the animation
  2063.                             if (pInfo->m_pSandwich->GetAttributeName() == kAttrNameSoundLevel)
  2064.                             {
  2065.                                 finishSoundLevelAnimation(pInfo);
  2066.                             }
  2067.                             // Now we need to delete this info object
  2068.                             HX_DELETE(pInfo);
  2069.                             // And remove it from the list
  2070.                             // We have to do the following hack since
  2071.                             // CHXSimpleList does not advance the position to 
  2072.                             // NULL if you RemoveAt() the last element in the list.
  2073.                             BOOL bLast = (m_pActiveAnimations->GetAt(pos) ==
  2074.                                           m_pActiveAnimations->GetTail());
  2075.                             pos        = m_pActiveAnimations->RemoveAt(pos);
  2076.                             if (bLast && pos)
  2077.                             {
  2078.                                 m_pActiveAnimations->GetNext(pos);
  2079.                             }
  2080.                         }
  2081.                     }
  2082.                     else
  2083.                     {
  2084.                         m_pActiveAnimations->GetNext(pos);
  2085.                     }
  2086.                 }
  2087.                 // Recompute the root-layout if necessary
  2088.                 if (m_bAnimateRootLayout && m_pRootLayout && m_pRootLayout->m_pRoot)
  2089.                 {
  2090.                     HXxSize cNewRootSize = {0, 0};
  2091.                     cNewRootSize.cx = (INT32) floor(m_pRootLayout->m_pRoot->m_dWidth  + 0.5);
  2092.                     cNewRootSize.cy = (INT32) floor(m_pRootLayout->m_pRoot->m_dHeight + 0.5);
  2093.                     SiteSizeChanged(m_pRootLayout->m_pSite, &cNewRootSize);
  2094.                 }
  2095. #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT)
  2096.                 // Animate any topLayout's
  2097.                 if (m_pAnimTopLayoutMap &&
  2098.                     m_pAnimTopLayoutMap->GetCount() > 0)
  2099.                 {
  2100.                     POSITION mpos = m_pAnimTopLayoutMap->GetStartPosition();
  2101.                     while (mpos)
  2102.                     {
  2103.                         void* pKey = NULL;
  2104.                         void* pVal = NULL;
  2105.                         m_pAnimTopLayoutMap->GetNextAssoc(mpos, pKey, pVal);
  2106.                         if (pKey)
  2107.                         {
  2108.                             CSmilBasicViewport* pVP = (CSmilBasicViewport*) pKey;
  2109.                             if (pVP && pVP->m_pPort)
  2110.                             {
  2111.                                 HXxSize cNewRootSize = {0, 0};
  2112.                                 cNewRootSize.cx = (INT32) floor(pVP->m_pPort->m_dWidth  + 0.5);
  2113.                                 cNewRootSize.cy = (INT32) floor(pVP->m_pPort->m_dHeight + 0.5);
  2114.                                 SiteSizeChanged(pVP->m_pSite, &cNewRootSize);
  2115.                             }
  2116.                         }
  2117.                     }
  2118.                     // Clear the map
  2119.                     m_pAnimTopLayoutMap->RemoveAll();
  2120.                 }
  2121. #endif /* #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT) */
  2122.                 // We've collected all the regions for which
  2123.                 // we need to call recomputeBoxLayout()
  2124.                 if (m_pAnimRegionRecomputeMap)
  2125.                 {
  2126.                     POSITION mpos = m_pAnimRegionRecomputeMap->GetStartPosition();
  2127.                     while (mpos)
  2128.                     {
  2129.                         void* pKey = NULL;
  2130.                         void* pVal = NULL;
  2131.                         m_pAnimRegionRecomputeMap->GetNextAssoc(mpos, pKey, pVal);
  2132.                         if (pKey)
  2133.                         {
  2134.                             CSmilBasicRegion* pRegion = (CSmilBasicRegion*) pKey;
  2135.                             recomputeBoxLayout(pRegion, TRUE);
  2136.                         }
  2137.                     }
  2138.                     // Clear the map
  2139.                     m_pAnimRegionRecomputeMap->RemoveAll();
  2140.                 }
  2141.                 // We've collected all the sites which need
  2142.                 // a ForceRedraw(), so do that now
  2143.                 if (m_pAnimSiteRedrawMap)
  2144.                 {
  2145.                     POSITION mpos = m_pAnimSiteRedrawMap->GetStartPosition();
  2146.                     while (mpos)
  2147.                     {
  2148.                         void* pKey = NULL;
  2149.                         void* pVal = NULL;
  2150.                         m_pAnimSiteRedrawMap->GetNextAssoc(mpos, pKey, pVal);
  2151.                         if (pKey)
  2152.                         {
  2153.                             IHXSite* pSite = (IHXSite*) pKey;
  2154.                             forceFullRedraw(pSite);
  2155.                         }
  2156.                     }
  2157.                     // Clear the map
  2158.                     m_pAnimSiteRedrawMap->RemoveAll();
  2159.                 }
  2160.                 unlockSiteComposition();
  2161.                 bltSiteComposition();
  2162.                 lockSiteComposition();
  2163.             }
  2164.             if (!m_pActiveAnimations ||
  2165.                 (m_pActiveAnimations && m_pActiveAnimations->GetCount() == 0))
  2166.             {
  2167.                 if (isSiteCompositionModeON())
  2168.                 {
  2169.                     turnSiteCompositionModeOFF();
  2170.                 }
  2171.             }
  2172.         }
  2173.         // If there is a soundlevel animation going on,
  2174.         // then release the mutex
  2175.         if (m_pSoundLevelMutex) m_pSoundLevelMutex->Unlock();
  2176.     }
  2177.     else
  2178.     {
  2179.         retVal = HXR_FAIL;
  2180.     }
  2181.     return retVal;
  2182. }
  2183. void CSmilDocumentRenderer::removeAnimation(CSmilAnimateInfo* pInfo)
  2184. {
  2185.     if (pInfo && m_pActiveAnimations)
  2186.     {
  2187.         // If there is a soundlevel animation going on, then
  2188.         // we need to try to grab the mutex
  2189.         if (m_pSoundLevelMutex) m_pSoundLevelMutex->Lock();
  2190.         // Now we can remove the animation
  2191.         LISTPOSITION pos = m_pActiveAnimations->GetHeadPosition();
  2192.         while (pos)
  2193.         {
  2194.             CSmilAnimateInfo* pLInfo =
  2195.                 (CSmilAnimateInfo*) m_pActiveAnimations->GetAt(pos);
  2196.             if (pInfo == pLInfo)
  2197.             {
  2198.                 m_pActiveAnimations->RemoveAt(pos);
  2199.                 break;
  2200.             }
  2201.             else
  2202.             {
  2203.                 m_pActiveAnimations->GetNext(pos);
  2204.             }
  2205.         }
  2206.         // If there is a soundlevel animation going on,
  2207.         // then release the mutex
  2208.         if (m_pSoundLevelMutex) m_pSoundLevelMutex->Unlock();
  2209.     }
  2210. }
  2211. void CSmilDocumentRenderer::doAnimation(CSmilAnimateInfo* pInfo, UINT32 ulTime)
  2212. {
  2213.     if (pInfo && pInfo->m_pSandwich && pInfo->m_pUnder)
  2214.     {
  2215.         // Compute the animation value
  2216.         CAttr cRet = pInfo->m_pSandwich->GetValue(ulTime, pInfo->m_pUnder, pInfo->m_pDepend);
  2217.         MLOG_ANIM(m_pErrorMessages,"doAnimation(,%lu) cRet=(%5.1lf,%5.1lf,%5.1lf,%5.1lf)n",
  2218.                   ulTime,
  2219.                   cRet.GetValueDouble(0),
  2220.                   cRet.GetValueDouble(1),
  2221.                   cRet.GetValueDouble(2),
  2222.                   cRet.GetValueDouble(3));
  2223.         // Adjust the sandwich
  2224.         pInfo->m_pSandwich->AdjustLayers(ulTime);
  2225.         // Apply the resulting value
  2226.         setValue(pInfo, &cRet, pInfo->m_pDepend,
  2227.                  (pInfo->m_pSandwich->GetNumLayers() ? FALSE : TRUE));
  2228.     }
  2229. }
  2230. HX_RESULT CSmilDocumentRenderer::getUnderlyingValue(CSmilAnimateInfo* pInfo,
  2231.                                                     REF(CAttr*)       rpValue)
  2232. {
  2233.     HX_RESULT retVal = HXR_OK;
  2234.     if (pInfo && pInfo->m_pSandwich)
  2235.     {
  2236.         // Get the target element id
  2237.         const char* pszID = pInfo->m_pSandwich->GetTargetElementID();
  2238.         // Get the target element tag
  2239.         SMILNodeTag eTag = pInfo->m_pSandwich->GetTargetElementTag();
  2240.         // Get the attribute name
  2241.         UINT32 ulAttr = pInfo->m_pSandwich->GetAttributeName();
  2242.         // Depending on the type of target element, we will
  2243.         // go lookup a different object
  2244.         if (eTag == SMILRegion)
  2245.         {
  2246.             // Get the region
  2247.             CSmilBasicRegion* pRegion = getRegionByID(pszID);
  2248.             if (pRegion)
  2249.             {
  2250.                 double   dVal[4]  = {0.0, 0.0, 0.0, 0.0};
  2251.                 CSS2Type eType[4] = {CSS2TypeAuto, CSS2TypeAuto,
  2252.                                      CSS2TypeAuto, CSS2TypeAuto};
  2253.                 switch (ulAttr)
  2254.                 {
  2255.                     case kAttrNameSoundLevel:
  2256.                         dVal[0] = pRegion->m_dSoundLevel;
  2257.                         break;
  2258.                     case kAttrNameZIndex:
  2259.                         dVal[0] = pRegion->m_lZIndex;
  2260.                         break;
  2261.                     case kAttrNameBackgroundColor:
  2262.                         {
  2263.                             UINT32 ulColor = pRegion->m_ulBackgroundColor;
  2264.                             dVal[0] = ((ulColor & 0x00FF0000) >> 16); // R
  2265.                             dVal[1] = ((ulColor & 0x0000FF00) >>  8); // G
  2266.                             dVal[2] =  (ulColor & 0x000000FF);        // B
  2267.                             dVal[3] = ((ulColor & 0xFF000000) >> 24); // A
  2268.                         }
  2269.                         break;
  2270.                     case kAttrNameLeft:
  2271.                     case kAttrNameTop:
  2272.                         // Note that we have to put both left and
  2273.                         // top in the same underlying value, since 
  2274.                         // an <animateMotion> could be inside the sandwich
  2275.                         // for left or top.
  2276.                         dVal[0]  = pRegion->m_LayoutRect.m_dLeft;
  2277.                         eType[0] = pRegion->m_LayoutRect.m_eLeftType;
  2278.                         dVal[1]  = pRegion->m_LayoutRect.m_dTop;
  2279.                         eType[1] = pRegion->m_LayoutRect.m_eTopType;
  2280.                         break;
  2281.                     case kAttrNameRight:
  2282.                         dVal[0]  = pRegion->m_LayoutRect.m_dRight;
  2283.                         eType[0] = pRegion->m_LayoutRect.m_eRightType;
  2284.                         break;
  2285.                     case kAttrNameBottom:
  2286.                         dVal[0]  = pRegion->m_LayoutRect.m_dBottom;
  2287.                         eType[0] = pRegion->m_LayoutRect.m_eBottomType;
  2288.                         break;
  2289.                     case kAttrNameWidth:
  2290.                         dVal[0]  = pRegion->m_LayoutRect.m_dWidth;
  2291.                         eType[0] = pRegion->m_LayoutRect.m_eWidthType;
  2292.                         break;
  2293.                     case kAttrNameHeight:
  2294.                         dVal[0]  = pRegion->m_LayoutRect.m_dHeight;
  2295.                         eType[0] = pRegion->m_LayoutRect.m_eHeightType;
  2296.                         break;
  2297.                 }
  2298.                 // Create the atttribute
  2299.                 HX_DELETE(rpValue);
  2300.                 rpValue = new CAttr(ulAttr,
  2301.                                     dVal[0], eType[0], dVal[1], eType[1],
  2302.                                     dVal[2], eType[2], dVal[3], eType[3]);
  2303.                 if (!rpValue)
  2304.                 {
  2305.                     retVal = HXR_OUTOFMEMORY;
  2306.                 }
  2307.             }
  2308.             else
  2309.             {
  2310.                 retVal = HXR_FAIL;
  2311.             }
  2312.         }
  2313.         else if (eTag == SMILAnchor)
  2314.         {
  2315.             // Find the CSmilAnchorElement object
  2316.             CSmilAnchorElement* pAnchor =
  2317.                 m_pSmilParser->getAnchorOrAreaElement(pInfo->m_pSandwich->GetTargetElementID());
  2318.             if (pAnchor && pAnchor->m_pNode && pAnchor->m_pNode->m_pValues)
  2319.             {
  2320.                 IHXBuffer* pCoords = NULL;
  2321.                 retVal = pAnchor->m_pNode->m_pValues->GetPropertyCString("coords", pCoords);
  2322.                 if (SUCCEEDED(retVal))
  2323.                 {
  2324.                     HX_DELETE(rpValue);
  2325.                     rpValue = new CAttr(kAttrNameCoords,
  2326.                                         (const char*) pCoords->GetBuffer());
  2327.                     if (!rpValue)
  2328.                     {
  2329.                         retVal = HXR_OUTOFMEMORY;
  2330.                     }
  2331.                 }
  2332.                 HX_RELEASE(pCoords);
  2333.             }
  2334.             else
  2335.             {
  2336.                 retVal = HXR_FAIL;
  2337.             }
  2338.         }
  2339.         else if (eTag == SMILText       ||
  2340.                  eTag == SMILImg        ||
  2341.                  eTag == SMILRef        ||
  2342.                  eTag == SMILAudio      ||
  2343.                  eTag == SMILVideo      ||
  2344.                  eTag == SMILAnimation  ||
  2345.                  eTag == SMILTextstream ||
  2346.                  eTag == SMILBrush)
  2347.         {
  2348.             // Get the source
  2349.             CSmilSource* pSource = getSource(pszID);
  2350.             if (pSource)
  2351.             {
  2352.                 double   dVal[4]  = {0.0, 0.0, 0.0, 0.0};
  2353.                 CSS2Type eType[4] = {CSS2TypeAuto, CSS2TypeAuto,
  2354.                                      CSS2TypeAuto, CSS2TypeAuto};
  2355.                 switch (ulAttr)
  2356.                 {
  2357.                     case kAttrNameLeft:
  2358.                     case kAttrNameTop:
  2359.                         // Note that we have to put both left and
  2360.                         // top in the same underlying value, since 
  2361.                         // an <animateMotion> could be inside the sandwich
  2362.                         // for left or top.
  2363.                         dVal[0]  = pSource->m_Rect.m_dLeft;
  2364.                         eType[0] = pSource->m_Rect.m_eLeftType;
  2365.                         dVal[1]  = pSource->m_Rect.m_dTop;
  2366.                         eType[1] = pSource->m_Rect.m_eTopType;
  2367.                         break;
  2368.                     case kAttrNameRight:
  2369.                         dVal[0]  = pSource->m_Rect.m_dRight;
  2370.                         eType[0] = pSource->m_Rect.m_eRightType;
  2371.                         break;
  2372.                     case kAttrNameBottom:
  2373.                         dVal[0]  = pSource->m_Rect.m_dBottom;
  2374.                         eType[0] = pSource->m_Rect.m_eBottomType;
  2375.                         break;
  2376.                     case kAttrNameWidth:
  2377.                         dVal[0]  = pSource->m_Rect.m_dWidth;
  2378.                         eType[0] = pSource->m_Rect.m_eWidthType;
  2379.                         break;
  2380.                     case kAttrNameHeight:
  2381.                         dVal[0]  = pSource->m_Rect.m_dHeight;
  2382.                         eType[0] = pSource->m_Rect.m_eHeightType;
  2383.                         break;
  2384.                     case kAttrNameZIndex:
  2385.                         dVal[0] = pSource->m_lZIndex;
  2386.                         break;
  2387.                     case kAttrNameBackgroundColor:
  2388.                         {
  2389.                             UINT32 ulColor = pSource->m_ulBackgroundColor;
  2390.                             dVal[0] = ((ulColor & 0x00FF0000) >> 16); // R
  2391.                             dVal[1] = ((ulColor & 0x0000FF00) >>  8); // G
  2392.                             dVal[2] =  (ulColor & 0x000000FF);        // B
  2393.                             dVal[3] = ((ulColor & 0xFF000000) >> 24); // A
  2394.                         }
  2395.                         break;
  2396.                     case kAttrNameColor:
  2397.                         {
  2398.                             UINT32 ulColor = pSource->m_ulColor;
  2399.                             dVal[0] = ((ulColor & 0x00FF0000) >> 16); // R
  2400.                             dVal[1] = ((ulColor & 0x0000FF00) >>  8); // G
  2401.                             dVal[2] =  (ulColor & 0x000000FF);        // B
  2402.                             dVal[3] = ((ulColor & 0xFF000000) >> 24); // A
  2403.                         }
  2404.                         break;
  2405.                     case kAttrNameMediaOpacity:
  2406.                         {
  2407.                             dVal[0] = (double) pSource->m_ulMediaOpacity;
  2408.                         }
  2409.                         break;
  2410.                     case kAttrNameBackgroundOpacity:
  2411.                         {
  2412.                             dVal[0] = (double) pSource->m_ulBackgroundOpacity;
  2413.                         }
  2414.                         break;
  2415.                 }
  2416.                 // Create the atttribute
  2417.                 HX_DELETE(rpValue);
  2418.                 rpValue = new CAttr(ulAttr,
  2419.                                    dVal[0], eType[0], dVal[1], eType[1],
  2420.                                    dVal[2], eType[2], dVal[3], eType[3]);
  2421.                 if (!rpValue)
  2422.                 {
  2423.                     retVal = HXR_OUTOFMEMORY;
  2424.                 }
  2425.             }
  2426.             else
  2427.             {
  2428.                 retVal = HXR_FAIL;
  2429.             }
  2430.         }
  2431.         else if (eTag == SMILRootLayout)
  2432.         {
  2433.             if (m_pRootLayout && m_pRootLayout->m_pRoot)
  2434.             {
  2435.                 double   dVal[4]  = {0.0, 0.0, 0.0, 0.0};
  2436.                 CSS2Type eType[4] = {CSS2TypeAuto, CSS2TypeAuto,
  2437.                                      CSS2TypeAuto, CSS2TypeAuto};
  2438.                 switch (ulAttr)
  2439.                 {
  2440.                     case kAttrNameWidth:
  2441.                         dVal[0]  = m_pRootLayout->m_pRoot->m_dWidth;
  2442.                         eType[0] = m_pRootLayout->m_pRoot->m_eWidthType;
  2443.                         break;
  2444.                     case kAttrNameHeight:
  2445.                         dVal[0]  = m_pRootLayout->m_pRoot->m_dHeight;
  2446.                         eType[0] = m_pRootLayout->m_pRoot->m_eHeightType;
  2447.                         break;
  2448.                 }
  2449.                 // Create the atttribute
  2450.                 HX_DELETE(rpValue);
  2451.                 rpValue = new CAttr(ulAttr,
  2452.                                     dVal[0], eType[0], dVal[1], eType[1],
  2453.                                     dVal[2], eType[2], dVal[3], eType[3]);
  2454.                 if (!rpValue)
  2455.                 {
  2456.                     retVal = HXR_OUTOFMEMORY;
  2457.                 }
  2458.             }
  2459.             else
  2460.             {
  2461.                 retVal = HXR_FAIL;
  2462.             }
  2463.         }
  2464. #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT)
  2465.         else if (eTag == SMILViewport)
  2466.         {
  2467.             CSmilBasicViewport* pPort = getViewport(pszID);
  2468.             if (pPort && pPort->m_pPort)
  2469.             {
  2470.                 double   dVal[4]  = {0.0, 0.0, 0.0, 0.0};
  2471.                 CSS2Type eType[4] = {CSS2TypeAuto, CSS2TypeAuto,
  2472.                                      CSS2TypeAuto, CSS2TypeAuto};
  2473.                 switch (ulAttr)
  2474.                 {
  2475.                     case kAttrNameWidth:
  2476.                         dVal[0]  = pPort->m_pPort->m_dWidth;
  2477.                         eType[0] = pPort->m_pPort->m_eWidthType;
  2478.                         break;
  2479.                     case kAttrNameHeight:
  2480.                         dVal[0]  = pPort->m_pPort->m_dHeight;
  2481.                         eType[0] = pPort->m_pPort->m_eHeightType;
  2482.                         break;
  2483.                 }
  2484.                 // Create the atttribute
  2485.                 HX_DELETE(rpValue);
  2486.                 rpValue = new CAttr(ulAttr,
  2487.                                     dVal[0], eType[0], dVal[1], eType[1],
  2488.                                     dVal[2], eType[2], dVal[3], eType[3]);
  2489.                 if (!rpValue)
  2490.                 {
  2491.                     retVal = HXR_OUTOFMEMORY;
  2492.                 }
  2493.             }
  2494.             else
  2495.             {
  2496.                 retVal = HXR_FAIL;
  2497.             }
  2498.         }
  2499. #endif /* #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT) */
  2500.         else if (eTag == SMILParam)
  2501.         {
  2502.             if (m_pSmilParser)
  2503.             {
  2504.                 CSmilElement* pEl = m_pSmilParser->findElement(pszID);
  2505.                 if (pEl && pEl->m_pNode && pEl->m_pNode->m_tag == SMILParam)
  2506.                 {
  2507.                     // Cast to a CSmilParamElement
  2508.                     CSmilParamElement* pParam = (CSmilParamElement*) pEl;
  2509.                     // Make sure we have a value attribute
  2510.                     if (pParam->m_pValue)
  2511.                     {
  2512.                         // Create the atttribute
  2513.                         HX_DELETE(rpValue);
  2514.                         rpValue = new CAttr(ulAttr,
  2515.                                             (const char*) pParam->m_pValue->GetBuffer());
  2516.                         if (!rpValue)
  2517.                         {
  2518.                             retVal = HXR_OUTOFMEMORY;
  2519.                         }
  2520.                     }
  2521.                 }
  2522.                 else
  2523.                 {
  2524.                     retVal = HXR_FAIL;
  2525.                 }
  2526.             }
  2527.             else
  2528.             {
  2529.                 retVal = HXR_FAIL;
  2530.             }
  2531.         }
  2532.     }
  2533.     return retVal;
  2534. }
  2535. HX_RESULT CSmilDocumentRenderer::getDependentValue(CSmilAnimateInfo* pInfo,
  2536.                                                    REF(CAttr*)       rpDepend)
  2537. {
  2538.     HX_RESULT retVal = HXR_OK;
  2539.     if (pInfo && pInfo->m_pSandwich)
  2540.     {
  2541.         // Clear any existing attribute
  2542.         HX_DELETE(rpDepend);
  2543.         // Get the target element id
  2544.         const char* pszID = pInfo->m_pSandwich->GetTargetElementID();
  2545.         // Get the target element tag
  2546.         SMILNodeTag eTag = pInfo->m_pSandwich->GetTargetElementTag();
  2547.         // Get the attribute name
  2548.         UINT32 ulAttr = pInfo->m_pSandwich->GetAttributeName();
  2549.         // Depending on the type of target element, we will
  2550.         // go lookup a different object
  2551.         if (eTag == SMILRegion)
  2552.         {
  2553.             // We need to compute the size of this region's parent.
  2554.             HXxSize           cParentSize = {0, 0};
  2555.             CSmilBasicRegion* pRegion     = getRegionByID(pszID);
  2556.             if (pRegion && pRegion->m_pParent)
  2557.             {
  2558.                 cParentSize.cx = HXxRECT_WIDTH(pRegion->m_pParent->m_Rect);
  2559.                 cParentSize.cy = HXxRECT_HEIGHT(pRegion->m_pParent->m_Rect);
  2560.             }
  2561.             double   dVal[2]  = {0.0, 0.0};
  2562.             CSS2Type eType[2] = {CSS2TypeAuto, CSS2TypeAuto};
  2563.             BOOL   bCreate = TRUE;
  2564.             switch (ulAttr)
  2565.             {
  2566.                 case kAttrNameLeft:
  2567.                 case kAttrNameTop:
  2568.                     // Note that we have to put both left and
  2569.                     // top in the same depenent value, since 
  2570.                     // an <animateMotion> could be inside the sandwich
  2571.                     // for left or top.
  2572.                     dVal[0]  = cParentSize.cx;
  2573.                     dVal[1]  = cParentSize.cy;
  2574.                     eType[0] = eType[1] = CSS2TypeLength;
  2575.                     break;
  2576.                 case kAttrNameRight:
  2577.                 case kAttrNameWidth:
  2578.                     dVal[0]  = cParentSize.cx;
  2579.                     eType[0] = CSS2TypeLength;
  2580.                     break;
  2581.                 case kAttrNameBottom:
  2582.                 case kAttrNameHeight:
  2583.                     dVal[0]  = cParentSize.cy;
  2584.                     eType[0] = CSS2TypeLength;
  2585.                     break;
  2586.                 default:
  2587.                     // We only need a dependent value for
  2588.                     // position and length attributes
  2589.                     bCreate = FALSE;
  2590.                     break;
  2591.             }
  2592.             // Was this an attribute for which we need
  2593.             // to create a dependent value?
  2594.             if (bCreate)
  2595.             {
  2596.                 // Create the atttribute
  2597.                 HX_DELETE(rpDepend);
  2598.                 rpDepend = new CAttr(ulAttr, dVal[0], eType[0], dVal[1], eType[1]);
  2599.                 if (!rpDepend)
  2600.                 {
  2601.                     retVal = HXR_OUTOFMEMORY;
  2602.                 }
  2603.             }
  2604.         }
  2605.         else if (eTag == SMILText       ||
  2606.                  eTag == SMILImg        ||
  2607.                  eTag == SMILRef        ||
  2608.                  eTag == SMILAudio      ||
  2609.                  eTag == SMILVideo      ||
  2610.                  eTag == SMILAnimation  ||
  2611.                  eTag == SMILTextstream ||
  2612.                  eTag == SMILBrush)
  2613.         {
  2614.             // Get the source
  2615.             CSmilSource* pSource = getSource(pszID);
  2616.             if (pSource)
  2617.             {
  2618.                 // Get the region this is playing to
  2619.                 CSmilBasicRegion* pRegion = getRegionByID((const char*) pSource->m_region);
  2620.                 if (pRegion)
  2621.                 {
  2622.                     HXxSize cRegionSize = {HXxRECT_WIDTH(pRegion->m_Rect),
  2623.                                            HXxRECT_HEIGHT(pRegion->m_Rect)};
  2624.                     double   dVal[3]  = {0.0, 0.0};
  2625.                     CSS2Type eType[3] = {CSS2TypeAuto, CSS2TypeAuto};
  2626.                     BOOL   bCreate    = TRUE;
  2627.                     switch (ulAttr)
  2628.                     {
  2629.                         case kAttrNameLeft:
  2630.                         case kAttrNameTop:
  2631.                             // Note that we have to put both left and
  2632.                             // top in the same depenent value, since 
  2633.                             // an <animateMotion> could be inside the sandwich
  2634.                             // for left or top.
  2635.                             dVal[0]  = cRegionSize.cx;
  2636.                             dVal[1]  = cRegionSize.cy;
  2637.                             eType[0] = eType[1] = CSS2TypeLength;
  2638.                             break;
  2639.                         case kAttrNameRight:
  2640.                         case kAttrNameWidth:
  2641.                             dVal[0]  = cRegionSize.cx;
  2642.                             eType[0] = CSS2TypeLength;
  2643.                             break;
  2644.                         case kAttrNameBottom:
  2645.                         case kAttrNameHeight:
  2646.                             dVal[0]  = cRegionSize.cy;
  2647.                             eType[0] = CSS2TypeLength;
  2648.                             break;
  2649.                         default:
  2650.                             // We only need a dependent value for
  2651.                             // position and length attributes
  2652.                             bCreate = FALSE;
  2653.                             break;
  2654.                     }
  2655.                     // Was this an attribute for which we need
  2656.                     // to create a dependent value?
  2657.                     if (bCreate)
  2658.                     {
  2659.                         // Create the atttribute
  2660.                         HX_DELETE(rpDepend);
  2661.                         rpDepend = new CAttr(ulAttr, dVal[0], eType[0], dVal[1], eType[1]);
  2662.                         if (!rpDepend)
  2663.                         {
  2664.                             retVal = HXR_OUTOFMEMORY;
  2665.                         }
  2666.                     }
  2667.                 }
  2668.                 else
  2669.                 {
  2670.                     retVal = HXR_FAIL;
  2671.                 }
  2672.             }
  2673.             else
  2674.             {
  2675.                 retVal = HXR_FAIL;
  2676.             }
  2677.         }
  2678.     }
  2679.     else
  2680.     {
  2681.         retVal = HXR_FAIL;
  2682.     }
  2683.     return retVal;
  2684. }
  2685. HX_RESULT CSmilDocumentRenderer::setValue(CSmilAnimateInfo* pInfo, CAttr* pValue,
  2686.                                           CAttr* pDepend, BOOL bUnderlyingValue)
  2687. {
  2688.     HX_RESULT retVal = HXR_OK;
  2689.     if (pInfo && pInfo->m_pSandwich && pValue)
  2690.     {
  2691.         // Get the target element id
  2692.         const char* pszID = pInfo->m_pSandwich->GetTargetElementID();
  2693.         // Get the target element tag
  2694.         SMILNodeTag eTag = pInfo->m_pSandwich->GetTargetElementTag();
  2695.         // Get the attribute name
  2696.         UINT32 ulAttr = pInfo->m_pSandwich->GetAttributeName();
  2697.         // Depending on the type of target element, we will
  2698.         // go lookup a different object
  2699.         if (eTag == SMILRegion)
  2700.         {
  2701.             CSmilBasicRegion* pRegion = getRegionByID(pszID);
  2702.             if (pRegion)
  2703.             {
  2704.                 switch (ulAttr)
  2705.                 {
  2706.                     case kAttrNameSoundLevel:
  2707.                         {
  2708.                             // XXXMEH - set the sound level - the core
  2709.                             // will call us back to get this value
  2710.                             pRegion->m_dSoundLevel = pValue->GetValueDouble();
  2711.                         }
  2712.                         break;
  2713.                     case kAttrNameZIndex:
  2714.                         {
  2715.                             // Get the computed z-index value
  2716.                             INT32 lZIndex = (INT32) (pValue->GetValueDouble() + 0.5);
  2717.                             // Set the z-index value in the CSmilBasicRegion
  2718.                             pRegion->m_lZIndex = lZIndex;
  2719.                             // XXXMEH - animation optimization
  2720.                             // Go ahead and resolve z-order here, but this 
  2721.                             // could be done more efficiently by collecting
  2722.                             // changes until the end.
  2723.                             resolveZOrder(getTopLevelBox(pRegion), m_ulCurrentTime);
  2724.                         }
  2725.                         break;
  2726.                     case kAttrNameBackgroundColor:
  2727.                         {
  2728.                             // Get the color
  2729.                             UINT32 ulRed   = (UINT32) pValue->GetValueDouble(0);
  2730.                             UINT32 ulGreen = (UINT32) pValue->GetValueDouble(1);
  2731.                             UINT32 ulBlue  = (UINT32) pValue->GetValueDouble(2);
  2732.                             UINT32 ulAlpha = (UINT32) pValue->GetValueDouble(3);
  2733.                             UINT32 ulColor = (ulAlpha << 24) | (ulRed << 16) |
  2734.                                              (ulGreen <<  8) | ulBlue;
  2735.                             // Set this color into the region
  2736.                             pRegion->m_ulBackgroundColor = ulColor;
  2737.                             // Set this color into the site user
  2738.                             if (pRegion->m_pSiteUser)
  2739.                             {
  2740.                                 // Get the CSmilSiteUser
  2741.                                 CSmilSiteUser* pUser = (CSmilSiteUser*) pRegion->m_pSiteUser;
  2742.                                 // Get the current background color
  2743.                                 UINT32 ulCurColor = pUser->GetBackgroundColor();
  2744.                                 // If it's different from the current color, then
  2745.                                 // change it
  2746.                                 if (ulColor != ulCurColor)
  2747.                                 {
  2748.                                     // Set the background color
  2749.                                     pUser->SetBackgroundColor(pRegion->m_ulBackgroundColor);
  2750.                                     // Queue the site for redraw
  2751.                                     queueSiteForAnimationRedraw(pRegion->m_pSite);
  2752. #if 0
  2753.                                     // XXXMEH - TEST - this is a further optimization, but
  2754.                                     // doesn't seem to be working due to a site bug, so ifdef
  2755.                                     // it out for now
  2756.                                     // Check to see if the "SiteNeverBlts" property
  2757.                                     // of the site needs to get updated
  2758.                                     if (isTransparent(ulColor) &&
  2759.                                         !isTransparent(ulCurColor))
  2760.                                     {
  2761.                                         setSiteProperty(pRegion->m_pSite, "SiteNeverBlts", "1");
  2762.                                     }
  2763.                                     else if (!isTransparent(ulColor) &&
  2764.                                              isTransparent(ulCurColor))
  2765.                                     {
  2766.                                         setSiteProperty(pRegion->m_pSite, "SiteNeverBlts", "0");
  2767.                                     }
  2768. #endif
  2769.                                 }
  2770.                             }
  2771.                         }
  2772.                         break;
  2773.                     case kAttrNameLeft:
  2774.                         pRegion->m_LayoutRect.m_dLeft       = pValue->GetValueDouble(0);
  2775.                         pRegion->m_LayoutRect.m_eLeftType   = pValue->GetCSS2Type(0);
  2776.                         queueRegionForRecompute(pRegion);
  2777.                         break;
  2778.                     case kAttrNameTop:
  2779.                         pRegion->m_LayoutRect.m_dTop        = pValue->GetValueDouble(1);
  2780.                         pRegion->m_LayoutRect.m_eTopType    = pValue->GetCSS2Type(1);
  2781.                         queueRegionForRecompute(pRegion);
  2782.                         break;
  2783.                     case kAttrNameRight:
  2784.                         pRegion->m_LayoutRect.m_dRight      = pValue->GetValueDouble(0);
  2785.                         pRegion->m_LayoutRect.m_eRightType  = pValue->GetCSS2Type(0);
  2786.                         queueRegionForRecompute(pRegion);
  2787.                         break;
  2788.                     case kAttrNameBottom:
  2789.                         pRegion->m_LayoutRect.m_dBottom     = pValue->GetValueDouble(0);
  2790.                         pRegion->m_LayoutRect.m_eBottomType = pValue->GetCSS2Type(0);
  2791.                         queueRegionForRecompute(pRegion);
  2792.                         break;
  2793.                     case kAttrNameWidth:
  2794.                         pRegion->m_LayoutRect.m_dWidth      = pValue->GetValueDouble(0);
  2795.                         pRegion->m_LayoutRect.m_eWidthType  = pValue->GetCSS2Type(0);
  2796.                         queueRegionForRecompute(pRegion);
  2797.                         break;
  2798.                     case kAttrNameHeight:
  2799.                         pRegion->m_LayoutRect.m_dHeight     = pValue->GetValueDouble(0);
  2800.                         pRegion->m_LayoutRect.m_eHeightType = pValue->GetCSS2Type(0);
  2801.                         queueRegionForRecompute(pRegion);
  2802.                         break;
  2803.                 }
  2804.             }
  2805.             else
  2806.             {
  2807.                 retVal = HXR_FAIL;
  2808.             }
  2809.         }
  2810.         else if (eTag == SMILAnchor)
  2811.         {
  2812.             // Find the CSmilAnchorElement object
  2813.             CSmilAnchorElement* pAnchor =
  2814.                 m_pSmilParser->getAnchorOrAreaElement(pInfo->m_pSandwich->GetTargetElementID());
  2815.             if (pAnchor)
  2816.             {
  2817.                 // Get the string value we want to set it to
  2818.                 const char* pszCoords = pValue->GetValueString();
  2819.                 if (pszCoords)
  2820.                 {
  2821.                     // Parse this string value
  2822.                     retVal = m_pSmilParser->parseAnchorCoords(pszCoords, pAnchor);
  2823.                 }
  2824.                 else
  2825.                 {
  2826.                     retVal = HXR_FAIL;
  2827.                 }
  2828.             }
  2829.             else
  2830.             {
  2831.                 retVal = HXR_FAIL;
  2832.             }
  2833.         }
  2834.         else if (eTag == SMILText       ||
  2835.                  eTag == SMILImg        ||
  2836.                  eTag == SMILRef        ||
  2837.                  eTag == SMILAudio      ||
  2838.                  eTag == SMILVideo      ||
  2839.                  eTag == SMILAnimation  ||
  2840.                  eTag == SMILTextstream ||
  2841.                  eTag == SMILBrush)
  2842.         {
  2843.             if (ulAttr == kAttrNameLeft   ||
  2844.                 ulAttr == kAttrNameTop    ||
  2845.                 ulAttr == kAttrNameRight  ||
  2846.                 ulAttr == kAttrNameBottom ||
  2847.                 ulAttr == kAttrNameWidth  ||
  2848.                 ulAttr == kAttrNameHeight)
  2849.             {
  2850.                 // Get the source
  2851.                 CSmilSource* pSource = getSource(pszID);
  2852.                 if (pSource)
  2853.                 {
  2854.                     // Set the attribute value
  2855.                     switch (ulAttr)
  2856.                     {
  2857.                         case kAttrNameLeft:
  2858.                             pSource->m_Rect.m_dLeft       = pValue->GetValueDouble();
  2859.                             pSource->m_Rect.m_eLeftType   = pValue->GetCSS2Type();
  2860.                             break;
  2861.                         case kAttrNameTop:
  2862.                             pSource->m_Rect.m_dTop        = pValue->GetValueDouble(1);
  2863.                             pSource->m_Rect.m_eTopType    = pValue->GetCSS2Type(1);
  2864.                             break;
  2865.                         case kAttrNameRight:
  2866.                             pSource->m_Rect.m_dRight      = pValue->GetValueDouble();
  2867.                             pSource->m_Rect.m_eRightType  = pValue->GetCSS2Type();
  2868.                             break;
  2869.                         case kAttrNameBottom:
  2870.                             pSource->m_Rect.m_dBottom     = pValue->GetValueDouble();
  2871.                             pSource->m_Rect.m_eBottomType = pValue->GetCSS2Type();
  2872.                             break;
  2873.                         case kAttrNameWidth:
  2874.                             pSource->m_Rect.m_dWidth      = pValue->GetValueDouble();
  2875.                             pSource->m_Rect.m_eWidthType  = pValue->GetCSS2Type();
  2876.                             break;
  2877.                         case kAttrNameHeight:
  2878.                             pSource->m_Rect.m_dHeight     = pValue->GetValueDouble();
  2879.                             pSource->m_Rect.m_eHeightType = pValue->GetCSS2Type();
  2880.                             break;
  2881.                     }
  2882.                     // XXXMEH - animation optimization
  2883.                     // We will go ahead and copy the new values to the site
  2884.                     // watcher, although it would be more efficient to collect
  2885.                     // the changes to the end and execute them together.
  2886.                     CSmilSiteWatcher* pWatcher = getRendererSiteWatcher(pszID);
  2887.                     if (pWatcher)
  2888.                     {
  2889.                         // Set the layout rect
  2890.                         pWatcher->SetSubRegionRect(pSource->m_Rect);
  2891.                         // Get the renderer site
  2892.                         IHXSite* pSite = NULL;
  2893.                         getRendererSite(pszID, pSite);
  2894.                         if (pSite)
  2895.                         {
  2896.                             // Re-position the site. It doesn't matter what
  2897.                             // position we pass in, because the site watcher's
  2898.                             // ChangingPosition() method will override it.
  2899.                             HXxPoint cPos = {1, 1};
  2900.                             pSite->SetPosition(cPos);
  2901.                             // Re-size the site. It doesn't matter what
  2902.                             // size we pass in, because the site watcher's
  2903.                             // ChangingSize() method will override it.
  2904.                             HXxSize cSize = {1, 1};
  2905.                             pSite->SetSize(cSize);
  2906.                         }
  2907.                         HX_RELEASE(pSite);
  2908.                     }
  2909.                 }
  2910.                 else
  2911.                 {
  2912.                     retVal = HXR_FAIL;
  2913.                 }
  2914.             }
  2915.             else if (ulAttr == kAttrNameZIndex ||
  2916.                      ulAttr == kAttrNameBackgroundColor)
  2917.             {
  2918.                 // Get the source
  2919.                 CSmilSource* pSource = getSource(pszID);
  2920.                 if (pSource)
  2921.                 {
  2922.                     // Get the region this is playing to
  2923.                     CSmilBasicRegion* pRegion = getRegionByID((const char*) pSource->m_region);
  2924.                     if (pRegion)
  2925.                     {
  2926.                         if (ulAttr == kAttrNameZIndex)
  2927.                         {
  2928.                             // Get the value to set
  2929.                             INT32 lZIndex = (INT32) (pValue->GetValueDouble() + 0.5);
  2930.                             // Set the z-index value in the CSmilBasicRegion
  2931.                             pRegion->m_lZIndex = lZIndex;
  2932.                             // XXXMEH - animation optimization
  2933.                             // Re-evaluate all the z-indices - note that
  2934.                             // we must re-evaluate from the parent of the region.
  2935.                             resolveZOrder(pRegion->m_pParent, m_ulCurrentTime);
  2936.                         }
  2937.                         else if (ulAttr == kAttrNameBackgroundColor)
  2938.                         {
  2939.                             // We are setting the backgroundColor for the region
  2940.                             // we are playing to
  2941.                             UINT32 ulRed   = (UINT32) pValue->GetValueDouble(0);
  2942.                             UINT32 ulGreen = (UINT32) pValue->GetValueDouble(1);
  2943.                             UINT32 ulBlue  = (UINT32) pValue->GetValueDouble(2);
  2944.                             UINT32 ulAlpha = (UINT32) pValue->GetValueDouble(3);
  2945.                             UINT32 ulColor = (ulAlpha << 24) | (ulRed << 16) |
  2946.                                              (ulGreen <<  8) | ulBlue;
  2947.                             // Get the site user for the region site
  2948.                             CSmilSiteUser* pUser = (CSmilSiteUser*) pRegion->m_pSiteUser;
  2949.                             if (pUser)
  2950.                             {
  2951.                                 // Check and make sure that a media backgroundColor
  2952.                                 // override did not just reset the color back to
  2953.                                 // the region color
  2954.                                 if (!bUnderlyingValue ||
  2955.                                     (bUnderlyingValue &&
  2956.                                      m_ulCurrentTime != pUser->GetLastMediaEndOverrideTime()))
  2957.                                 {
  2958.                                     // Set the background color
  2959.             pUser->SetBackgroundColor(ulColor);
  2960.                                 }
  2961.                             }
  2962.                             // XXXMEH - animation optimzation
  2963.                             // We will go ahead and force redraw on the site, but
  2964.                             // this can be optimized by collecting changes until
  2965.                             // the end of the animation
  2966.                             if (pRegion->m_pSite)
  2967.                             {
  2968.                                 HXxSize cSize = {0, 0};
  2969.                                 pRegion->m_pSite->GetSize(cSize);
  2970.                                 HXxRect cRect = {0, 0, cSize.cx, cSize.cy};
  2971.                                 pRegion->m_pSite->DamageRect(cRect);
  2972.                                 pRegion->m_pSite->ForceRedraw();
  2973.                             }
  2974.                         }
  2975.                     }
  2976.                     else
  2977.                     {
  2978.                         retVal = HXR_FAIL;
  2979.                     }
  2980.                 }
  2981.                 else
  2982.                 {
  2983.                     retVal = HXR_FAIL;
  2984.                 }