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

Symbian

开发平台:

Visual C++

  1. (float)fDur / 1000.0 );
  2.     urlString += extraURLparams;
  3.     extraURLparams = "";
  4.     chDelimiter = '&';
  5. }
  6. if ((UINT32)-1 !=
  7. pElement->m_ulClipBegin)
  8. {
  9.     extraURLparams.Format(
  10. "%cstart=%.3f", chDelimiter,
  11. (float)pElement->m_ulClipBegin/
  12. 1000.0 );
  13.     urlString += extraURLparams;
  14.     extraURLparams = "";
  15.     chDelimiter = '&';
  16. }
  17. if ((UINT32)-1 !=
  18. pElement->m_ulClipEnd)
  19. {
  20.     extraURLparams.Format(
  21. "%cend=%.3f", chDelimiter,
  22. (float)pElement->m_ulClipEnd/
  23. 1000.0 );
  24.     urlString += extraURLparams;
  25.     extraURLparams = "";
  26.     chDelimiter = '&';
  27. }
  28. if (HXR_OK == 
  29. pChildPlayer->QueryInterface(
  30. IID_IHXPlayer2, 
  31. (void**)&pPlayer2_Child))
  32. {
  33.     IHXRequest* pRequest = NULL;
  34.     IHXCommonClassFactory* pFactory=
  35.     m_pParent->getFactory();
  36.     if (pFactory)
  37.     {
  38. IHXRequest* pRequest = NULL;
  39. pFactory->CreateInstance(
  40. CLSID_IHXRequest,
  41. (void**) &pRequest);
  42. if (pRequest)
  43. {
  44.     pRequest->
  45. SetRequestHeaders(
  46. pValues);
  47.     pRequest->SetURL((const
  48. char*)urlString);
  49.     openrslt =
  50.     pPlayer2_Child->
  51.     OpenRequest(
  52.     pRequest);
  53. }
  54.     }
  55. }
  56. else // /No IHXPlayer2, so just call
  57.     // OpenURL() & see what happens:
  58. {
  59.     openrslt = pChildPlayer->
  60.     OpenURL((const char*)
  61.     urlString);
  62. }
  63. if (HXR_OK == openrslt)
  64. {
  65.     pChildPlayer->Begin();
  66. }
  67.     }
  68. }
  69.     }
  70. }
  71.                         // Release the request parameters
  72.                         HX_RELEASE(pReqVal);
  73.     }
  74. }
  75.     }
  76.     pValues->Release();
  77. }
  78.     }
  79. cleanup:
  80.     return rc;
  81. }
  82. HX_RESULT
  83. CSmilDocumentRenderer::handleSourceUpdate(CSmilSourceUpdate* pElement)
  84. {
  85.     HX_RESULT rc = HXR_OK;
  86.     const char* pszID = (const char*)pElement->m_srcID;
  87.     // determine whether this source has been initialized yet...
  88.     SMILPlayToAssoc* pPlayToAssoc = 0;
  89.     if(m_pPlayToAssocList)
  90.     {
  91. CHXSimpleList::Iterator i;
  92. for(i=m_pPlayToAssocList->Begin();i!=m_pPlayToAssocList->End();++i)
  93. {
  94.     SMILPlayToAssoc* pThisAssoc = (SMILPlayToAssoc*)(*i);
  95.     if(pThisAssoc->m_id == pszID  &&
  96.     // /Added this while re-fixing PR 69639; be sure to
  97.     // ignore already-stopped track & keep looking in
  98.     // case element restart made new track w/same id:
  99.     !pThisAssoc->m_bTrackStopped)
  100.     {
  101. pPlayToAssoc = pThisAssoc;
  102. break;
  103.     }
  104. }
  105.     }
  106.     if(pPlayToAssoc &&
  107.        pPlayToAssoc->m_sourceMap.GetCount() > 0)
  108.     {
  109.         rc = doSourceUpdate(pPlayToAssoc, pElement);
  110.     }
  111.     else
  112.     {
  113. // stick it into the deferred map,
  114. // it will be handled in RendererInitialized()
  115. if(!m_pDeferredSourceMap)
  116. {
  117.     m_pDeferredSourceMap = new CHXMapStringToOb;
  118. }
  119. SMILDeferredSourceInfo* pInfo = new SMILDeferredSourceInfo;
  120. // /XXXEH- if duration is pure of delay, here, tell pInfo so (need pInfo to have new flag var):
  121. pInfo->m_ulDuration = pElement->m_ulUpdatedDuration;
  122. pInfo->m_ulDelay = 0;
  123. // /Fixes mem leak when pszID is already in the map:
  124. SMILDeferredSourceInfo* pTmpInfo;
  125. if (m_pDeferredSourceMap->Lookup(pszID, (void*&)pTmpInfo))
  126. {
  127.     HX_DELETE(pTmpInfo);
  128. }
  129. (*m_pDeferredSourceMap)[pszID] = pInfo;
  130.     }
  131.     return rc;
  132. }
  133. // /Immediately removes a track that's associated with the source:
  134. // Returns HXR_OK only if the track was found and RemoveTrack(n)
  135. // succeeded:
  136. HX_RESULT CSmilDocumentRenderer::handleTrackRemoval(const char* pszID, INT32 nGroupNum)
  137. {
  138.     HX_RESULT retVal = HXR_FAIL;
  139. #if defined(HELIX_FEATURE_SMIL2_ANIMATION)
  140.     // First we have to check if this is an animation
  141.     if (pszID && m_pAnimationMap)
  142.     {
  143.         void* pVoid = NULL;
  144.         m_pAnimationMap->Lookup(pszID, pVoid);
  145.         if (pVoid)
  146.         {
  147.             // Yes, this is an animation, so clear the return value
  148.             retVal = HXR_OK;
  149.             // Now call removeAnimation with this element
  150.             CSmilAnimateElement* pAnim = (CSmilAnimateElement*) pVoid;
  151.             removeAnimation(pAnim);
  152.         }
  153.     }
  154. #endif /* #if defined(HELIX_FEATURE_SMIL2_ANIMATION) */
  155.     // If we are still currently in a failed state, then 
  156.     // it wasn't an animation.
  157.     if (FAILED(retVal))
  158.     {
  159.         IHXGroup* pGroup = 0;
  160.         if(m_pGroupMap && 
  161.            m_pGroupMap->Lookup(nGroupNum, (void*&)pGroup))
  162.         {
  163.             // determine whether this source has been started yet:
  164.             SMILPlayToAssoc* pPlayToAssoc = NULL;
  165.             if(m_pPlayToAssocList)
  166.             {
  167.                 CHXSimpleList::Iterator i;
  168.                 for(i=m_pPlayToAssocList->Begin();
  169.                         i!=m_pPlayToAssocList->End();++i)
  170.                 {
  171.                     SMILPlayToAssoc* pThisAssoc = (SMILPlayToAssoc*)(*i);
  172.                     if (pThisAssoc->m_id == pszID  &&
  173.     // /Added this while re-fixing PR 69639; be sure to
  174.     // ignore already-stopped track & keep looking in
  175.     // case element restart made new track w/same id:
  176.     !pThisAssoc->m_bTrackStopped)
  177.                     {
  178.                         pPlayToAssoc = pThisAssoc;
  179.                         break;
  180.                     }
  181.                 }
  182.             }
  183.             if (pPlayToAssoc)
  184.             {
  185. #if defined(_DEBUG)  &&  defined(XXXEH_DEBUGOUT_TRACKSTOPPAUSERESUME)
  186. {
  187. FILE* f1 = ::fopen("c:\smil2AddDuration.txt", "a+");
  188. ::fprintf(f1, "CSmilDocumentRenderer::handleTrackRemoval(ID=%s, group=%ld)n",
  189. (const char*)pszID, nGroupNum);
  190. ::fclose(f1);
  191. }
  192. #endif
  193. // /Fixes PR 81253: old value in m_pDeferredSourceMap
  194. // has old (first-play) duration so updateStreamTiming() was
  195. // getting called with that (now-wrong) value when
  196. // rendererInitialized() got called if this track restarted,
  197. // resulting in wrong presentation duration.  So, remove old
  198. // reference to that element from the map here:
  199. if (m_pDeferredSourceMap)
  200. {
  201.     SMILDeferredSourceInfo* pDeferredInfo = NULL;
  202.     const char* pDeferredID = (const char*)pPlayToAssoc->m_id;
  203.     if (m_pDeferredSourceMap->Lookup(pDeferredID,
  204.     (void*&)pDeferredInfo))
  205.     {
  206. CSmilElement* pThisElement = 
  207. m_pSmilParser->findElement(pDeferredID);
  208. HX_ASSERT(pThisElement);
  209. HX_DELETE(pDeferredInfo);
  210. BOOL bRemovedKeyOK =
  211. m_pDeferredSourceMap->RemoveKey(pDeferredID);
  212. HX_ASSERT(bRemovedKeyOK);
  213.     }
  214. }
  215.                 pPlayToAssoc->m_bRemovePending = TRUE;
  216. if (m_bInTrackDurationSetCall)
  217. {
  218.     retVal = HXR_OK;
  219.     // /Helps fix PR 66391: call RemoveTrack() later, after
  220.     // TrackDurationSet() has finished, otherwise core crashes
  221.     // when it continues to use the removed-and-deleted
  222.     // pStream in SourceInfo::SetupRenderer():
  223.     if (!m_pDeferrededRemoveTrackMap)
  224.     {
  225. m_pDeferrededRemoveTrackMap = new CHXMapStringToOb();
  226.     }
  227.     if (m_pDeferrededRemoveTrackMap)
  228.     {
  229. // /Don't add it if it's already in the map:
  230. if (!(*m_pDeferrededRemoveTrackMap)[pszID])
  231. {
  232.     // /Add remove-track ID to the map for deferring
  233.     // calling RemoveTrack() until the core is ready:
  234.     CHXString* pCPNStrID = new CHXString(pszID);
  235.     if (pCPNStrID)
  236.     {
  237. (*m_pDeferrededRemoveTrackMap)[pszID] =
  238. (void*)pCPNStrID;
  239.     }
  240. }
  241.     }
  242.     else
  243.     {
  244. retVal = HXR_OUTOFMEMORY;
  245.     }
  246. }
  247. else
  248. {
  249.     retVal = pGroup->RemoveTrack(pPlayToAssoc->m_uTrackIndex);
  250. }
  251.     }
  252.         }
  253.     }
  254.     return retVal;
  255. }
  256. // /Immediately pauses a track that's associated with the source:
  257. // Returns HXR_OK only if the track was found and PauseTrack(n)
  258. // succeeded:
  259. // /pTimeVal gets created and filled with data that makes it a watcher
  260. // for the endEvent of the "pauser" so that the element getting paused
  261. // here can resume at that time, if and when it happens:
  262. HX_RESULT
  263. CSmilDocumentRenderer::handleTrackPausing(SMILNode* pNode,
  264. LONG32 lTimeOfPause,
  265. SMILPriorityClassPauseDisplay pauseDisplay,
  266. const char* pIdOfPauser)
  267. {
  268.     HX_RESULT rc = HXR_FAILED;
  269.     IHXGroup* pGroup = 0;
  270.     if(m_pGroupMap && 
  271.        m_pGroupMap->Lookup((INT32)pNode->m_nGroup, (void*&)pGroup))
  272.     {
  273.         // /QI for IHXGroup2
  274.         IHXGroup2* pGroup2 = NULL;
  275.         pGroup->QueryInterface(IID_IHXGroup2, (void**) &pGroup2);
  276.         if (pGroup2)
  277.         {
  278.     // /Determine whether this source has been started yet:
  279.     SMILPlayToAssoc* pPlayToAssoc = NULL;
  280.     if(m_pPlayToAssocList)
  281.     {
  282. CHXSimpleList::Iterator i;
  283. for(i=m_pPlayToAssocList->Begin();
  284. i!=m_pPlayToAssocList->End();++i)
  285. {
  286.     SMILPlayToAssoc* pThisAssoc = (SMILPlayToAssoc*)(*i);
  287.     if(pThisAssoc->m_id == pNode->m_id  &&
  288.     // /Helps re-fix PR 69639; be sure to ignore
  289.     // already-stopped track & keep looking in case
  290.     // element restart made new track w/same id:
  291.     !pThisAssoc->m_bTrackStopped)
  292.     {
  293. pPlayToAssoc = pThisAssoc;
  294. break;
  295.     }
  296. }
  297.     }
  298.     if (pPlayToAssoc)
  299.     {
  300. IHXTrack* pHXTrack = NULL;
  301. rc = pGroup2->GetIHXTrack(pPlayToAssoc->m_uTrackIndex,
  302. pHXTrack);
  303. if (pHXTrack)
  304. {
  305. #if defined(_DEBUG)  &&  defined(XXXEH_DEBUGOUT_TRACKSTOPPAUSERESUME)
  306. {
  307. FILE* f1 = ::fopen("c:\smil2AddDuration.txt", "a+");
  308. ::fprintf(f1, "CSmilDocumentRenderer::handleTrackPausing(ID=%s,"
  309.   " timeOfPause=%ld, ID of pauser=%s)n",
  310. (const char*)pNode->m_id, lTimeOfPause, (const char*)pIdOfPauser);
  311. ::fclose(f1);
  312. }
  313. #endif
  314.     rc = pHXTrack->Pause();
  315.     // /Ceate a new SmilTimeValue watching for endEvent
  316.     // on pIdOfPauser
  317.     SmilTimeValue* pTimeVal = new SmilTimeValue(m_pContext,
  318.     /* Don't care what start line is:*/ 0,
  319.     pNode->m_pElement);
  320.     if(pTimeVal)
  321.     {
  322. CHXString pStr = pIdOfPauser;
  323. pStr += ".resumeEvent";
  324. HX_RESULT pnr1 = pTimeVal->parseValue(pStr,
  325. SMILSyncAttrBegin, (const char*)pNode->m_id);
  326. HX_RESULT pnr2= pTimeVal->setPauseTime(lTimeOfPause);
  327. HX_ASSERT(HXR_OK == pnr2);
  328. // /Note: this function takes care of getting rid of
  329. // any existing resumeEvent on this element; since it
  330. // can only be in the "resume stack" once:
  331. BOOL bOldResumeEventWasRemoved = FALSE;
  332. HX_RESULT rslt = m_pSmilParser->addResumeEvent(
  333. pTimeVal, bOldResumeEventWasRemoved);
  334. #if defined(_DEBUG)
  335. if (bOldResumeEventWasRemoved)
  336. {
  337.     bOldResumeEventWasRemoved = 1;// /DEBUG-ONLY CODE
  338. }
  339. #endif
  340.     }
  341. }
  342. HX_RELEASE(pHXTrack);
  343.     }
  344. }
  345.         HX_RELEASE(pGroup2);
  346.     }
  347.     return rc;
  348. }
  349. // /Immediately resumes a track that's associated with the source:
  350. // Returns HXR_OK only if the track was found and PlayTrack(n)
  351. // succeeded:
  352. HX_RESULT
  353. CSmilDocumentRenderer::handleTrackResuming(const char* pID, INT32 nGroupNum)
  354. {
  355.     HX_RESULT rc = HXR_FAILED;
  356.     IHXGroup* pGroup = 0;
  357.     if(m_pGroupMap && 
  358.        m_pGroupMap->Lookup(nGroupNum, (void*&)pGroup))
  359.     {
  360. // /QI for IHXGroup2
  361. IHXGroup2* pGroup2 = NULL;
  362. pGroup->QueryInterface(IID_IHXGroup2, (void**) &pGroup2);
  363. if (pGroup2)
  364. {
  365.     // /XXXEH- TODO: OPTIMIZATION: use "getPlayToAssocByMedia(pID)"
  366.     // here instead (?):
  367.     // /Determine whether this source has been started yet:
  368.     SMILPlayToAssoc* pPlayToAssoc = NULL;
  369.     if(m_pPlayToAssocList)
  370.     {
  371. CHXSimpleList::Iterator i;
  372. for(i=m_pPlayToAssocList->Begin();
  373. i!=m_pPlayToAssocList->End();++i)
  374. {
  375.     SMILPlayToAssoc* pThisAssoc = (SMILPlayToAssoc*)(*i);
  376.     if (pThisAssoc->m_id == pID  &&
  377.     // /Added this while re-fixing PR 69639; be sure to
  378.     // ignore already-stopped track & keep looking in
  379.     // case element restart made new track w/same id:
  380.     !pThisAssoc->m_bTrackStopped)
  381.     {
  382. pPlayToAssoc = pThisAssoc;
  383. break;
  384.     }
  385. }
  386.     }
  387.     HX_ASSERT(pPlayToAssoc);
  388.     if (pPlayToAssoc)
  389.     {
  390. IHXTrack* pHXTrack = NULL;
  391. rc = pGroup2->GetIHXTrack(pPlayToAssoc->m_uTrackIndex,
  392. pHXTrack);
  393. HX_ASSERT(pHXTrack);
  394. if (pHXTrack)
  395. {
  396.     if (isMediaPausedAndDisabled(pID))
  397.     {
  398. // /Handle un-blocking of mouse events and changing
  399. // site appearance back to normal:
  400. if (!reenablePausedAndDisabledMedia(pID,
  401. (UINT16)nGroupNum))
  402. {
  403.     HX_ASSERT(0);
  404. }
  405.     }
  406.     // /XXXEH- TODO- OPTIMIZATION: only need to do this if
  407.     // pauseDisplay == "hide" but we'll need a map for that,
  408.     // as well:
  409.     else
  410.     {
  411. CSmilBasicRegion* pRegion = NULL;
  412. if(pPlayToAssoc)
  413. {
  414.     // First, assume that pPlayTo is an id and see
  415.     // if we can find the region by id:
  416.     pRegion = getRegionByID(pPlayToAssoc->m_playTo);
  417.     if (!pRegion)
  418.     {
  419. // We didn't find it by id, so try to find it
  420. // by regionName:
  421. pRegion = getFirstRegionByName(
  422. pPlayToAssoc->m_playTo);
  423.     }
  424. }
  425. if (pRegion  &&  m_pSiteInfoList)
  426. {
  427.     CHXSimpleList::Iterator i =
  428.     m_pSiteInfoList->Begin();
  429.     for(; i != m_pSiteInfoList->End(); ++i)
  430.     {
  431. SMILSiteInfo* pSiteInfo =(SMILSiteInfo*)(*i);
  432. if(pSiteInfo->m_uGroupIndex ==
  433. m_uCurrentGroupIndex  &&
  434. pSiteInfo->m_MediaID ==
  435. pPlayToAssoc->m_id)
  436. {
  437.     IHXSite* pRegionSite = NULL;
  438.     CSmilBasicRegion* pCurRegion =
  439.     getRegionByID(
  440.     pSiteInfo->m_regionID);
  441.     if (pCurRegion  !=  pRegion)
  442.     {
  443. HX_ASSERT(pRegion);
  444. continue;
  445.     }
  446.     // /Helps fix PR 81510 (& dup. PR 83796):
  447.     // z-ordering code can put it at top of
  448.     // z-order of siblings who have already
  449.     // played to same region or otherwise have
  450.     // same z-index, by looking at this value:
  451.     if (m_ulCurrentTime > 0)
  452.     {
  453. pSiteInfo->m_ulResumeTime =
  454. m_ulCurrentTime-1;
  455.     }
  456.     if(pRegion->m_eBackgroundColorType ==
  457.     CSS2TypeTransparent)
  458.     {
  459. pRegionSite =
  460. pSiteInfo->m_pRegionSite;
  461.     }
  462.     // /Show site as it resumes:
  463.     CSmilShowSiteEvent* pShowEvent = 
  464.     new CSmilShowSiteEvent(
  465.     pPlayToAssoc->m_uGroupIndex,
  466.     // /Add a few millisec so it
  467.     // won't re-hide when it starts:
  468.     m_ulCurrentTime + 10, 
  469.     pSiteInfo->m_pRendererSite,
  470.     pRegion->m_pSite,
  471.     TRUE, // /ShowSite=TRUE
  472.     FALSE,
  473.     this,
  474.     pPlayToAssoc->m_id,
  475.     pRegion->m_region,
  476.     pRegion->m_eShowBackground);
  477.     insertEvent(pShowEvent);
  478. }
  479.     }
  480. }
  481.     }
  482. #if defined(_DEBUG)  &&  defined(XXXEH_DEBUGOUT_TRACKSTOPPAUSERESUME)
  483. {
  484. FILE* f1 = ::fopen("c:\smil2AddDuration.txt", "a+");
  485. ::fprintf(f1, "CSmilDocumentRenderer::handleTrackResuming(ID=%s, group=%ld)n",
  486. (const char*)pID, nGroupNum);
  487. ::fclose(f1);
  488. }
  489. #endif
  490.     rc = pHXTrack->Begin();
  491. }
  492. HX_RELEASE(pHXTrack);
  493.     }
  494. }
  495. HX_RELEASE(pGroup2);
  496.     }
  497.     return rc;
  498. }
  499. HX_RESULT CSmilDocumentRenderer::handleEndLayout(CSmilEndLayout* pElement)
  500. {
  501.     HX_RESULT retVal = HXR_OK;
  502.     // Set the flag saying we DO have a <layout> element
  503.     m_bLayoutElementPresent = TRUE;
  504.     // Decide if we have an "empty layout" condition, which
  505.     // is where we just have:
  506.     // <layout>
  507.     // </layout>
  508.     // but nothing inside it. So therefore we have empty layout
  509.     // if at this point all of the following are true:
  510.     // a) we have no <root-layout> element
  511.     // b) we have no <region> elements
  512.     // c) we have no <regPoint> elements
  513.     // d) we have no <topLayout> elements
  514.     if ((!m_pRegionMap    ||
  515.          (m_pRegionMap &&  m_pRegionMap->GetCount() == 0)) &&
  516.         (!m_pRootLayout   ||
  517.          (m_pRootLayout && !m_pRootLayout->IsRootLayoutElementPresent())) &&
  518.         (!m_pRegPointMap  ||
  519.          (m_pRegPointMap && m_pRegPointMap->GetCount() == 0)) &&
  520.         (!m_pViewportList ||
  521.          (m_pViewportList && m_pViewportList->GetCount() == 0)))
  522.     {
  523.         m_bEmptyLayout = TRUE;
  524.     }
  525.     // Decide if we need to set up the root-layout at 
  526.     // this point or later. We should only attempt to
  527.     // setup the root layout here if either: a) both
  528.     // root layout width and height are valid; OR
  529.     // b) we have some <region> children of the root layout
  530.     // defined. If we have (a), we know we will succeed,
  531.     // but if (b) we may or may not succeed.
  532.     if (m_pRootLayout &&
  533.         ((m_pRootLayout->IsWidthSet() &&
  534.           m_pRootLayout->IsHeightSet()) ||
  535.          (m_pRootLayout->m_pChildList &&
  536.           m_pRootLayout->m_pChildList->GetCount() > 0)))
  537.     {
  538.         // We need to attempt to set up the root layout
  539.         // without yet assigning defaults
  540.         HX_RESULT rv = setupRootLayout(FALSE);
  541.         if (SUCCEEDED(rv))
  542.         {
  543.             // Set the flag saying we've done the
  544.             // root-layout setup
  545.             m_bIsRootLayoutSetup = TRUE;
  546.         }
  547.         else
  548.         {
  549.             // Ok, we have regions which are children
  550.             // of the root-layout, but we could not
  551.             // groc the size of the root-layout from
  552.             // the regions. So we will try again, this
  553.             // time assigning defaults if necessary.
  554.             // This should succeed.
  555.             rv = setupRootLayout(TRUE);
  556.             if (SUCCEEDED(rv))
  557.             {
  558.                 // Set the flag saying we've done the
  559.                 // root-layout setup
  560.                 m_bIsRootLayoutSetup = TRUE;
  561.             }
  562.         }
  563.     }
  564. #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT)
  565.     // Decide if we need to do viewport setup here.
  566.     // We should only attempt to do viewport setup
  567.     // here if, of course, there is at least one
  568.     // viewport defined.
  569.     if (m_pViewportList &&
  570.         m_pViewportList->GetCount() > 0)
  571.     {
  572.         // Setup any viewports
  573.         HX_RESULT rv = setupViewports();
  574.     }
  575. #endif /* #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT) */
  576.     return retVal;
  577. }
  578. HX_RESULT
  579. CSmilDocumentRenderer::handleMeta(CSmilMeta* pElement)
  580. {
  581.     HX_RESULT rc = HXR_OK;
  582.     IHXPlayer* pPlayer = m_pParent->getPlayer();
  583.     IHXGroupManager* pMgr = NULL;
  584.     IHXValues* pValues = NULL;
  585.     if(pElement->m_name.GetLength() > 0)
  586.     {
  587. if(HXR_OK == pPlayer->QueryInterface(IID_IHXGroupManager, (void**)&pMgr))
  588. {
  589.     pValues = pMgr->GetPresentationProperties();
  590.     if(!pValues)
  591.     {
  592. pValues = new CHXOrderedValues;
  593. pValues->AddRef();
  594. pMgr->SetPresentationProperties(pValues);
  595.     }
  596.     IHXBuffer* pBuf = new CHXBuffer;
  597.     pBuf->AddRef();
  598.     pBuf->Set((BYTE*)(const char*)pElement->m_content,
  599. pElement->m_content.GetLength()+1);
  600.     pValues->SetPropertyCString((const char*)pElement->m_name,
  601. pBuf);
  602.     pBuf->Release();
  603.     pValues->Release();
  604.     pMgr->Release();
  605. }
  606.     }
  607.     return rc;
  608. }
  609. HX_RESULT
  610. CSmilDocumentRenderer::handleMetadata(CSmilMetadata* pElement)
  611. {
  612.     HX_RESULT rc = HXR_OK;
  613.     if (m_bMetadataPassedOffAlready) // /We send all metadata in one big chunk.
  614.     {
  615. return rc;
  616.     }
  617.     m_bMetadataPassedOffAlready = TRUE;
  618.     IHXPlayer* pPlayer = m_pParent->getPlayer();
  619.     IHXGroupManager* pMgr = NULL;
  620.     IHXValues* pValues = NULL;
  621.     if(m_metadata.GetLength() > 0)
  622.     {
  623. if(HXR_OK == pPlayer->QueryInterface(IID_IHXGroupManager, (void**)&pMgr))
  624. {
  625.     pValues = pMgr->GetPresentationProperties();
  626.     if(!pValues)
  627.     {
  628. pValues = new CHXOrderedValues;
  629. pValues->AddRef();
  630. pMgr->SetPresentationProperties(pValues);
  631.     }
  632.     IHXBuffer* pBuf = new CHXBuffer;
  633.     pBuf->AddRef();
  634.     pBuf->Set((BYTE*)(const char*)m_metadata,
  635. m_metadata.GetLength()+1);
  636.     pValues->SetPropertyCString("metadata", pBuf);
  637.     pBuf->Release();
  638.     pValues->Release();
  639.     pMgr->Release();
  640. }
  641.     }
  642. #if defined (XXX_DUMP_METADATA_TO_FILE)
  643. {FILE* f = ::fopen("c:\temp\metadata.txt", "w");
  644.     if (f)
  645.     {
  646. ::fprintf(f,"METADATA:{{{n%sn}}}n", (const char*)m_metadata);
  647. ::fclose(f);
  648.     }
  649. }
  650. #endif
  651.     return rc;
  652. }
  653. HX_RESULT
  654. CSmilDocumentRenderer::handleRendererPreFetch(CSmilRendererPreFetch *pRend)
  655. {
  656.     HX_RESULT rc = HXR_OK;
  657.     const char* pMimeType = (const char*)pRend->m_mimeType;
  658.     IHXRendererUpgrade* pUpgrade = 0;
  659.     if(m_pContext)
  660.     {
  661. IHXSystemRequired* pISystemRequired = NULL;
  662. m_pContext->QueryInterface(IID_IHXSystemRequired, 
  663.     (void**)&pISystemRequired);
  664. CHXBuffer* pBuffer = new CHXBuffer;
  665. pBuffer->AddRef();
  666. pBuffer->Set((BYTE*)pMimeType, strlen(pMimeType)+1);
  667. if (pISystemRequired)
  668. {
  669.     IHXUpgradeCollection* pUpgradeCollection = NULL;
  670.     IHXPlayer* pPlayer = m_pParent->getPlayer();     
  671.     if(pPlayer)
  672. pPlayer->QueryInterface(IID_IHXUpgradeCollection, (void**)&pUpgradeCollection);
  673.     if(pUpgradeCollection)
  674.     {
  675. pUpgradeCollection->Add(eUT_Required, pBuffer, 0, 0);
  676. // HasFeatures() calls removes all existing features from pUpgradeCollection.
  677. pISystemRequired->HasFeatures(pUpgradeCollection);
  678.     }
  679.     HX_RELEASE(pUpgradeCollection);
  680.     HX_RELEASE(pISystemRequired);
  681. }
  682. HX_RELEASE(pBuffer);
  683.     }
  684.     return rc;
  685. }
  686. HX_RESULT
  687. CSmilDocumentRenderer::insertEvent(CSmilLayoutEvent* pEvent)
  688. {
  689.     const char* pszMediaID  = "NULL";
  690.     const char* pszRegionID = "NULL";
  691.     if (pEvent &&
  692.         (pEvent->m_type == CSmilLayoutEvent::eShowSite ||
  693.          pEvent->m_type == CSmilLayoutEvent::eHideSite))
  694.     {
  695.         CSmilShowSiteEvent* pShow = (CSmilShowSiteEvent*) pEvent;
  696.         pszMediaID  = pShow->getMediaID();
  697.         pszRegionID = pShow->getRegionID();
  698.     }
  699.     MLOG_EVENT(m_pErrorMessages,
  700.                "insertEvent() (%s,%lu,%u,%lu,%lu,%s,%s) tick=%lun",
  701.                pEvent->getEventTypeName(),
  702.                pEvent->m_ulEventTime,
  703.                pEvent->m_uGroupIndex,
  704.                pEvent->m_bOnlyHideSite,
  705.                pEvent->m_bIgnorEvent,
  706.                pszMediaID,
  707.                pszRegionID,
  708.                HX_GET_BETTERTICKCOUNT());
  709.     if(!m_pEventList)
  710.     {
  711. m_pEventList = new CHXSimpleList;
  712.     }
  713.     LISTPOSITION lPos = m_pEventList->GetHeadPosition();
  714.     LISTPOSITION lPrev = lPos;
  715.     BOOL bInserted = FALSE;
  716.     BOOL bFoundOurShow = FALSE;
  717.     while(lPos)
  718.     {
  719. CSmilLayoutEvent* pThisEvent = 
  720.     (CSmilLayoutEvent*)m_pEventList->GetNext(lPos);
  721. if((pThisEvent->m_type == CSmilLayoutEvent::eShowSite || 
  722.     pThisEvent->m_type == CSmilLayoutEvent::eHideSite) &&
  723.     pThisEvent->m_ulEventTime == pEvent->m_ulEventTime &&
  724.     pThisEvent->getRegionSite() == pEvent->getRegionSite())
  725. {
  726.     if(pEvent->m_type == CSmilLayoutEvent::eShowSite)
  727.     {
  728. if(!lPos)
  729. {
  730.     m_pEventList->AddTail(pEvent);
  731.     bInserted = TRUE;
  732.     break;
  733. }
  734. // find position of last 'hide' event at this time
  735. // move past all non show events at this time...
  736. while(lPos &&
  737.     pThisEvent->m_ulEventTime == pEvent->m_ulEventTime &&
  738.     pThisEvent->getRegionSite() == pEvent->getRegionSite() &&
  739.     pThisEvent->m_type != CSmilLayoutEvent::eShowSite)
  740. {
  741.     lPrev = lPos;
  742.     pThisEvent = (CSmilLayoutEvent*)m_pEventList->GetNext(lPos);
  743. }
  744.     }
  745.     // move past any Transition events at this time...
  746.     while (lPos &&
  747. pThisEvent->m_ulEventTime == pEvent->m_ulEventTime &&
  748. (pThisEvent->m_type == CSmilLayoutEvent::eBeginTransition ||
  749. pThisEvent->m_type == CSmilLayoutEvent::eEndTransition) )
  750.     {
  751. lPrev = lPos;
  752. pThisEvent = (CSmilLayoutEvent*)m_pEventList->GetNext(lPos);
  753.     }
  754.     
  755.     m_pEventList->InsertBefore(lPrev, pEvent);
  756.     bInserted = TRUE;
  757.     break;
  758. }
  759. if ((pEvent->m_type == CSmilLayoutEvent::eBeginTransition ||
  760.     pEvent->m_type == CSmilLayoutEvent::eEndTransition) &&
  761.     pThisEvent->m_ulEventTime == pEvent->m_ulEventTime)
  762. {
  763.     // we want transitions to be put before this event..
  764.     m_pEventList->InsertBefore(lPrev, pEvent);
  765.     bInserted = TRUE;
  766.     break;
  767. }
  768. else if(pThisEvent->m_ulEventTime > pEvent->m_ulEventTime)
  769. {
  770.     if (pEvent->m_type == CSmilLayoutEvent::eHideSite)
  771.     {
  772. // if we are a hide event, check to see if there is 
  773. // a hide event in the future for our same region, and
  774. // a different renderer site, if so, modifiy this
  775. // event so it will only hide the renderer...
  776. // lPos  -- position of pThisEvent (past were we want to be inserted)
  777. // lPrev -- start here so we will also consider pThisEvent..
  778. LISTPOSITION next = lPrev;
  779. while (next)
  780. {
  781.     CSmilLayoutEvent* pFutureEvent = (CSmilLayoutEvent*)m_pEventList->GetAt(next);
  782.     
  783.     if (pFutureEvent->getRegionSite() == pEvent->getRegionSite() &&
  784. pFutureEvent->getRendererSite() != pEvent->getRendererSite())
  785.     {
  786. if (pFutureEvent->m_type == CSmilLayoutEvent::eHideSite)
  787. {
  788.     pEvent->m_bOnlyHideSite = TRUE;
  789.     break;
  790. }
  791. // as soon as we find a show event for this same region
  792. // and a different site, we can stop.
  793. else if (pFutureEvent->m_type == CSmilLayoutEvent::eShowSite)
  794. {
  795.     break;
  796. }
  797.     }
  798.     m_pEventList->GetNext(next);
  799. }
  800.     }
  801.     
  802.     m_pEventList->InsertBefore(lPrev, pEvent);
  803.     bInserted = TRUE;
  804.     break;
  805. }
  806. else if (pEvent->m_type == CSmilLayoutEvent::eHideSite &&
  807.     pThisEvent->m_type == CSmilLayoutEvent::eShowSite &&
  808.     pThisEvent->getRegionSite() == pEvent->getRegionSite() &&
  809.     pThisEvent->getRendererSite() == pEvent->getRendererSite())
  810. {
  811.     // note that we have passed the show event for our site
  812.     bFoundOurShow = TRUE;
  813. }
  814. else if (pEvent->m_type == CSmilLayoutEvent::eHideSite &&
  815.     pThisEvent->m_type == CSmilLayoutEvent::eHideSite &&
  816.     pThisEvent->getRegionSite() == pEvent->getRegionSite() &&
  817.     pThisEvent->getRendererSite() != pEvent->getRendererSite()
  818.     && bFoundOurShow)
  819. {
  820.     // if we are inserting a hide event, after the current hide event,
  821.     // and the current hide event goes to the same region as the current 
  822.     // hide event, && the renderer sites are different, then we need
  823.     // to modify this event so that it does not hide the region's site...
  824.     pThisEvent->m_bOnlyHideSite = TRUE;
  825. }
  826. lPrev = lPos;
  827.     }
  828.     if(!bInserted)
  829.     {
  830. // not inserted, stick it on the end of the list
  831. m_pEventList->AddTail(pEvent);
  832.     }
  833.     // set list position member
  834.     m_ulEventListPosition = m_pEventList->GetHeadPosition();
  835.     MLOG_EVENT(m_pErrorMessages, "tdumping event queue after insertionn");
  836. //    DumpEventQueue();
  837.     return HXR_OK;
  838. }
  839. CSmilShowSiteEvent* CSmilDocumentRenderer::getShowHideEvent(const char* pszMediaID,
  840.                                                             const char* pszRegionID,
  841.                                                             BOOL        bShowEvent)
  842. {
  843.     CSmilShowSiteEvent* pRet = NULL;
  844.     if (m_pEventList && pszMediaID && pszRegionID)
  845.     {
  846.         LISTPOSITION pos = m_pEventList->GetHeadPosition();
  847.         while (pos)
  848.         {
  849.             CSmilLayoutEvent* pEvent =
  850.                 (CSmilLayoutEvent*) m_pEventList->GetNext(pos);
  851.             if (pEvent &&
  852.                 (pEvent->m_type == CSmilLayoutEvent::eShowSite ||
  853.                  pEvent->m_type == CSmilLayoutEvent::eHideSite))
  854.             {
  855.                 CSmilShowSiteEvent* pShowEvent = (CSmilShowSiteEvent*) pEvent;
  856.                 if (pShowEvent->getShowSite() == bShowEvent &&
  857.                     !strcmp(pszMediaID, pShowEvent->getMediaID()) &&
  858.                     !strcmp(pszRegionID, pShowEvent->getRegionID()))
  859.                 {
  860.                     pRet = pShowEvent;
  861.                     break;
  862.                 }
  863.             }
  864.         }
  865.     }
  866.     return pRet;
  867. }
  868. #if defined(HELIX_FEATURE_SMIL2_ANIMATION)
  869. CSmilAnimateEvent* CSmilDocumentRenderer::getAnimateEvent(CSmilAnimateElement* pAnim)
  870. {
  871.     CSmilAnimateEvent* pRet = NULL;
  872.     if (m_pEventList && pAnim)
  873.     {
  874.         LISTPOSITION pos = m_pEventList->GetHeadPosition();
  875.         while (pos)
  876.         {
  877.             CSmilLayoutEvent* pEvent =
  878.                 (CSmilLayoutEvent*) m_pEventList->GetNext(pos);
  879.             if (pEvent &&
  880.                 pEvent->m_type == CSmilLayoutEvent::eAnimate)
  881.             {
  882.                 CSmilAnimateEvent* pAnimEvent = (CSmilAnimateEvent*) pEvent;
  883.                 if (pAnimEvent->isSameElement(pAnim))
  884.                 {
  885.                     pRet = pAnimEvent;
  886.                     break;
  887.                 }
  888.             }
  889.         }
  890.     }
  891.     return pRet;
  892. }
  893. #endif /* #if defined(HELIX_FEATURE_SMIL2_ANIMATION) */
  894. void CSmilDocumentRenderer::removeEvent(CSmilLayoutEvent* pEvent)
  895. {
  896.     if (pEvent && m_pEventList)
  897.     {
  898.         LISTPOSITION pos = m_pEventList->GetHeadPosition();
  899.         while (pos)
  900.         {
  901.             CSmilLayoutEvent* pListEvent =
  902.                 (CSmilLayoutEvent*) m_pEventList->GetAt(pos);
  903.             if (pListEvent == pEvent)
  904.             {
  905.                 m_pEventList->RemoveAt(pos);
  906.                 break;
  907.             }
  908.             m_pEventList->GetNext(pos);
  909.         }
  910.     }
  911. }
  912. HX_RESULT
  913. CSmilDocumentRenderer::insertSiteInfo(void* pVoidInfo)
  914. {
  915.     if(!m_pSiteInfoList)
  916.     {
  917. m_pSiteInfoList = new CHXSimpleList;
  918.     }
  919.     SMILSiteInfo* pInfo = (SMILSiteInfo*)pVoidInfo;
  920.     LISTPOSITION lPos = m_pSiteInfoList->GetHeadPosition();
  921.     LISTPOSITION lPrev = lPos;
  922.     BOOL bInserted = FALSE;
  923.     while(lPos)
  924.     {
  925. SMILSiteInfo* pThisInfo = 
  926.     (SMILSiteInfo*)m_pSiteInfoList->GetNext(lPos);
  927. if(pThisInfo->m_ulDelay > pInfo->m_ulDelay)
  928. {
  929.     m_pSiteInfoList->InsertBefore(lPrev, pInfo);
  930.     bInserted = TRUE;
  931.     break;
  932. }
  933. lPrev = lPos;
  934.     }
  935.     if(!bInserted)
  936.     {
  937. // not inserted, stick it on the end of the list
  938. m_pSiteInfoList->AddTail(pInfo);
  939.     }
  940.     return HXR_OK;
  941. }
  942. void CSmilDocumentRenderer::removeSiteInfo(SMILSiteInfo* pSiteInfo)
  943. {
  944.     if (m_pSiteInfoList && pSiteInfo)
  945.     {
  946.         LISTPOSITION pos = m_pSiteInfoList->GetHeadPosition();
  947.         while (pos)
  948.         {
  949.             SMILSiteInfo* pInfo =
  950.                 (SMILSiteInfo*) m_pSiteInfoList->GetAt(pos);
  951.             if (pInfo == pSiteInfo)
  952.             {
  953.                 m_pSiteInfoList->RemoveAt(pos);
  954.                 break;
  955.             }
  956.             m_pSiteInfoList->GetNext(pos);
  957.         }
  958.     }
  959. }
  960. HX_RESULT
  961. CSmilDocumentRenderer::onTimeSync(UINT32 ulTimeValue)
  962. {
  963.     MLOG_TIMESYNC(m_pErrorMessages, "onTimeSync(%lu) tick=%lun", ulTimeValue,
  964.                   HX_GET_BETTERTICKCOUNT());
  965.     HX_RESULT rc = HXR_OK;
  966.     m_ulCurrentTime = ulTimeValue;
  967.     if(!m_bFirstTimeSync)
  968.     {
  969. // draw background and regions
  970. m_bFirstTimeSync = TRUE;
  971. // now I should force a background redraw...
  972. if(m_pRootLayout->m_pSite)
  973. {
  974.             forceFullRedraw(m_pRootLayout->m_pSite);
  975.     if(m_pRegionMap)
  976.     {
  977. CHXMapStringToOb::Iterator i = m_pRegionMap->Begin();
  978. for(; i != m_pRegionMap->End(); ++i)
  979. {
  980.     CSmilBasicRegion* pRegion = (CSmilBasicRegion*)(*i);
  981.     if (pRegion)
  982.     {
  983.                         forceFullRedraw(pRegion->m_pSite);
  984.     }
  985. }
  986.     }
  987. }
  988.     }
  989.     rc = flushAllEvents( ulTimeValue, TRUE );
  990.     // /Helps fix PR 66391: it should now be OK to call RemoveTrack() on each
  991.     // track that was added and subsequently found to begin too late to play
  992.     // once its parent's duration became resolved:
  993.     if (m_pDeferrededRemoveTrackMap)
  994.     {
  995. CHXMapStringToOb::Iterator i = m_pDeferrededRemoveTrackMap->Begin();
  996. for(; i != m_pDeferrededRemoveTrackMap->End(); ++i)
  997. {
  998.     CHXString* pID = (CHXString*)(*i);
  999.             // Get the playTo for this media and then the group and track#:
  1000.             SMILPlayToAssoc* pPlayToAsso = pID?
  1001.     // /Changing to (*pID) instead of (pID) properly fixes
  1002.     // PR 66391 which wasn't working for implicit IDs.  It's a
  1003.     // bit scary that the prior code *worked* for explicit IDs
  1004.     // which were stored in the smallString of the CHXString:
  1005.     getPlayToAssocByMedia((const char*)(*pID)) : NULL;
  1006.     HX_ASSERT(pPlayToAsso);
  1007.             if (pPlayToAsso)
  1008.             {
  1009.                 UINT16 usGroup = pPlayToAsso->m_uGroupIndex;
  1010. IHXGroup* pGroup = 0;
  1011. if (m_pGroupMap  &&  m_pGroupMap->Lookup(usGroup, (void*&)pGroup))
  1012. {
  1013.     HX_RESULT pnrRemoveTrackRetVal =
  1014.     pGroup->RemoveTrack(pPlayToAsso->m_uTrackIndex);
  1015.     HX_ASSERT(HXR_OK == pnrRemoveTrackRetVal);
  1016. }
  1017.     }
  1018.     HX_DELETE(pID); // /Whole list gets deleted, below.
  1019. }
  1020. // /Delete the whole list:
  1021. HX_DELETE(m_pDeferrededRemoveTrackMap);
  1022.     }
  1023.     if (m_pActiveTransitions)
  1024.     {
  1025. // cycle through all the active transitions...
  1026. LISTPOSITION lpos = m_pActiveTransitions->GetHeadPosition();
  1027. while (lpos)
  1028. {
  1029.     SMILTransitionState* pState = 
  1030. (SMILTransitionState*)m_pActiveTransitions->GetAt(lpos);
  1031.     if (ulTimeValue < pState->m_ulEndTime)
  1032.     {
  1033. doTransition(lpos, ulTimeValue);
  1034. m_pActiveTransitions->GetNext(lpos);
  1035.     }
  1036.     else
  1037.     {
  1038. doTransition(lpos, pState->m_ulEndTime);
  1039. lpos = m_pActiveTransitions->RemoveAt(lpos);
  1040. HX_RELEASE(pState->m_pSiteTransition);
  1041. HX_DELETE(pState);
  1042.     }
  1043. }
  1044.     }
  1045. #if defined(HELIX_FEATURE_SMIL2_ANIMATION)
  1046.     // We want to cap the time at the duration of
  1047.     // the current group - we don't want to send
  1048.     // a timesync that is greater than the duration.
  1049.     UINT32 ulAnimTime = ulTimeValue;
  1050.     if (ulAnimTime > m_ulCurGroupDuration &&
  1051.         m_ulCurGroupDuration > 0)
  1052.     {
  1053.         ulAnimTime = m_ulCurGroupDuration;
  1054.     }
  1055.     // Do all the active animations
  1056.     if (m_pActiveAnimations && m_pActiveAnimations->GetCount() > 0)
  1057.     {
  1058.         if (atLeastOneActiveAnimation(ulAnimTime))
  1059.         {
  1060.             if (!isSiteCompositionModeON())
  1061.             {
  1062.                 turnSiteCompositionModeON();
  1063.             }
  1064.         }
  1065.         // m_pAnimSiteRedrawMap is a list of sites
  1066.         // which need to ForceRedraw() as a result on an
  1067.         // animation on this time sync.
  1068.         if (!m_pAnimSiteRedrawMap)
  1069.         {
  1070.             m_pAnimSiteRedrawMap = new CHXMapPtrToPtr();
  1071.         }
  1072.         if (m_pAnimSiteRedrawMap)
  1073.         {
  1074.             m_pAnimSiteRedrawMap->RemoveAll();
  1075.         }
  1076.         // m_pAnimRegionRecomputeMap is a list of sites
  1077.         // which need to ForceRedraw() as a result on an
  1078.         // animation on this time sync.
  1079.         if (!m_pAnimRegionRecomputeMap)
  1080.         {
  1081.             m_pAnimRegionRecomputeMap = new CHXMapPtrToPtr();
  1082.         }
  1083.         if (m_pAnimRegionRecomputeMap)
  1084.         {
  1085.             m_pAnimRegionRecomputeMap->RemoveAll();
  1086.         }
  1087.         // m_pAnimTopLayoutMap is a collection of topLayout's
  1088.         // which have been animated programmatically and
  1089.         // need resizing.
  1090.         if (m_pAnimTopLayoutMap)
  1091.         {
  1092.             m_pAnimTopLayoutMap->RemoveAll();
  1093.         }
  1094.         // Clear the animate root layout flag
  1095.         m_bAnimateRootLayout = FALSE;
  1096.         // If there is a soundlevel animation going on, then
  1097.         // we need to try to grab the mutex
  1098.         if (m_pSoundLevelMutex) m_pSoundLevelMutex->Lock();
  1099.         // Send this time to all active animations
  1100.         LISTPOSITION pos = m_pActiveAnimations->GetHeadPosition();
  1101.         while (pos)
  1102.         {
  1103.             CSmilAnimateInfo* pInfo = (CSmilAnimateInfo*) m_pActiveAnimations->GetAt(pos);
  1104.             if (pInfo && pInfo->m_pSandwich &&
  1105.                 pInfo->m_pSandwich->GetAttributeName() != kAttrNameSoundLevel)
  1106.             {
  1107.                 // Execute the animation at this time
  1108.                 doAnimation(pInfo, ulAnimTime);
  1109.                 // Are there any layers left in the sandwich?
  1110.                 if (pInfo->m_pSandwich->GetNumLayers())
  1111.                 {
  1112.                     // There are still some layers left, so
  1113.                     // leave the sandwich alone and just advance
  1114.                     // to the next animation
  1115.                     m_pActiveAnimations->GetNext(pos);
  1116.                 }
  1117.                 else
  1118.                 {
  1119.                     // There are no more layers left in the
  1120.                     // sandwich, so this animation is done. So,
  1121.                     // we need to restore whatever original values
  1122.                     // were present
  1123.                     setValue(pInfo, pInfo->m_pUnder, pInfo->m_pDepend, TRUE);
  1124.                     // Now we need to delete this info object
  1125.                     HX_DELETE(pInfo);
  1126.                     // And remove it from the list
  1127.                     // We have to do the following hack since
  1128.                     // CHXSimpleList does not advance the position to 
  1129.                     // NULL if you RemoveAt() the last element in the list.
  1130.                     BOOL bLast = (m_pActiveAnimations->GetAt(pos) ==
  1131.                                   m_pActiveAnimations->GetTail());
  1132.                     pos        = m_pActiveAnimations->RemoveAt(pos);
  1133.                     if (bLast && pos)
  1134.                     {
  1135.                         m_pActiveAnimations->GetNext(pos);
  1136.                     }
  1137.                 }
  1138.             }
  1139.             else
  1140.             {
  1141.                 m_pActiveAnimations->GetNext(pos);
  1142.             }
  1143.         }
  1144.         // If there is a soundlevel animation going on, then
  1145.         // we can now release the mutex
  1146.         if (m_pSoundLevelMutex) m_pSoundLevelMutex->Unlock();
  1147.         // Recompute the root-layout if necessary
  1148.         if (m_bAnimateRootLayout && m_pRootLayout && m_pRootLayout->m_pRoot)
  1149.         {
  1150.             HXxSize cNewRootSize = {0, 0};
  1151.             cNewRootSize.cx = (INT32) floor(m_pRootLayout->m_pRoot->m_dWidth  + 0.5);
  1152.             cNewRootSize.cy = (INT32) floor(m_pRootLayout->m_pRoot->m_dHeight + 0.5);
  1153.             SiteSizeChanged(m_pRootLayout->m_pSite, &cNewRootSize);
  1154.         }
  1155. #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT)
  1156.         // Animate any topLayout's
  1157.         if (m_pAnimTopLayoutMap &&
  1158.             m_pAnimTopLayoutMap->GetCount() > 0)
  1159.         {
  1160.             POSITION mpos = m_pAnimTopLayoutMap->GetStartPosition();
  1161.             while (mpos)
  1162.             {
  1163.                 void* pKey = NULL;
  1164.                 void* pVal = NULL;
  1165.                 m_pAnimTopLayoutMap->GetNextAssoc(mpos, pKey, pVal);
  1166.                 if (pKey)
  1167.                 {
  1168.                     CSmilBasicViewport* pVP = (CSmilBasicViewport*) pKey;
  1169.                     if (pVP && pVP->m_pPort)
  1170.                     {
  1171.                         HXxSize cNewRootSize = {0, 0};
  1172.                         cNewRootSize.cx = (INT32) floor(pVP->m_pPort->m_dWidth  + 0.5);
  1173.                         cNewRootSize.cy = (INT32) floor(pVP->m_pPort->m_dHeight + 0.5);
  1174.                         SiteSizeChanged(pVP->m_pSite, &cNewRootSize);
  1175.                     }
  1176.                 }
  1177.             }
  1178.             // Clear the map
  1179.             m_pAnimTopLayoutMap->RemoveAll();
  1180.         }
  1181. #endif /* #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT) */
  1182.         // We've collected all the regions for which
  1183.         // we need to call recomputeBoxLayout()
  1184.         if (m_pAnimRegionRecomputeMap)
  1185.         {
  1186.             POSITION mpos = m_pAnimRegionRecomputeMap->GetStartPosition();
  1187.             while (mpos)
  1188.             {
  1189.                 void* pKey = NULL;
  1190.                 void* pVal = NULL;
  1191.                 m_pAnimRegionRecomputeMap->GetNextAssoc(mpos, pKey, pVal);
  1192.                 if (pKey)
  1193.                 {
  1194.                     CSmilBasicRegion* pRegion = (CSmilBasicRegion*) pKey;
  1195.                     recomputeBoxLayout(pRegion, TRUE);
  1196.                 }
  1197.             }
  1198.             // Clear the map
  1199.             m_pAnimRegionRecomputeMap->RemoveAll();
  1200.         }
  1201.         // We've collected all the sites which need
  1202.         // a ForceRedraw(), so do that now
  1203.         if (m_pAnimSiteRedrawMap)
  1204.         {
  1205.             POSITION mpos = m_pAnimSiteRedrawMap->GetStartPosition();
  1206.             while (mpos)
  1207.             {
  1208.                 void* pKey = NULL;
  1209.                 void* pVal = NULL;
  1210.                 m_pAnimSiteRedrawMap->GetNextAssoc(mpos, pKey, pVal);
  1211.                 if (pKey)
  1212.                 {
  1213.                     IHXSite* pSite = (IHXSite*) pKey;
  1214.                     forceFullRedraw(pSite);
  1215.                 }
  1216.             }
  1217.             // Clear the map
  1218.             m_pAnimSiteRedrawMap->RemoveAll();
  1219.         }
  1220.         unlockSiteComposition();
  1221.         bltSiteComposition();
  1222.         lockSiteComposition();
  1223.     }
  1224.     if (!atLeastOneActiveAnimation(ulAnimTime))
  1225.     {
  1226.         if (isSiteCompositionModeON())
  1227.         {
  1228.             turnSiteCompositionModeOFF();
  1229. //            forceFullRecursiveRedraw(m_pRootLayout);
  1230.         }
  1231.     }
  1232. #endif /* #if defined(HELIX_FEATURE_SMIL2_ANIMATION) */
  1233.     BOOL bSomeElementScheduleWasChanged = FALSE;
  1234.     CHXSimpleList pauseDisplayHideElementList;
  1235.     CHXSimpleList pauseDisplayDisableElementList;
  1236.     if (m_pHandlePendingSchedulingCallback &&
  1237. m_pHandlePendingSchedulingCallback->m_bIsCallbackPending)
  1238.     {
  1239. m_pHandlePendingSchedulingCallback->m_bIsCallbackPending = FALSE;
  1240. m_pScheduler->Remove(m_pHandlePendingSchedulingCallback->m_PendingHandle);
  1241. m_pHandlePendingSchedulingCallback->m_PendingHandle = 0;
  1242.     }
  1243.     HX_RESULT tmprslt =
  1244.     m_pSmilParser->handlePendingScheduling(m_ulCurrentTime,
  1245.     m_uCurrentGroupIndex,
  1246.     bSomeElementScheduleWasChanged,
  1247.     &pauseDisplayHideElementList,
  1248.     &pauseDisplayDisableElementList);
  1249.     if (SUCCEEDED(tmprslt)  &&  bSomeElementScheduleWasChanged)
  1250.     {
  1251. CHXSimpleList* pWhichList = NULL;
  1252. BOOL bDoHide = TRUE;
  1253. if (!pauseDisplayHideElementList.IsEmpty())
  1254. {
  1255.     pWhichList = &pauseDisplayHideElementList;
  1256.     bDoHide = TRUE;
  1257. }
  1258. else if (!pauseDisplayDisableElementList.IsEmpty())
  1259. {
  1260.     pWhichList = &pauseDisplayDisableElementList;
  1261.     bDoHide = FALSE;
  1262. }
  1263. if (pWhichList)
  1264. {
  1265.     LISTPOSITION listPos =
  1266.     pWhichList->GetHeadPosition();
  1267.     while (listPos)
  1268.     {
  1269. LISTPOSITION lPosOfCurTmpVal = listPos;
  1270. // /Gets val at listPos and then moves listPos to next node:
  1271. CHXString* pCStrId = (CHXString*)pWhichList->GetNext(listPos);
  1272. if (pCStrId)
  1273. {
  1274.     SMILPlayToAssoc* pPlayToAssoc = getPlayToAssocByMedia(
  1275.     (const char*)(*pCStrId));
  1276.     CSmilBasicRegion* pRegion = NULL;
  1277.     if(pPlayToAssoc)
  1278.     {
  1279. // First, assume that pPlayTo is an id and see
  1280. // if we can find the region by id:
  1281. pRegion = getRegionByID(pPlayToAssoc->m_playTo);
  1282. if (!pRegion)
  1283. {
  1284.     // We didn't find it by id, so try to find it
  1285.     // by regionName:
  1286.     pRegion = getFirstRegionByName(
  1287.     pPlayToAssoc->m_playTo);
  1288. }
  1289.     }
  1290.     HX_ASSERT(pRegion  &&  m_pSiteInfoList);
  1291.     if (pRegion)
  1292.     {
  1293. if(m_pSiteInfoList)
  1294. {
  1295.     CHXSimpleList::Iterator i =
  1296.     m_pSiteInfoList->Begin();
  1297.     for(; i != m_pSiteInfoList->End(); ++i)
  1298.     {
  1299. SMILSiteInfo* pSiteInfo =(SMILSiteInfo*)(*i);
  1300. if(pSiteInfo->m_uGroupIndex ==
  1301. m_uCurrentGroupIndex  &&
  1302. pSiteInfo->m_MediaID ==
  1303. pPlayToAssoc->m_id)
  1304. {
  1305.     IHXSite* pRegionSite = NULL;
  1306.     CSmilBasicRegion* pCurRegion =
  1307.     getRegionByID(
  1308.     pSiteInfo->m_regionID);
  1309.     if (pCurRegion  !=  pRegion)
  1310.     {
  1311. HX_ASSERT(pRegion);
  1312. continue;
  1313.     }
  1314.     if(pRegion->m_eBackgroundColorType ==
  1315.     CSS2TypeTransparent)
  1316.     {
  1317. pRegionSite =
  1318. pSiteInfo->m_pRegionSite;
  1319.     }
  1320.     if (bDoHide)
  1321.     {
  1322. // /Hide site while it's paused:
  1323. CSmilShowSiteEvent* pHideEvent = 
  1324. new CSmilShowSiteEvent(
  1325. pPlayToAssoc->m_uGroupIndex,
  1326. // /Add a few millisec so it
  1327. // won't "unhide" when other
  1328. // track starts (fixes
  1329. // PR 50708):
  1330. m_ulCurrentTime + 10, 
  1331. pSiteInfo->m_pRendererSite,
  1332. pRegion->m_pSite,
  1333. FALSE, // /ShowSite=FALSE
  1334. FALSE,
  1335. this,
  1336. pPlayToAssoc->m_id,
  1337. pRegion->m_region,
  1338. pRegion->m_eShowBackground);
  1339. insertEvent(pHideEvent);
  1340. // /Note: don't break here as there
  1341. // might be multiple sites to which
  1342. // this media is currently playing:
  1343.     }
  1344.     else // /pauseDisplay == "disable":
  1345.     {
  1346. #if defined(XXXEH_NEED_TO_ADD_51_PRCNT_OPAQUE_SITE_ON_TOP_TO_DISABLE)
  1347. // /Create a child of the region site
  1348. IHXSite* pTempSite = NULL;
  1349. HX_RESULT retVal = pSiteInfo->
  1350. m_pRendererSite->CreateChild(
  1351. pTempSite);
  1352. if (SUCCEEDED(retVal))
  1353. {
  1354.     // /Add the site to the manager:
  1355.     retVal = m_pSiteMgr->AddSite(
  1356.     pTempSite);
  1357.     HXxSize cSize;
  1358.     pSiteInfo->m_pRendererSite->GetSize(cSize);
  1359.     HXxPoint cPos;
  1360.     pSiteInfo->m_pRendererSite->GetPosition(cPos);
  1361.     pTempSite->SetSize(cSize);
  1362.     pTempSite->SetPosition(cPos);
  1363.     if (SUCCEEDED(retVal))
  1364.     {
  1365. showSite(pTempSite, TRUE);
  1366. // /Do we need to do this too?!:
  1367. HXxRect cRect = {0, 0, cSize.cx, cSize.cy};
  1368. pTempSite->DamageRect(cRect);
  1369. pTempSite->ForceRedraw();
  1370.     }
  1371. }
  1372. #else /* Otherwise just disable the site so it won't handle mouse events: */
  1373.       /*Also, QI the renderer site for IHXVideoControl (YUV renderers only)
  1374.         and adjust the brightness down by 50% */
  1375. // /Put media ID into the map:
  1376. if(!m_pPausedAndDisabledIDMap)
  1377. {
  1378.     m_pPausedAndDisabledIDMap =
  1379.     new CHXMapStringToOb;
  1380. }
  1381. CHXString* pCStr = new CHXString;
  1382. const char* pID = (const char*)
  1383. (*pCStrId);
  1384. if (pCStr)
  1385. {
  1386.     *pCStr = pID;
  1387.     // /Prevents mem leak when pID is
  1388.     // already in the map:
  1389.     CHXString* pTmpCStr;
  1390.     if (m_pPausedAndDisabledIDMap->
  1391.     Lookup(pID,
  1392.     (void*&)pTmpCStr))
  1393.     {
  1394. HX_DELETE(pTmpCStr);
  1395.     }
  1396.     (*m_pPausedAndDisabledIDMap)[pID] =
  1397.     pCStr;
  1398. }
  1399. // /Now, adjust the brightness of the
  1400. // site if we can:
  1401. IHXVideoControl* pVidCntrls = NULL;
  1402. HX_RESULT pnrVC =
  1403. pSiteInfo->m_pRendererSite->
  1404. QueryInterface(IID_IHXVideoControl,
  1405. (void**)&pVidCntrls);
  1406. if (SUCCEEDED(pnrVC))
  1407. {
  1408.     // /Save this and reset it in
  1409.     // during handleTrackResuming():
  1410.     float fBrightness =
  1411. pVidCntrls->GetBrightness();
  1412.     // /Put media ID into the map:
  1413.     if(!m_pPausedAndDisabledBrightnessMap)
  1414.     {
  1415. m_pPausedAndDisabledBrightnessMap =
  1416. new CHXMapStringToOb;
  1417.     }
  1418.     
  1419.     float* pfPrePauseBrightness =
  1420.     new float;
  1421.     if (pfPrePauseBrightness)
  1422.     {
  1423. *pfPrePauseBrightness =
  1424. fBrightness;
  1425. // /Prevents mem leak when pID
  1426. // is already in the map:
  1427. float* pfTmp;
  1428. if (m_pPausedAndDisabledBrightnessMap->
  1429. Lookup(pID,
  1430. (void*&)pfTmp))
  1431. {
  1432.     HX_DELETE(pfTmp);
  1433. }
  1434. (*m_pPausedAndDisabledBrightnessMap)[pID] =
  1435. pfPrePauseBrightness;
  1436.     }
  1437.     float fPausedBrightness =
  1438.     (fBrightness < -25? -90:
  1439.     fBrightness - 75);
  1440.     HX_RESULT rsltSetBrtness =
  1441.     pVidCntrls->SetBrightness(
  1442.     fPausedBrightness);
  1443.     pSiteInfo->m_pRendererSite->
  1444.     ForceRedraw();
  1445.     HX_RELEASE(pVidCntrls);
  1446. }
  1447. #endif
  1448.     }
  1449. }
  1450.     }
  1451. }
  1452.     }
  1453. }
  1454. // /Remove it from the list:
  1455. HX_DELETE(pCStrId);
  1456. pWhichList->RemoveAt(lPosOfCurTmpVal);
  1457.     }
  1458. }
  1459. handleElements();
  1460.     }
  1461.     if (SUCCEEDED(rc))
  1462.     {
  1463. rc = tmprslt;
  1464.     }
  1465.     // /Don't do this at time zero otherwise current player doesn't have
  1466.     // time to get up and running:
  1467.     if (m_ulCurrentTime > 100)
  1468.     {
  1469. // /findNextPendingOnLoadURL finds next "automatic" hyperlink, i.e.,
  1470. // hyperlink whose a/anchor/area tags has 'actuate="onLoad"' in it:
  1471. CHXMapStringToOb* pMapOfAnchorsToLaunchAtCurTime =
  1472. m_pSmilParser->findNextPendingOnLoadURL(m_ulCurrentTime);
  1473. if (pMapOfAnchorsToLaunchAtCurTime)
  1474. {
  1475.     // /Now, go through all onLoad anchors found and launch them all:
  1476.     CHXMapStringToOb::Iterator i =
  1477.     pMapOfAnchorsToLaunchAtCurTime->Begin();
  1478.     for(; i != pMapOfAnchorsToLaunchAtCurTime->End(); ++i)
  1479.     {
  1480. CSmilAAnchorElement* pAnchor = (CSmilAAnchorElement*)(*i);
  1481. if (!pAnchor)
  1482. {
  1483.     HX_ASSERT(pAnchor);
  1484.     continue;
  1485. }
  1486. // /NOTE: be sure to do the following LAST in this function in
  1487. // case the launching of an URL replaces this smlrendr instance.
  1488. // /Launch the URL;
  1489. HX_RESULT rcHLT = handleHyperlinkTraversal(pAnchor);
  1490.     }
  1491.     HX_DELETE(pMapOfAnchorsToLaunchAtCurTime);
  1492. }
  1493.     }
  1494.     return rc;
  1495. }
  1496. void
  1497. CSmilDocumentRenderer::RemoveEvents(UINT32 ulGroupIndex, IHXSite* pSite)
  1498. {
  1499.     // handle all events up to time ulFlushToTime + ulGranularity
  1500.     HX_RESULT rc = HXR_OK;
  1501.     if(m_pEventList)
  1502.     {
  1503. LISTPOSITION lPos = m_pEventList->GetHeadPosition();
  1504. while(lPos && m_pEventList->GetCount())
  1505. {
  1506.     // handle all events at or before ulTimeValue
  1507.     CSmilLayoutEvent* pEvent = (CSmilLayoutEvent*)m_pEventList->GetAt(lPos);
  1508.     if(pEvent->m_uGroupIndex == ulGroupIndex &&
  1509.        pEvent->getRendererSite() == pSite)
  1510.     {
  1511. HX_DELETE(pEvent);
  1512. lPos = m_pEventList->RemoveAt(lPos);
  1513.     }
  1514.     else
  1515.     {
  1516. m_pEventList->GetNext(lPos);
  1517.     }
  1518. }
  1519. // set list position member
  1520. m_ulEventListPosition = m_pEventList->GetHeadPosition();
  1521.     }
  1522.     return;
  1523. }
  1524. HX_RESULT CSmilDocumentRenderer::flushAllEvents( UINT32 ulFlushToTime, BOOL bBreak)
  1525. {
  1526.     // handle all events up to time ulFlushToTime + ulGranularity
  1527.     HX_RESULT rc = HXR_OK;
  1528.     if(m_pEventList && m_pEventList->GetCount() > 0)
  1529.     {
  1530. //LISTPOSITION lPos = m_pEventList->GetHeadPosition();
  1531. while(m_ulEventListPosition)
  1532. {
  1533.     // handle events which have eventTime<=ulFlushToTime+ulGranularity
  1534.     // also only handle events that are in the current group, in case
  1535.     // events for the next group have been added to the event list.
  1536.     CSmilLayoutEvent* pEvent
  1537. = (CSmilLayoutEvent*) m_pEventList->GetAt(m_ulEventListPosition);
  1538.    
  1539. #ifdef _MACINTOSH
  1540.     // XXXBobClark:
  1541.     // On the Mac side, our site's ShowSite implementation
  1542.     // draws synchronously: right then. On Windows, it draws
  1543.     // asynchronously by setting up a callback. The upshot is
  1544.     // that on Windows you can get away with a ShowSite(TRUE)
  1545.     // followed immediately by a ShowSite(FALSE), because the
  1546.     // actual screen won't get updated while the site is
  1547.     // briefly visible. But on the Mac it will show a visible
  1548.     // flicker. So the interim workaround here is to check the
  1549.     // events we're flushing; if we're showing a site that will
  1550.     // be hidden by the time the flush is done (or vice versa),
  1551.     // we ignore that event.
  1552.     // XXXMEH - Note that this code was written when there was
  1553.     // only show and hide events. Now that there are other events,
  1554.     // we need to make sure we only operate on show and hide events
  1555.     LISTPOSITION tempPos = m_ulEventListPosition;
  1556.     BOOL bCurrentEventCancelledOutByFutureEvent = FALSE;
  1557.     if (pEvent->IsShowOrHideEvent())
  1558.     {
  1559. CSmilShowSiteEvent* pCurrentEvent = (CSmilShowSiteEvent*)pEvent;
  1560. m_pEventList->GetNext(tempPos); // to start with the next position...
  1561. while (tempPos)
  1562. {
  1563.     CSmilLayoutEvent* pFutureLayoutEvent = (CSmilLayoutEvent*) m_pEventList->GetAt(tempPos);
  1564.     if (!pFutureLayoutEvent || !pFutureLayoutEvent->IsShowOrHideEvent())
  1565.     {
  1566. break;
  1567.     }
  1568.     CSmilShowSiteEvent* pFutureEvent = (CSmilShowSiteEvent*)m_pEventList->GetAt(tempPos);
  1569.     if ( !pFutureEvent
  1570.  || pFutureEvent->m_ulEventTime > ulFlushToTime)
  1571.     {
  1572. break;
  1573.     }
  1574.     
  1575.     if ( pFutureEvent && pCurrentEvent
  1576.     && pCurrentEvent->getRendererSite() == pFutureEvent->getRendererSite()
  1577.     && pCurrentEvent->getRegionSite() == pFutureEvent->getRegionSite()
  1578.     && pCurrentEvent->getShowSite() != pFutureEvent->getShowSite() )
  1579.     {
  1580. bCurrentEventCancelledOutByFutureEvent = TRUE;
  1581. break;
  1582.     }
  1583.     
  1584.     m_pEventList->GetNext(tempPos);
  1585. }
  1586.     }
  1587. #endif
  1588.             // no need of granularity since the core will
  1589.             // ensure we call OnTimeSync at the end of its duration
  1590.             if (pEvent &&
  1591.                 (m_uCurrentGroupIndex == -1 || pEvent->m_uGroupIndex == m_uCurrentGroupIndex) &&
  1592.                 pEvent->m_ulEventTime <= ulFlushToTime) //XXXMERGE
  1593.             {
  1594. #ifdef _MACINTOSH
  1595.                 if (!bCurrentEventCancelledOutByFutureEvent)
  1596.                 {
  1597. #endif
  1598.                    if (!pEvent->getHandledFlag())
  1599.                    {
  1600.                        rc = pEvent->handleEvent(ulFlushToTime);
  1601.                        pEvent->setHandledFlag(TRUE);
  1602.                    }
  1603. #ifdef _MACINTOSH
  1604.                 }
  1605. #endif
  1606.             }
  1607.             else if( bBreak )
  1608.             {
  1609.                 break;
  1610.             }
  1611.             BOOL bRemoveEvent = FALSE;
  1612. #if defined(HELIX_FEATURE_SMIL2_ANIMATION)
  1613.             // If this is an animate event and it begins
  1614.             // an animation on some SMIL event, then we
  1615.             // should remove this CSmilLayoutEvent from
  1616.             // the queue after executing it.
  1617.             if (pEvent->m_type == CSmilLayoutEvent::eAnimate)
  1618.             {
  1619.                 CSmilAnimateEvent* pAnimEvent = (CSmilAnimateEvent*) pEvent;
  1620.                 if (pAnimEvent->hasEventBasedBegin())
  1621.                 {
  1622.                     bRemoveEvent = TRUE;
  1623.                 }
  1624.             }
  1625. #endif /* #if defined(HELIX_FEATURE_SMIL2_ANIMATION) */
  1626.             if (bRemoveEvent)
  1627.             {
  1628.                 // Remove the event from the queue
  1629.                 m_ulEventListPosition = m_pEventList->RemoveAt(m_ulEventListPosition);
  1630.                 // Delete the event
  1631.                 HX_DELETE(pEvent);
  1632.             }
  1633.             else
  1634.             {
  1635.                 m_pEventList->GetNext(m_ulEventListPosition);
  1636.             }
  1637. }
  1638.     }
  1639.     return rc;
  1640. }
  1641. BOOL
  1642. CSmilDocumentRenderer::IsFullScreen()
  1643. {
  1644.     BOOL bRet = FALSE;
  1645.     if (m_pRootLayout->m_pSite)
  1646.     {
  1647. IHXSiteFullScreen* pFull = NULL;
  1648. m_pRootLayout->m_pSite->QueryInterface(IID_IHXSiteFullScreen, (void**) &pFull);
  1649. if (pFull)
  1650. {
  1651.     bRet = pFull->IsFullScreen();
  1652. }
  1653. HX_RELEASE(pFull);
  1654.     }
  1655.     return bRet;
  1656. }
  1657. #if defined(HELIX_FEATURE_SMIL2_ANIMATION)
  1658. void CSmilDocumentRenderer::startSoundLevelAnimation(CSmilAnimateInfo* pInfo)
  1659. {
  1660.     MLOG_ANIM(m_pErrorMessages,"startSoundLevelAnimation(0x%08x) m_ulCurrentTime=%lu tick=%lun",
  1661.               pInfo, m_ulCurrentTime, HX_GET_BETTERTICKCOUNT());
  1662.     if (pInfo && m_pPlayToAssocList)
  1663.     {
  1664.         // Get the sound level to set
  1665.         UINT16 usSoundLevel = 100;
  1666.         if (pInfo->m_pSandwich)
  1667.         {
  1668.             CAttr cRet   = pInfo->m_pSandwich->GetValue(m_ulCurrentTime,
  1669.                                                         pInfo->m_pUnder, pInfo->m_pDepend);
  1670.             INT32 lLevel = (INT32) (cRet.GetValueDouble() + 0.5);
  1671.             if (lLevel < 0) lLevel = 0;
  1672.             usSoundLevel = (UINT16) lLevel;
  1673.         }
  1674.         // Find the right IHXTrack
  1675.         SMILPlayToAssoc* pPlayTo = NULL;
  1676.         LISTPOSITION     pos     = m_pPlayToAssocList->GetHeadPosition();
  1677.         while (pos)
  1678.         {
  1679.             SMILPlayToAssoc* pListPlayTo = (SMILPlayToAssoc*) m_pPlayToAssocList->GetNext(pos);
  1680.             if (pListPlayTo &&
  1681.                 pListPlayTo->m_playTo == pInfo->m_pSandwich->GetTargetElementID())
  1682.             {
  1683.                 IHXTrack* pTrack = NULL;
  1684.                 HX_RESULT  rv     = getTrack(pListPlayTo->m_uGroupIndex,
  1685.                                              pListPlayTo->m_uTrackIndex,
  1686.                                              pTrack);
  1687.                 if (SUCCEEDED(rv))
  1688.                 {
  1689.                     // Start the sound level animation
  1690.                     MLOG_ANIM(m_pErrorMessages,"I call BeginSoundLevelAnimation(%u) at m_ulCurrentTime=%luttick=%lun",
  1691.                               usSoundLevel, m_ulCurrentTime, HX_GET_BETTERTICKCOUNT());
  1692.                     pTrack->BeginSoundLevelAnimation(usSoundLevel);
  1693.                 }
  1694.                 HX_RELEASE(pTrack);
  1695.             }
  1696.         }
  1697.     }
  1698.     MLOG_ANIM(m_pErrorMessages,"exit startSoundLevelAnimation(0x%08x) m_ulCurrentTime=%lu tick=%lun",
  1699.               pInfo, m_ulCurrentTime, HX_GET_BETTERTICKCOUNT());
  1700. }
  1701. void CSmilDocumentRenderer::finishSoundLevelAnimation(CSmilAnimateInfo* pInfo,
  1702.                                                       BOOL              bUseCurrentLevel)
  1703. {
  1704.     MLOG_ANIM(m_pErrorMessages,"finishSoundLevelAnimation(0x%08x,%lu) at m_ulCurrentTime=%luttick=%lun",
  1705.               pInfo, bUseCurrentLevel, m_ulCurrentTime, HX_GET_BETTERTICKCOUNT());
  1706.     if (pInfo && pInfo->m_pUnder && m_pPlayToAssocList)
  1707.     {
  1708.         // Get the sound level from the underlying value
  1709.         INT32 lLevel = (INT32) (pInfo->m_pUnder->GetValueDouble() + 0.5);
  1710.         // Clip at 0 if necessary
  1711.         if (lLevel < 0)
  1712.         {
  1713.             lLevel = 0;
  1714.         }
  1715.         UINT16 usSoundLevel = (UINT16) lLevel;
  1716.         // Call on all IHXTrack's playing to this region
  1717.         SMILPlayToAssoc* pPlayTo = NULL;
  1718.         LISTPOSITION     pos     = m_pPlayToAssocList->GetHeadPosition();
  1719.         while (pos)
  1720.         {
  1721.             SMILPlayToAssoc* pListPlayTo = (SMILPlayToAssoc*) m_pPlayToAssocList->GetNext(pos);
  1722.             if (pListPlayTo &&
  1723.                 pListPlayTo->m_playTo == pInfo->m_pSandwich->GetTargetElementID())
  1724.             {
  1725.                 IHXTrack* pTrack = NULL;
  1726.                 HX_RESULT  rv     = getTrack(pListPlayTo->m_uGroupIndex,
  1727.                                              pListPlayTo->m_uTrackIndex,
  1728.                                              pTrack);
  1729.                 if (SUCCEEDED(rv))
  1730.                 {
  1731.                     if (bUseCurrentLevel)
  1732.                     {
  1733.                         // If this flag is set, we should end the 
  1734.                         // soundLevel animation with whatever the
  1735.                         // current value of the soundLevel is, instead
  1736.                         // of reverting back to the underlying value
  1737.                         // of the animation. This will be used when we
  1738.                         // are ending one animation with the intention
  1739.                         // of immediately beginning another.
  1740.                         usSoundLevel = pTrack->GetSoundLevel();
  1741.                     }
  1742.                     MLOG_ANIM(m_pErrorMessages,"I call EndSoundLevelAnimation(%u) at m_ulCurrentTime=%luttick=%lun",
  1743.                               usSoundLevel, m_ulCurrentTime, HX_GET_BETTERTICKCOUNT());
  1744.                     // Start the sound level animation
  1745.                     pTrack->EndSoundLevelAnimation(usSoundLevel);
  1746.                 }
  1747.                 HX_RELEASE(pTrack);
  1748.             }
  1749.         }
  1750.     }
  1751.     MLOG_ANIM(m_pErrorMessages,"exit finishSoundLevelAnimation(0x%08x,%lu) at m_ulCurrentTime=%luttick=%lun",
  1752.               pInfo, bUseCurrentLevel, m_ulCurrentTime, HX_GET_BETTERTICKCOUNT());
  1753. }
  1754. #endif /* #if defined(HELIX_FEATURE_SMIL2_ANIMATION) */
  1755. BOOL CSmilDocumentRenderer::isAttributeAnimated(const char* pszElementID,
  1756.                                                 UINT32      ulAttrName)
  1757. {
  1758.     BOOL bRet = FALSE;
  1759. #if defined(HELIX_FEATURE_SMIL2_ANIMATION)
  1760.     if (pszElementID && m_pAnimationMap)
  1761.     {
  1762.         POSITION pos = m_pAnimationMap->GetStartPosition();
  1763.         while (pos)
  1764.         {
  1765.             const char* pszKey = NULL;
  1766.             void*       pVoid  = NULL;
  1767.             m_pAnimationMap->GetNextAssoc(pos, pszKey, pVoid);
  1768.             if (pszKey && pVoid)
  1769.             {
  1770.                 CSmilAnimateElement* pAnim = (CSmilAnimateElement*) pVoid;
  1771.                 if (pAnim &&
  1772.                     pAnim->m_pTargetElementID &&
  1773.                     *pAnim->m_pTargetElementID == pszElementID &&
  1774.                     ((UINT32) pAnim->m_ucAttributeName) == ulAttrName)
  1775.                 {
  1776.                     bRet = TRUE;
  1777.                     break;
  1778.                 }
  1779.             }
  1780.         }
  1781.     }
  1782.     // Did we find a currently scheduled animation?
  1783.     if (!bRet && m_pSmilParser)
  1784.     {
  1785.         // We didn't find a currently scheduled
  1786.         // animation, but we need to check if the
  1787.         // parser knows about any animations on this
  1788.         // element/attribute, since animations which
  1789.         // start on events won't show up in the document
  1790.         // until the time they actually start. This is
  1791.         // especially important for soundLevel animations,
  1792.         // since we need to know about any possible animations
  1793.         // on the soundLevel before we add the track.
  1794.         bRet = m_pSmilParser->isAttributeAnimated(pszElementID, ulAttrName);
  1795.     }
  1796. #endif /* #if defined(HELIX_FEATURE_SMIL2_ANIMATION) */
  1797.     return bRet;
  1798. }
  1799. BOOL CSmilDocumentRenderer::isRegionBackgroundColorOverridden(CSmilBasicRegion* pRegion)
  1800. {
  1801.     BOOL bRet = FALSE;
  1802.     if (pRegion && m_pPlayToAssocList)
  1803.     {
  1804.         LISTPOSITION pos = m_pPlayToAssocList->GetHeadPosition();
  1805.         while (pos)
  1806.         {
  1807.             SMILPlayToAssoc* pAssoc =
  1808.                 (SMILPlayToAssoc*) m_pPlayToAssocList->GetNext(pos);
  1809.             if (pAssoc &&
  1810.                 pAssoc->m_playTo == pRegion->m_region)
  1811.             {
  1812.                 CSmilSource* pSrc = getSource(pAssoc->m_id);
  1813.                 if (pSrc &&
  1814.                     pSrc->m_bBackgroundColorSpecified)
  1815.                 {
  1816.                     bRet = TRUE;
  1817.                     break;
  1818.                 }
  1819.             }
  1820.         }
  1821.     }
  1822.     return bRet;
  1823. }
  1824. #if defined(HELIX_FEATURE_SMIL2_ANIMATION)
  1825. CSmilAnimateElement* CSmilDocumentRenderer::getFirstAnimationElement(const char* pszElementID,
  1826.                                                                      UINT32      ulAttrName)
  1827. {
  1828.     CSmilAnimateElement* pRet = NULL;
  1829.     if (pszElementID && m_pAnimationMap)
  1830.     {
  1831.         // Initialize the iterator
  1832.         m_AnimationIterator = m_pAnimationMap->GetStartPosition();
  1833.         // Get the first element in the map
  1834.         pRet = getNextAnimationElement(pszElementID, ulAttrName);
  1835.     }
  1836.     return pRet;
  1837. }
  1838. CSmilAnimateElement* CSmilDocumentRenderer::getNextAnimationElement(const char* pszElementID,
  1839.                                                                     UINT32      ulAttrName)
  1840. {
  1841.     CSmilAnimateElement* pRet = NULL;
  1842.     if (pszElementID && m_pAnimationMap)
  1843.     {
  1844.         while (m_AnimationIterator)
  1845.         {
  1846.             const char* pszKey = NULL;
  1847.             void*       pVoid  = NULL;
  1848.             m_pAnimationMap->GetNextAssoc(m_AnimationIterator, pszKey, pVoid);
  1849.             if (pszKey && pVoid)
  1850.             {
  1851.                 CSmilAnimateElement* pAnim = (CSmilAnimateElement*) pVoid;
  1852.                 if (pAnim &&
  1853.                     pAnim->m_pTargetElementID &&
  1854.                     *pAnim->m_pTargetElementID == pszElementID &&
  1855.                     ((UINT32) pAnim->m_ucAttributeName) == ulAttrName)
  1856.                 {
  1857.                     pRet = pAnim;
  1858.                     break;
  1859.                 }
  1860.             }
  1861.         }
  1862.     }
  1863.     return pRet;
  1864. }
  1865. #endif /* #if defined(HELIX_FEATURE_SMIL2_ANIMATION) */
  1866. BOOL CSmilDocumentRenderer::getGroupDuration(UINT16      usGroupIndex,
  1867.                                              REF(UINT32) rulDuration)
  1868. {
  1869.     BOOL bRet = FALSE;
  1870.     if (m_pGroupInfoMap)
  1871.     {
  1872.         void* pVoid = NULL;
  1873.         if(m_pGroupInfoMap->Lookup((INT32) usGroupIndex, pVoid))
  1874.         {
  1875.             SMILGroupInfo* pGroupInfo = (SMILGroupInfo*) pVoid;
  1876.             if (pGroupInfo &&
  1877.                 pGroupInfo->m_bDurationSet)
  1878.             {
  1879.                 rulDuration = pGroupInfo->m_ulDuration;
  1880.                 bRet        = TRUE;
  1881.             }
  1882.         }
  1883.     }
  1884.     return bRet;
  1885. }
  1886. HX_RESULT CSmilDocumentRenderer::getTrack(UINT16 uGroupIndex, UINT16 uTrackIndex, REF(IHXTrack*) rpTrack)
  1887. {
  1888.     HX_RESULT retVal = HXR_FAIL;
  1889.     SMILPlayToAssoc* pPT = getPlayToAssoc(uGroupIndex, uTrackIndex);
  1890.     if (pPT && m_pGroupMap)
  1891.     {
  1892.         // Get the current group
  1893.         void* pVoid = NULL;
  1894.         if(m_pGroupMap->Lookup(pPT->m_uGroupIndex, pVoid) && pVoid)
  1895.         {
  1896.             // QI for IHXGroup2
  1897.             IHXGroup*  pGroup  = (IHXGroup*) pVoid;
  1898.             IHXGroup2* pGroup2 = NULL;
  1899.             pGroup->QueryInterface(IID_IHXGroup2, (void**) &pGroup2);
  1900.             if (pGroup2)
  1901.             {
  1902.                 // Get the right IHXTrack
  1903.                 IHXTrack* pTrack = NULL;
  1904.                 pGroup2->GetIHXTrack(pPT->m_uTrackIndex, pTrack);
  1905.                 if (pTrack)
  1906.                 {
  1907.                     retVal = HXR_OK;
  1908.                     HX_RELEASE(rpTrack);
  1909.                     rpTrack = pTrack;
  1910.                     rpTrack->AddRef();
  1911.                 }
  1912.                 HX_RELEASE(pTrack);
  1913.             }
  1914.             HX_RELEASE(pGroup2);
  1915.         }
  1916.     }
  1917.     return retVal;
  1918. }
  1919. void CSmilDocumentRenderer::forceFullRedraw(IHXSite* pSite)
  1920. {
  1921.     if (pSite)
  1922.     {
  1923.         HXxSize cSize;
  1924.         pSite->GetSize(cSize);
  1925.         HXxRect cRect = {0, 0, cSize.cx, cSize.cy};
  1926.         pSite->DamageRect(cRect);
  1927.         pSite->ForceRedraw();
  1928.     }
  1929. }
  1930. void CSmilDocumentRenderer::forceFullRecursiveRedraw(CSmilBasicBox* pBox)
  1931. {
  1932.     if (pBox)
  1933.     {
  1934.         // Force a redraw of this box's site
  1935.         forceFullRedraw(pBox->m_pSite);
  1936.         // Force an update on any child renderer sites
  1937.         if (pBox->m_pChildRendererSiteList)
  1938.         {
  1939.             LISTPOSITION pos = pBox->m_pChildRendererSiteList->GetHeadPosition();
  1940.             while (pos)
  1941.             {
  1942.                 IHXSite* pChildRendSite =
  1943.                     (IHXSite*) pBox->m_pChildRendererSiteList->GetNext(pos);
  1944.                 forceFullRedraw(pChildRendSite);
  1945.             }
  1946.         }
  1947.         // Now recursively force updates on any children
  1948.         if (pBox->m_pChildList)
  1949.         {
  1950.             LISTPOSITION pos = pBox->m_pChildList->GetHeadPosition();
  1951.             while (pos)
  1952.             {
  1953.                 CSmilBasicBox* pChildBox =
  1954.                     (CSmilBasicBox*) pBox->m_pChildList->GetNext(pos);
  1955.                 forceFullRecursiveRedraw(pChildBox);
  1956.             }
  1957.         }
  1958.     }
  1959. }
  1960. void CSmilDocumentRenderer::destroyRendererSites(CSmilBasicBox* pBox)
  1961. {
  1962. #if 0
  1963.     if (pBox)
  1964.     {
  1965.         // Take care of all the renderers which are
  1966.         // children of this box's site
  1967.         if (pBox->m_pChildRendererSiteList)
  1968.         {
  1969.             // Since we know no renderers are playing to a
  1970.             // root-level site box, then we know that this box
  1971.             // has to be a region, so we can cast to a CSmilBasicRegion
  1972.             CSmilBasicRegion* pRegion = (CSmilBasicRegion*) pBox;
  1973.             // Loop through the child renderer sites
  1974.             LISTPOSITION pos = pBox->m_pChildRendererSiteList->GetHeadPosition();
  1975.             while (pos)
  1976.             {
  1977.                 IHXSite* pRendSite =
  1978.                     (IHXSite*) pBox->m_pChildRendererSiteList->GetNext(pos);
  1979.                 if (pRendSite)
  1980.                 {
  1981.                     // Remove the site from the site manager
  1982.                     if (m_pSiteMgr)
  1983.                     {
  1984.                         m_pSiteMgr->RemoveSite(pRendSite);
  1985.                     }
  1986.                     // Destroy the parent-child relationship between
  1987.                     // region site and renderer site
  1988.                     if (pRegion->m_pSite)
  1989.                     {
  1990.                         pRegion->m_pSite->DestroyChild(pRendSite);
  1991.                     }
  1992.                     // Detach the connection between the
  1993.                     // site and the site watcher. Note that this
  1994.                     // only causes the site to remove its ref on
  1995.                     // the site watcher - it doesn't delete it.
  1996.                     pRendSite->DetachWatcher();
  1997.                     // Get the site watcher from the site watcher map
  1998.                     if (m_pSiteWatcherMap)
  1999.                     {
  2000.                         void* pVoid = NULL;
  2001.                         if (m_pSiteWatcherMap->Lookup((void*) pRendSite, pVoid) && pVoid)
  2002.                         {
  2003.                             // Get the CSmilSiteWatcher pointer
  2004.                             CSmilSiteWatcher* pWatcher = (CSmilSiteWatcher*) pVoid;
  2005.                             // Remove the site watcher from the site watcher map
  2006.                             m_pSiteWatcherMap->RemoveKey((void*) pRendSite);
  2007.                             // Release our ref on the site watcher
  2008.                             HX_RELEASE(pWatcher);
  2009.                         }
  2010.                     }
  2011.                     // Remove this renderer from the m_pSiteInfoByRendererMap
  2012.                     if (m_pSiteInfoByRendererMap)
  2013.                     {
  2014.                         m_pSiteInfoByRendererMap->RemoveKey((void*) pRendSite);
  2015.                     }
  2016.                     // Release the site info's ref 
  2017.                     // on the renderer site
  2018.                     HX_RELEASE(pRendSite);
  2019.                 }
  2020.             }
  2021.         }
  2022.     }
  2023. #else
  2024.     HX_ASSERT(m_pSiteInfoList); // /Fix for PR 116482 in player core should
  2025.                                 // ensure that we don't get here w/NULL m_p...
  2026.     // Here we want to destroy all the renderer sites
  2027.     // which were playing to a region in this top-level
  2028.     // box. The top level box could be the root-layout or
  2029.     // it could be a viewport.
  2030.     if (pBox && m_pSiteInfoByRendererMap  &&
  2031.             // /This check fixes PR 101285 crash.  If m_pSiteInfoList has been
  2032.             // deleted, then m_pSiteInfoByRendererMap points at deleted items:
  2033.             m_pSiteInfoList)
  2034.     {
  2035.         // Create a list which keeps track of which
  2036.         // keys we have operated on
  2037.         CHXSimpleList cKeyList;
  2038.         // Loop through all of the renderers
  2039.         POSITION pos = m_pSiteInfoByRendererMap->GetStartPosition();
  2040.         while (pos)
  2041.         {
  2042.             void* pKey = NULL;
  2043.             void* pVal = NULL;
  2044.             m_pSiteInfoByRendererMap->GetNextAssoc(pos, pKey, pVal);
  2045.             if (pVal)
  2046.             {
  2047.                 // Get the site info pointer
  2048.                 SMILSiteInfo* pSiteInfo = (SMILSiteInfo*) pVal;
  2049.                 if (pSiteInfo->m_pRendererSite)
  2050.                 {
  2051.                     // Get the playback region
  2052.                     CSmilBasicRegion* pRegion = getRegionByID(pSiteInfo->m_regionID);
  2053.                     if (pRegion)
  2054.                     {
  2055.                         // Now get the top-level box which this
  2056.                         // region is under
  2057.                         CSmilBasicBox* pTop = getTopLevelBox(pRegion);
  2058.                         // Only do this operation for those renderers
  2059.                         // playing to regions which are in *this* top-level box.
  2060.                         if (pTop == pBox)
  2061.                         {
  2062.     // XXX HP this is to fix PR63462.
  2063.     // pSiteInfo->m_pRendererSite is added by addRendererSiteChild()
  2064.     // and we need to call its corresponding removeRendererSiteChild()
  2065.     // before we destroying the site.
  2066.     pRegion->removeRendererSiteChild(pSiteInfo->m_pRendererSite);
  2067.                             // Remove the site from the site manager
  2068.                             m_pSiteMgr->RemoveSite(pSiteInfo->m_pRendererSite);
  2069.                             // Destroy the parent-child relationship between
  2070.                             // region site and renderer site
  2071.                             if (pRegion->m_pSite)
  2072.                             {
  2073.                                 pRegion->m_pSite->DestroyChild(pSiteInfo->m_pRendererSite);
  2074.                             }
  2075.                             // Detach the connection between the
  2076.                             // site and the site watcher. Note that this
  2077.                             // only causes the site to remove its ref on
  2078.                             // the site watcher - it doesn't delete it.
  2079.                             pSiteInfo->m_pRendererSite->DetachWatcher();
  2080.                             // Get the site watcher from the site watcher map
  2081.                             if (m_pSiteWatcherMap)
  2082.                             {
  2083.                                 void* pVoid = NULL;
  2084.                                 if (m_pSiteWatcherMap->Lookup((void*) pSiteInfo->m_pRendererSite, pVoid) &&
  2085.                                     pVoid)
  2086.                                 {
  2087.                                     // Get the CSmilSiteWatcher pointer
  2088.                                     CSmilSiteWatcher* pWatcher = (CSmilSiteWatcher*) pVoid;
  2089.                                     // Remove the site watcher from the site watcher map
  2090.                                     m_pSiteWatcherMap->RemoveKey((void*) pSiteInfo->m_pRendererSite);
  2091.                                     // Release our ref on the site watcher
  2092.                                     HX_RELEASE(pWatcher);
  2093.                                 }
  2094.                             }
  2095.                             // Remove the site watcher from the map
  2096.                             removeRendererSiteWatcherFromMap((const char*) pSiteInfo->m_MediaID);
  2097.                             // Remove the site from the map
  2098.                             removeRendererSiteFromMap((const char*) pSiteInfo->m_MediaID);
  2099.                             // Release the site info's ref 
  2100.                             // on the renderer site
  2101.                             HX_RELEASE(pSiteInfo->m_pRendererSite);
  2102.                             // Add this key to the list
  2103.                             cKeyList.AddTail((void*) pKey);
  2104.                         }
  2105.                     }
  2106.                 }
  2107.             }
  2108.         }
  2109.         // Now loop through the keys we operated on
  2110.         // and remove them from the map
  2111.         LISTPOSITION lpos = cKeyList.GetHeadPosition();
  2112.         while (lpos)
  2113.         {
  2114.             void* pKey = cKeyList.GetNext(lpos);
  2115.             if (pKey)
  2116.             {
  2117.                 m_pSiteInfoByRendererMap->RemoveKey(pKey);
  2118.             }
  2119.         }
  2120.         // Delete these only if close has already been called.
  2121.         // In that case, this is our last line of defense
  2122.         // against a leak.
  2123.         if (m_bCloseCalled)
  2124.         {
  2125.             // Now if we have deleted all the renderers in the map,
  2126.             // then delete the whole map
  2127.             if (m_pSiteInfoByRendererMap &&
  2128.                 m_pSiteInfoByRendererMap->GetCount() == 0)
  2129.             {
  2130.                 HX_DELETE(m_pSiteInfoByRendererMap);
  2131.             }
  2132.             // If we have deleted all the watchers in the
  2133.             // site watcher map, then delete the map itself.
  2134.             if (m_pSiteWatcherMap &&
  2135.                 m_pSiteWatcherMap->GetCount() == 0)
  2136.             {
  2137.                 HX_DELETE(m_pSiteWatcherMap);
  2138.             }
  2139.         }
  2140.     }
  2141. #endif
  2142. }
  2143. HX_RESULT CSmilDocumentRenderer::setupRootLayout(BOOL bAssignDefaults)
  2144. {
  2145.     HX_RESULT retVal = HXR_OK;
  2146.     if (m_pRootLayout)
  2147.     {
  2148.         // Are we supposed to assign defaults?
  2149.         if (bAssignDefaults)
  2150.         {
  2151.     // If we haven't resolved the root-layout width,
  2152.     // then assign a default root layout width
  2153.     if (!m_pRootLayout->m_bWidthResolved)
  2154.     {
  2155.         m_pRootLayout->m_Rect.left             = 0;
  2156.         m_pRootLayout->m_Rect.right            = DEFAULT_ROOT_LAYOUT_WIDTH;
  2157.         m_pRootLayout->m_bWidthResolved        = TRUE;
  2158.                 m_pRootLayout->m_bDefaultWidthAssigned = TRUE;
  2159.                 if (!m_pRootLayout->m_bOriginalWidthSet)
  2160.                 {
  2161.                     m_pRootLayout->m_OriginalSize.cx   = DEFAULT_ROOT_LAYOUT_WIDTH;
  2162.                     m_pRootLayout->m_bOriginalWidthSet = TRUE;
  2163.                 }
  2164.             }
  2165.     // If we haven't resolved the root-layout height,
  2166.     // then assign a default root layout height
  2167.     if (!m_pRootLayout->m_bHeightResolved)
  2168.     {
  2169.         m_pRootLayout->m_Rect.top               = 0;
  2170.         m_pRootLayout->m_Rect.bottom            = DEFAULT_ROOT_LAYOUT_HEIGHT;
  2171.         m_pRootLayout->m_bHeightResolved        = TRUE;
  2172.                 m_pRootLayout->m_bDefaultHeightAssigned = TRUE;
  2173.                 if (!m_pRootLayout->m_bOriginalHeightSet)
  2174.                 {
  2175.                     m_pRootLayout->m_OriginalSize.cy    = DEFAULT_ROOT_LAYOUT_HEIGHT;
  2176.                     m_pRootLayout->m_bOriginalHeightSet = TRUE;
  2177.                 }
  2178.     }
  2179.         }
  2180. // Compute left and right of the region rects
  2181. HX_RESULT rvW = computeBoxDimension(m_pRootLayout, BoxDimensionWidth);
  2182. // Compute top and bottom of the region rects
  2183. HX_RESULT rvH = computeBoxDimension(m_pRootLayout, BoxDimensionHeight);
  2184.         if (SUCCEEDED(rvW) && SUCCEEDED(rvH))
  2185.         {
  2186.             // Get the root layout id
  2187.             const char* pszRootID = "root-layout";
  2188.             if (m_pRootLayout->m_pRoot &&
  2189.                 m_pRootLayout->m_pRoot->m_pNode)
  2190.             {
  2191.                 pszRootID = m_pRootLayout->m_pRoot->m_pNode->m_id;
  2192.             }
  2193.     // Create a site user for the root layout
  2194.     HX_RELEASE(m_pRootLayout->m_pSiteUser);
  2195.     m_pRootLayout->m_pSiteUser = new CSmilSiteUser(this,
  2196.    m_pRootLayout->GetBackgroundColor(),
  2197.    m_pContext,
  2198.    TRUE,
  2199.                                                            pszRootID);
  2200.     if (m_pRootLayout->m_pSiteUser)
  2201.     {
  2202. // AddRef the site user
  2203. m_pRootLayout->m_pSiteUser->AddRef();
  2204. // Set several properties in the site user
  2205.                 //
  2206.                 // First, get an IHXValues interface
  2207.                 IHXValues* pSiteUserValues = NULL;
  2208.                 m_pRootLayout->m_pSiteUser->QueryInterface(IID_IHXValues,
  2209.                                                            (void**) &pSiteUserValues);
  2210.                 if (pSiteUserValues)
  2211.                 {
  2212.                     // Set the "name" CString property
  2213.                     addStringProperty(pSiteUserValues, m_pContext,
  2214.                                       "name", "TopLevelSite");
  2215.                     // Set the "contextWindow" CString property
  2216.                     const char* pszCWVal = NULL;
  2217.                     if (m_pRootLayout->m_pRoot)
  2218.                     {
  2219.                         if (m_pRootLayout->m_pRoot->m_eContextWindow == ContextWindowAuto)
  2220.                         {
  2221.                             pszCWVal = "auto";
  2222.                         }
  2223.                         else
  2224.                         {
  2225.                             pszCWVal = "openAtStart";
  2226.                         }
  2227.                     }
  2228.                     addStringProperty(pSiteUserValues, m_pContext,
  2229.                                       "contextWindow", pszCWVal);
  2230.                 }
  2231.                 HX_RELEASE(pSiteUserValues);
  2232. // QI for IUnknown
  2233. IUnknown* pThisUnk = NULL;
  2234. m_pRootLayout->m_pSiteUser->QueryInterface(IID_IUnknown, (void**) &pThisUnk);
  2235. if (pThisUnk)
  2236. {
  2237.     // This is a call back to CSmilRenderer, which in turn
  2238.     // calls IHXLayoutSiteGroupManager::AddLayoutSiteGroup()
  2239.     // with CSmilDocumentRenderer as the callback interface.
  2240.     // This call results in our AttachSite method being called,
  2241.     // which sets the top level site member (m_pRootLayout->m_pSite).
  2242.     m_pParent->HandleAddLayoutSiteGroup(pThisUnk);
  2243.     m_bSiteLayoutComplete = TRUE;
  2244. }
  2245. HX_RELEASE(pThisUnk);
  2246. // Create sites for each of the regions
  2247. // under the root-layout
  2248. retVal = createRegionSites(m_pRootLayout->m_pChildList);
  2249. if (SUCCEEDED(retVal))
  2250. {
  2251.     // We will initially set the z-orders
  2252.     resolveZOrder(m_pRootLayout, m_ulCurrentTime);
  2253.     // force initial redraw
  2254.     forceFullRedraw(m_pRootLayout->m_pSite);
  2255. }
  2256.     }
  2257.     else
  2258.     {
  2259. retVal = HXR_OUTOFMEMORY;
  2260.     }
  2261. }
  2262.         else
  2263.         {
  2264.             retVal = HXR_FAIL;
  2265.         }
  2266.     }
  2267.     else
  2268.     {
  2269.         retVal = HXR_FAIL;
  2270.     }
  2271.     return retVal;
  2272. }
  2273. #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT)
  2274. HX_RESULT CSmilDocumentRenderer::setupViewports()
  2275. {
  2276.     HX_RESULT retVal = HXR_OK;
  2277.     // Do we have any viewports?
  2278.     if (m_pViewportList && m_pViewPortManager)
  2279.     {
  2280.         // Loop through each viewport, setting it up
  2281.         LISTPOSITION pos = m_pViewportList->GetHeadPosition();
  2282.         while (pos && SUCCEEDED(retVal))
  2283.         {
  2284.             // Get the viewport
  2285.             CSmilBasicViewport* pVP =
  2286.                 (CSmilBasicViewport*) m_pViewportList->GetNext(pos);
  2287.             if (pVP && pVP->m_pPort)
  2288.             {
  2289.                 // Compute left and right of the region rects
  2290.                 retVal = computeBoxDimension(pVP, BoxDimensionWidth);
  2291.                 if (SUCCEEDED(retVal))
  2292.                 {
  2293.                     // Compute top and bottom of the region rects
  2294.                     retVal = computeBoxDimension(pVP, BoxDimensionHeight);
  2295.                     if (SUCCEEDED(retVal))
  2296.                     {
  2297.                         // Create a site user for this viewport
  2298.                         HX_RELEASE(pVP->m_pSiteUser);
  2299.                         pVP->m_pSiteUser = new CSmilSiteUser(this,
  2300.                                                              pVP->m_pPort->m_ulBackgroundColor,
  2301.                                                              m_pContext,
  2302.                                                              TRUE,
  2303.                                                              pVP->m_pPort->m_pNode->m_id);
  2304.                         if (pVP->m_pSiteUser)
  2305.                         {
  2306.                             // AddRef the site user
  2307.                             pVP->m_pSiteUser->AddRef();
  2308.                             // Create an IHXValues
  2309.                             IHXCommonClassFactory* pFactory = NULL;
  2310.                             retVal = m_pContext->QueryInterface(IID_IHXCommonClassFactory,
  2311.                                                                 (void**) &pFactory);
  2312.                             if (SUCCEEDED(retVal))
  2313.                             {
  2314.                                 IHXValues* pValues = NULL;
  2315.                                 retVal = pFactory->CreateInstance(CLSID_IHXValues,
  2316.                                                                   (void**) &pValues);
  2317.                                 if (SUCCEEDED(retVal))
  2318.                                 {
  2319.                                     // Set the "playto" property to be the
  2320.                                     // id of this viewport
  2321.                                     setProperty(pValues, "playto", (const char*) pVP->m_id);
  2322.                                     // Get the IHXSiteUser interface from CSmilSiteUser
  2323.                                     IHXSiteUser* pSiteUser = NULL;
  2324.                                     retVal = pVP->m_pSiteUser->QueryInterface(IID_IHXSiteUser,
  2325.                                                                               (void**) &pSiteUser);
  2326.                                     if (SUCCEEDED(retVal))
  2327.                                     {
  2328.                                         // Create the viewport. This is an asynchronous
  2329.                                         // call - it will call us back with AttachSite.
  2330.                                         retVal = m_pViewPortManager->OpenViewPort(pValues, pSiteUser);
  2331.                                     }
  2332.                                     HX_RELEASE(pSiteUser);
  2333.                                 }
  2334.                                 HX_RELEASE(pValues);
  2335.                             }
  2336.                             HX_RELEASE(pFactory);
  2337.                         }
  2338.                         else
  2339.                         {
  2340.                             retVal = HXR_OUTOFMEMORY;
  2341.                         }
  2342.                     }
  2343.                 }
  2344.             }
  2345.             else
  2346.             {
  2347.                 retVal = HXR_FAIL;
  2348.             }
  2349.         }
  2350.     }
  2351.     return retVal;
  2352. }
  2353. HX_RESULT CSmilDocumentRenderer::finishOneViewportSetup(CSmilBasicViewport* pPort)
  2354. {
  2355.     HX_RESULT retVal = HXR_OK;
  2356.     if (pPort && pPort->m_pPort)
  2357.     {
  2358.         // Create all the sites which are children of this site
  2359.         retVal = createRegionSites(pPort->m_pChildList);
  2360.         if (SUCCEEDED(retVal))
  2361.         {
  2362.             // We will initially set the z-orders
  2363.             resolveZOrder(pPort, m_ulCurrentTime);
  2364.             // If the open property of the viewport is
  2365.             // onStart, then we will go ahead and show the
  2366.             // window. If it is whenActive, then we will
  2367.             // hide the window now.
  2368.             BOOL bShow = TRUE;
  2369.             if (pPort->m_pPort->m_eOpen == ViewportOpenWhenActive)
  2370.             {
  2371.                 bShow = FALSE;
  2372.             }
  2373.             showHideViewport((const char*) pPort->m_id, bShow);
  2374.             // force initial redraw
  2375.             forceFullRedraw(pPort->m_pSite);
  2376.             // Set the setup flag
  2377.             pPort->m_bViewportIsSetup = TRUE;
  2378.             // Now we need to check if all the viewport sites
  2379.             // have been setup. If they have, then we will call
  2380.             // setupViewportsDone().
  2381.             BOOL bAllAreSetup = TRUE;
  2382.             if(m_pViewportList)
  2383.             {
  2384.                 LISTPOSITION pos = m_pViewportList->GetHeadPosition();
  2385.                 while (pos)
  2386.                 {
  2387.                     CSmilBasicViewport* pListPort =
  2388.                         (CSmilBasicViewport*) m_pViewportList->GetNext(pos);
  2389.                     if (pListPort && pListPort->m_bViewportIsSetup == FALSE)
  2390.                     {
  2391.                         bAllAreSetup = FALSE;
  2392.                         break;
  2393.                     }
  2394.                 }
  2395.             }
  2396.             if (bAllAreSetup)
  2397.             {
  2398.                 // All the viewports are now setup
  2399.                 setupViewportsDone(retVal);
  2400.             }
  2401.         }
  2402.     }
  2403.     else
  2404.     {
  2405.         retVal = HXR_FAIL;
  2406.     }
  2407.     return retVal;
  2408. }
  2409. HX_RESULT CSmilDocumentRenderer::setupViewportsDone(HX_RESULT status)
  2410. {
  2411.     HX_RESULT retVal = HXR_OK;
  2412.     return retVal;
  2413. }
  2414. void CSmilDocumentRenderer::closeViewports()
  2415. {
  2416.     if (m_pViewportList && m_pViewPortManager)
  2417.     {
  2418.         LISTPOSITION pos = m_pViewportList->GetHeadPosition();
  2419.         while (pos)
  2420.         {
  2421.             CSmilBasicViewport* pVP =
  2422.                 (CSmilBasicViewport*) m_pViewportList->GetNext(pos);
  2423.             if (pVP && pVP->m_bOpen)
  2424.             {
  2425. #ifdef XXXMEH_DO_VIEWPORT_TLC
  2426.                 m_bSMILViewportClose = TRUE;
  2427. #endif
  2428.                 // Close the viewport
  2429.                 m_pViewPortManager->CloseViewPort((const char*) pVP->m_id);
  2430. #ifdef XXXMEH_DO_VIEWPORT_TLC
  2431.                 m_bSMILViewportClose = FALSE;
  2432. #endif
  2433.             }
  2434.         }
  2435.     }
  2436. }
  2437. void CSmilDocumentRenderer::showHideViewport(const char* pszID, BOOL bShow)
  2438. {
  2439.     if (m_pViewPortManager && pszID)
  2440.     {
  2441.         IHXViewPort* pPort = NULL;
  2442.         m_pViewPortManager->GetViewPort(pszID, pPort);
  2443.         if (pPort)
  2444.         {
  2445.             if (bShow)
  2446.             {
  2447.                 pPort->Show();
  2448.             }
  2449.             else
  2450.             {
  2451.                 pPort->Hide();
  2452.             }
  2453.         }
  2454.         HX_RELEASE(pPort);
  2455.     }
  2456. }
  2457. void CSmilDocumentRenderer::showHideViewport(CSmilBasicViewport* pPort,
  2458.                                              BOOL                bShow)
  2459. {
  2460.     if (pPort          &&
  2461.         pPort->m_pPort &&
  2462.         pPort->m_pPort->m_pNode)
  2463.     {
  2464.         showHideViewport((const char*) pPort->m_id, bShow);
  2465.     }
  2466. }
  2467. #endif /* #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT) */
  2468. void CSmilDocumentRenderer::destroyRegions(CHXSimpleList* pChildList)
  2469. {
  2470.     if (pChildList)
  2471.     {
  2472.         // Loop through the children regions
  2473.         LISTPOSITION pos = pChildList->GetHeadPosition();
  2474.         while (pos)
  2475.         {
  2476.             // Since these are children, they have to be
  2477.             // regions, as top-level boxes (root-layout
  2478.             // and viewport) cannot be children.
  2479.             CSmilBasicRegion* pRegion = (CSmilBasicRegion*) pChildList->GetNext(pos);
  2480.             if (pRegion)
  2481.             {
  2482.                 // First we must destroy the children of this
  2483.                 // region, since they hold links to their ancestors
  2484.                 destroyRegions(pRegion->m_pChildList);
  2485.                 // Now we can destroy this region.
  2486.                 if (m_pRegionMap)
  2487.                 {
  2488.                     // First, remove the key from the region map
  2489.                     m_pRegionMap->RemoveKey((const char*) pRegion->m_region);
  2490.                 }
  2491.                 // Now we can delete the region
  2492.                 HX_DELETE(pRegion);
  2493.             }
  2494.         }
  2495.     }
  2496. }
  2497. void CSmilDocumentRenderer::destroyAllRegions()
  2498. {
  2499.     if (m_pRegionMap)
  2500.     {
  2501. // Run through the map
  2502. POSITION pos = m_pRegionMap->GetStartPosition();
  2503. while (pos)
  2504. {
  2505.     const char* pszKey = NULL;
  2506.     void*       pVal   = NULL;
  2507.     m_pRegionMap->GetNextAssoc(pos, pszKey, pVal);
  2508.     if (pVal)
  2509.     {
  2510. // Get the region pointer
  2511. CSmilBasicRegion* pRegion = (CSmilBasicRegion*) pVal;
  2512. // Delete this region
  2513. HX_DELETE(pRegion);
  2514.     }
  2515. }
  2516.         // Remove all the entries
  2517.         m_pRegionMap->RemoveAll();
  2518.         // Delete the map
  2519.         HX_DELETE(m_pRegionMap);
  2520.     }
  2521. }
  2522. void CSmilDocumentRenderer::setElementRemoveTime(const char* pszID,
  2523.                                                  UINT32      ulRemoveTime)
  2524. {
  2525.     if (pszID && m_pSmilParser)
  2526.     {
  2527.         CSmilElement* pElement = m_pSmilParser->findElement(pszID);
  2528.         if (pElement)
  2529.         {
  2530.             pElement->m_ulRemoveTime = ulRemoveTime;
  2531.         }
  2532.     }
  2533. }
  2534. #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT) && defined(XXXMEH_DO_VIEWPORT_TLC)
  2535. void CSmilDocumentRenderer::clearViewportMap()
  2536. {
  2537.     if (m_pViewPortSiteMap)
  2538.     {
  2539.         POSITION pos = m_pViewPortSiteMap->GetStartPosition();
  2540.         while (pos)
  2541.         {
  2542.             const char* pszKey = NULL;
  2543.             void*       pObj   = NULL;
  2544.             m_pViewPortSiteMap->GetNextAssoc(pos, pszKey, pObj);
  2545.             if (pObj)
  2546.             {
  2547.                 IHXSite* pSite = (IHXSite*) pObj;
  2548.                 HX_RELEASE(pSite);
  2549.             }
  2550.         }
  2551.         m_pViewPortSiteMap->RemoveAll();
  2552.     }
  2553. }
  2554. #endif /* #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT) && defined(XXXMEH_DO_VIEWPORT_TLC) */
  2555. void CSmilDocumentRenderer::showAllSites(CSmilBasicBox* pBox, BOOL bShow)
  2556. {
  2557.     if (pBox && pBox->m_pSite)
  2558.     {
  2559.         ShowBackground eShow = ShowBackgroundAlways;
  2560.         if (pBox->m_pParent)
  2561.         {
  2562.             CSmilBasicRegion* pRegion = (CSmilBasicRegion*) pBox;
  2563.             eShow = pRegion->m_eShowBackground;
  2564.         }
  2565.         if (eShow == ShowBackgroundAlways)
  2566.         {
  2567.             BOOL bVisible = isSiteVisible(pBox->m_pSite);
  2568.             showSite(pBox->m_pSite, bShow);
  2569.         }
  2570.         // Process the children
  2571.         if (pBox->m_pChildList)
  2572.         {
  2573.             LISTPOSITION pos = pBox->m_pChildList->GetHeadPosition();
  2574.             while (pos)
  2575.             {
  2576.                 CSmilBasicBox* pChildBox =
  2577.                     (CSmilBasicBox*) pBox->m_pChildList->GetNext(pos);
  2578.                 showAllSites(pChildBox, bShow);
  2579.             }
  2580.         }
  2581.     }
  2582. }
  2583. void CSmilDocumentRenderer::showSite(IHXSite* pSite, BOOL bShow)
  2584. {
  2585.     if(pSite)
  2586.     {
  2587.         IHXSite2* pSite2 = NULL;
  2588.         pSite->QueryInterface(IID_IHXSite2, (void**) &pSite2);
  2589.         if (pSite2)
  2590.         {
  2591.             pSite2->ShowSite(bShow);
  2592.         }
  2593.         HX_RELEASE(pSite2);
  2594.     }
  2595. }
  2596. BOOL CSmilDocumentRenderer::isSiteVisible(IHXSite* pSite)
  2597. {
  2598.     BOOL bRet = FALSE;
  2599.     if (pSite)
  2600.     {
  2601.         IHXSite2* pSite2 = NULL;
  2602.         pSite->QueryInterface(IID_IHXSite2, (void**) &pSite2);
  2603.         if (pSite2)
  2604.         {
  2605.             bRet = pSite2->IsSiteVisible();
  2606.         }
  2607.         HX_RELEASE(pSite2);
  2608.     }
  2609.     return bRet;
  2610. }
  2611. void CSmilDocumentRenderer::setSiteZIndex(IHXSite* pSite, INT32 lZIndex)
  2612. {
  2613.     if (pSite)
  2614.     {
  2615.         IHXSite2* pSite2 = NULL;
  2616.         pSite->QueryInterface(IID_IHXSite2, (void**) &pSite2);
  2617.         if (pSite2)
  2618.         {
  2619.             INT32     lCurZOrder = 0;
  2620.             HX_RESULT rv         = pSite2->GetZOrder(lCurZOrder);
  2621.             if (FAILED(rv) ||
  2622.                 (SUCCEEDED(rv) && lZIndex != lCurZOrder))
  2623.             {
  2624.                 pSite2->SetZOrder(lZIndex);
  2625.             }
  2626.         }
  2627.         HX_RELEASE(pSite2);
  2628.     }
  2629. }
  2630. INT32 CSmilDocumentRenderer::getSiteZIndex(IHXSite* pSite)
  2631. {
  2632.     INT32 lRet = 0;
  2633.     if (pSite)
  2634.     {
  2635.         IHXSite2* pSite2 = NULL;
  2636.         pSite->QueryInterface(IID_IHXSite2, (void**) &pSite2);
  2637.         if (pSite2)
  2638.         {
  2639.             pSite2->GetZOrder(lRet);
  2640.         }
  2641.         HX_RELEASE(pSite2);
  2642.     }
  2643.     return lRet;
  2644. }
  2645. UINT32 CSmilDocumentRenderer::getNumberOfChildSites(IHXSite* pSite)
  2646. {
  2647.     UINT32 ulRet = 0;
  2648.     if (pSite)
  2649.     {
  2650.         IHXSite2* pSite2 = NULL;
  2651.         pSite->QueryInterface(IID_IHXSite2, (void**) &pSite2);
  2652.         if (pSite2)
  2653.         {
  2654.             ulRet = pSite2->GetNumberOfChildSites();
  2655.         }
  2656.         HX_RELEASE(pSite2);
  2657.     }
  2658.     return ulRet;
  2659. }
  2660. HX_RESULT
  2661. CSmilDocumentRenderer::onPreSeek(UINT32 ulOldTime, UINT32 ulNewTime)
  2662. {
  2663.     HX_RESULT rc = HXR_OK;
  2664. //{FILE* f1 = ::fopen("c:\temp\out.txt", "a+"); ::fprintf(f1, "onPreSeekn");::fclose(f1);}
  2665.     if(m_pSiteInfoList  &&  m_pSiteInfoList->GetCount() > 0)
  2666.     {
  2667. // hide all regions/sites in current group
  2668. CHXSimpleList::Iterator i = m_pSiteInfoList->Begin();
  2669. for(; i != m_pSiteInfoList->End(); ++i)
  2670. {
  2671.     SMILSiteInfo* pSiteInfo = (SMILSiteInfo*)(*i);
  2672.     if(pSiteInfo->m_uGroupIndex == m_uCurrentGroupIndex)
  2673.     {
  2674. // /Reset resumeTime of site infos if seek is back before they
  2675. // occurred so wrong one isn't on top (after fix for PR 81510
  2676. // (& dup. PR 83796)):
  2677. if (pSiteInfo->m_ulResumeTime > ulNewTime)
  2678. {
  2679.     pSiteInfo->m_ulResumeTime = 0;
  2680. }
  2681. IHXSite* pRegionSite = NULL;
  2682. CSmilBasicRegion* pRegion = getRegionByID(pSiteInfo->m_regionID);
  2683. if (!pRegion)
  2684. {
  2685.     HX_ASSERT(pRegion);
  2686.     continue;
  2687. }
  2688. if(pRegion->m_eBackgroundColorType == CSS2TypeTransparent)
  2689. {
  2690.     pRegionSite = pSiteInfo->m_pRegionSite;
  2691. }
  2692. showSite(pSiteInfo->m_pRendererSite, FALSE);
  2693. showSite(pRegionSite, FALSE);
  2694.     }
  2695. }
  2696. // remove all the transitions...
  2697. removeActiveTransitions();
  2698. #if defined(HELIX_FEATURE_SMIL2_ANIMATION)
  2699.         // remove all the animations
  2700.         removeActiveAnimations();
  2701. #endif /* #if defined(HELIX_FEATURE_SMIL2_ANIMATION) */
  2702.         // Clear the "handled" flag on all events
  2703.         clearAllEventHandledFlags();
  2704. // /Notify rmasmil so its data structures can prep for a seek, e.g.,
  2705. // re-loading all old actuate="onLoad" links that were removed when
  2706. // used already, prior to this (backwards) seek; fixes PR 67170:
  2707. if (m_pSmilParser)
  2708. {
  2709.     m_pSmilParser->prepForSeek(ulOldTime, ulNewTime);
  2710. }
  2711. // show/hide sites up to ulNewTime
  2712. // events at the same time for the same region
  2713. // are ordererd 'hide' first, then 'show' so
  2714. // a hide doesn't override a show.
  2715. m_ulEventListPosition = m_pEventList->GetHeadPosition();
  2716. flushAllEvents( ulNewTime, TRUE );
  2717.     }
  2718.     return rc;
  2719. }
  2720. HX_RESULT
  2721. CSmilDocumentRenderer::endStream()
  2722. {
  2723.     m_bSMILPresentationHasEnded = TRUE;
  2724.     flushAllEvents();    // flush all remaining events
  2725.     if(m_pGroupMap)
  2726.     {
  2727. CHXMapLongToObj::Iterator i;
  2728. for(i=m_pGroupMap->Begin();i!=m_pGroupMap->End();++i)
  2729. {
  2730.     IHXGroup* pGroup = (IHXGroup*)(*i);
  2731.     pGroup->Release();
  2732. }
  2733. HX_DELETE(m_pGroupMap);
  2734.     }
  2735.     HX_RELEASE(m_pPersistentLayoutStream);
  2736.     closeOldRenderers(TRUE);
  2737.     HX_RELEASE(m_pPersistentProperties);
  2738.     HX_RELEASE(m_pPersistentParentRenderer);
  2739.     if (isSiteCompositionModeON())
  2740.     {
  2741.         turnSiteCompositionModeOFF();
  2742.     }
  2743.     return HXR_OK;
  2744. }
  2745. CSmilBasicRegion* CSmilDocumentRenderer::setupDefaultLayout()
  2746. {
  2747.     CSmilBasicRegion* pRet = NULL;
  2748.     // First we need to check if we have already created
  2749.     // a default region.
  2750.     // XXXMEH - later, we might want to something more sophisticated
  2751.     // here and make sure that the default region name we create
  2752.     // is unique. For now, we make it a weird string.
  2753.     const char* pszDefRegID = "jgje4u5kd845prhd94";
  2754.     // Do we already have a default region?
  2755.     CSmilBasicRegion* pRegion = getRegionByID(pszDefRegID);
  2756.     if (!pRegion)
  2757.     {
  2758.         // We don't already have a default region - create one.
  2759.         pRegion = new CSmilBasicRegion(NULL);
  2760.         if (pRegion)
  2761.         {
  2762.             // Assign the default id to this region
  2763.             pRegion->m_region = pszDefRegID;
  2764.             // Set the root-layout as the parent
  2765.             pRegion->m_pParent = m_pRootLayout;
  2766.             // Add this region as a child of the root-layout
  2767.             HX_RESULT retVal = m_pRootLayout->addChild(pRegion);
  2768.             if (SUCCEEDED(retVal))
  2769.             {
  2770.                 // Add the default region to the region map
  2771.                 m_pRegionMap->SetAt(pszDefRegID, (void*) pRegion);
  2772.                 // Do we need to set up the root-layout?
  2773.                 if (!m_bIsRootLayoutSetup)
  2774.                 {
  2775.                     // We need to set up the root-layout. This can
  2776.                     // happen if either there WAS no root-layout element
  2777.                     // or if the root-layout element was missing either
  2778.                     // a "width" or "height" property
  2779.                     retVal = setupRootLayout(TRUE);
  2780.                     if (SUCCEEDED(retVal))
  2781.                     {
  2782.                         // Set the flag
  2783.                         m_bIsRootLayoutSetup = TRUE;
  2784.                         // Assign the out parameter
  2785.                         pRet = pRegion;
  2786.                     }
  2787.                 }
  2788.                 else
  2789.                 {
  2790.                     // <root-layout> is already set up, but we need to resolve
  2791.                     // the width and height of this region.
  2792.                     retVal = computeBoxDimension(pRegion, BoxDimensionWidth);
  2793.                     if (SUCCEEDED(retVal))
  2794.                     {
  2795.                         retVal = computeBoxDimension(pRegion, BoxDimensionHeight);
  2796.                         if (SUCCEEDED(retVal))
  2797.                         {
  2798.                             // Now we need to do the regular setup of this region
  2799.                             retVal = createRegionSite(pRegion);
  2800.                             if (SUCCEEDED(retVal))
  2801.                             {
  2802.                                 // Assign the out parameter
  2803.                                 pRet = pRegion;
  2804.                             }
  2805.                         }
  2806.                     }
  2807.                 }
  2808.             }
  2809.         }
  2810.     }
  2811.     else
  2812.     {
  2813.         // We have a default region, so we assume that
  2814.         // we don't have to do any additional setup.
  2815.         pRet = pRegion;
  2816.     }
  2817.     return pRet;
  2818. }
  2819. CSmilBasicRegion* CSmilDocumentRenderer::getRegionByID(const char* pID)
  2820. {
  2821.     CSmilBasicRegion* pRegion = 0;
  2822.     if(m_pRegionMap)
  2823.     {
  2824. m_pRegionMap->Lookup(pID, (void*&)pRegion);
  2825.     }
  2826.     return pRegion;
  2827. }
  2828. UINT32 CSmilDocumentRenderer::getNumRegionsByName(const char* pszName)
  2829. {
  2830.     UINT32 ulRet = 0;
  2831.     CSmilBasicRegion* pRegion = getFirstRegionByName(pszName);
  2832.     while (pRegion)
  2833.     {
  2834.         ulRet++;
  2835.         pRegion = getNextRegionByName(pszName);
  2836.     }
  2837.     return ulRet;
  2838. }
  2839. CSmilBasicRegion* CSmilDocumentRenderer::getFirstRegionByName(const char* pszName)
  2840. {
  2841.     CSmilBasicRegion* pRet = NULL;
  2842.     if (m_pRegionMap)
  2843.     {
  2844.         // Initialize the iterator
  2845.         m_pRegionMapIterator = m_pRegionMap->GetStartPosition();
  2846.         // Get the region
  2847.         pRet = getRegionByName(pszName);
  2848.     }
  2849.     return pRet;
  2850. }
  2851. CSmilBasicRegion* CSmilDocumentRenderer::getNextRegionByName(const char* pszName)
  2852. {
  2853.     return getRegionByName(pszName);
  2854. }
  2855. BOOL CSmilDocumentRenderer::isAncestorRegion(CSmilBasicRegion* pPossibleParent,
  2856.                                              CSmilBasicRegion* pPossibleChild)
  2857. {
  2858.     BOOL bRet = FALSE;
  2859.     if (pPossibleParent)
  2860.     {
  2861.         while (pPossibleChild)
  2862.         {
  2863.             if (pPossibleParent == pPossibleChild)
  2864.             {
  2865.                 bRet = TRUE;
  2866.                 break;
  2867.             }
  2868.             // If our parent has a parent, then the
  2869.             // CSmilBasicBox is still a region.
  2870.             if (pPossibleChild->m_pParent &&
  2871.                 pPossibleChild->m_pParent->m_pParent)
  2872.             {
  2873.                 pPossibleChild = (CSmilBasicRegion*) pPossibleChild->m_pParent;
  2874.             }
  2875.             else
  2876.             {
  2877.                 break;
  2878.             }
  2879.         }
  2880.     }
  2881.     return bRet;
  2882. }
  2883. HX_RESULT CSmilDocumentRenderer::getCommonAncestorRegion(CSmilBasicRegion*      pRegA,
  2884.                                                          CSmilBasicRegion*      pRegB,
  2885.                                                          REF(CSmilBasicRegion*) rpCommon)
  2886. {
  2887.     HX_RESULT retVal = HXR_OK;
  2888.     if (pRegA && pRegB)
  2889.     {
  2890.         // First check if B is a child of A,
  2891.         // then check if A is a child of B,
  2892.         // then check for a common ancestor
  2893.         if (isAncestorRegion(pRegA, pRegB))
  2894.         {
  2895.             rpCommon = pRegA;
  2896.         }
  2897.         else if (isAncestorRegion(pRegB, pRegA))
  2898.         {
  2899.             rpCommon = pRegB;
  2900.         }
  2901.         else
  2902.         {
  2903.             retVal = HXR_FAIL;
  2904.         }
  2905.     }
  2906.     return retVal;
  2907. }
  2908. #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT)
  2909. CSmilBasicViewport* CSmilDocumentRenderer::getViewport(const char* pszID)
  2910. {
  2911.     CSmilBasicViewport* pRet = NULL;
  2912.     if(m_pViewportList)
  2913.     {
  2914.         LISTPOSITION pos = m_pViewportList->GetHeadPosition();
  2915.         while (pos)
  2916.         {
  2917.             CSmilBasicViewport* pPort =
  2918.                 (CSmilBasicViewport*) m_pViewportList->GetNext(pos);
  2919.             if (pPort && pPort->m_id == pszID)
  2920.             {
  2921.                 pRet = pPort;
  2922.                 break;
  2923.             }
  2924.         }
  2925.     }
  2926.     return pRet;
  2927. }
  2928. CSmilBasicViewport* CSmilDocumentRenderer::getViewportBySiteUser(CSmilSiteUser* pSiteUser)
  2929. {
  2930.     CSmilBasicViewport* pRet = NULL;
  2931.     if(m_pViewportList)
  2932.     {
  2933.         LISTPOSITION pos = m_pViewportList->GetHeadPosition();
  2934.         while (pos)
  2935.         {
  2936.             CSmilBasicViewport* pPort =
  2937.                 (CSmilBasicViewport*) m_pViewportList->GetNext(pos);
  2938.             if (pPort &&