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

Symbian

开发平台:

Visual C++

  1.             }
  2.             else if (ulAttr == kAttrNameColor)
  3.             {
  4.                 // Get the color we want to set
  5.                 UINT32 ulRed   = (UINT32) pValue->GetValueDouble(0);
  6.                 UINT32 ulGreen = (UINT32) pValue->GetValueDouble(1);
  7.                 UINT32 ulBlue  = (UINT32) pValue->GetValueDouble(2);
  8.                 UINT32 ulAlpha = (UINT32) pValue->GetValueDouble(3);
  9.                 UINT32 ulColor = (ulAlpha << 24) | (ulRed << 16) |
  10.                                  (ulGreen <<  8) | ulBlue;
  11.                 // Set the color into the renderer
  12.                 BOOL bChanged = FALSE;
  13.                 retVal = setRendererULONG32Property(pszID, "color",
  14.                                                     ulColor, bChanged);
  15.                 if (SUCCEEDED(retVal) && bChanged)
  16.                 {
  17.                     // Get the renderer site
  18.                     IHXSite* pRendererSite = NULL;
  19.                     retVal = getRendererSite(pszID, pRendererSite);
  20.                     if (SUCCEEDED(retVal))
  21.                     {
  22.                         // Queue the site for redraw
  23.                         queueSiteForAnimationRedraw(pRendererSite);
  24.                     }
  25.                     HX_RELEASE(pRendererSite);
  26.                 }
  27.             }
  28.             else if (ulAttr == kAttrNameMediaOpacity ||
  29.                      ulAttr == kAttrNameBackgroundOpacity)
  30.             {
  31.                 // Get the correct property string
  32.                 const char* pszPropStr = (ulAttr == kAttrNameMediaOpacity ? "mediaOpacity" : "backgroundOpacity");
  33.                 // Get the value to set
  34.                 UINT32 ulOpacity = (UINT32) pValue->GetValueDouble();
  35.                 // Set the property
  36.                 BOOL bChanged = FALSE;
  37.                 retVal = setRendererULONG32Property(pszID, pszPropStr,
  38.                                                     ulOpacity, bChanged);
  39.                 if (SUCCEEDED(retVal) && bChanged)
  40.                 {
  41.                     // Get the renderer site
  42.                     IHXSite* pRendererSite = NULL;
  43.                     retVal = getRendererSite(pszID, pRendererSite);
  44.                     if (SUCCEEDED(retVal))
  45.                     {
  46.                         // Queue the site for redraw
  47.                         queueSiteForAnimationRedraw(pRendererSite);
  48.                     }
  49.                     HX_RELEASE(pRendererSite);
  50.                 }
  51.             }
  52.         }
  53.         else if (eTag == SMILRootLayout)
  54.         {
  55.             if (m_pRootLayout && m_pRootLayout->m_pRoot)
  56.             {
  57.                 switch (ulAttr)
  58.                 {
  59.                     case kAttrNameWidth:
  60.                         if (m_pRootLayout->m_pRoot->m_dWidth != pValue->GetValueDouble(0))
  61.                         {
  62.                             m_pRootLayout->m_pRoot->m_dWidth     = pValue->GetValueDouble(0);
  63.                             m_pRootLayout->m_pRoot->m_eWidthType = pValue->GetCSS2Type(0);
  64.                             m_bAnimateRootLayout                 = TRUE;
  65.                         }
  66.                         break;
  67.                     case kAttrNameHeight:
  68.                         if (m_pRootLayout->m_pRoot->m_dHeight != pValue->GetValueDouble(0))
  69.                         {
  70.                             m_pRootLayout->m_pRoot->m_dHeight     = pValue->GetValueDouble(0);
  71.                             m_pRootLayout->m_pRoot->m_eHeightType = pValue->GetCSS2Type(0);
  72.                             m_bAnimateRootLayout                  = TRUE;
  73.                         }
  74.                         break;
  75.                 }
  76.             }
  77.             else
  78.             {
  79.                 retVal = HXR_FAIL;
  80.             }
  81.         }
  82. #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT)
  83.         else if (eTag == SMILViewport)
  84.         {
  85.             CSmilBasicViewport* pVP = getViewport(pszID);
  86.             if (pVP && pVP->m_pPort)
  87.             {
  88.                 BOOL bQueueVP = FALSE;
  89.                 switch (ulAttr)
  90.                 {
  91.                     case kAttrNameWidth:
  92.                         if (pVP->m_pPort->m_dWidth != pValue->GetValueDouble(0))
  93.                         {
  94.                             pVP->m_pPort->m_dWidth     = pValue->GetValueDouble(0);
  95.                             pVP->m_pPort->m_eWidthType = pValue->GetCSS2Type(0);
  96.                             bQueueVP = TRUE;
  97.                         }
  98.                         break;
  99.                     case kAttrNameHeight:
  100.                         if (pVP->m_pPort->m_dHeight != pValue->GetValueDouble(0))
  101.                         {
  102.                             pVP->m_pPort->m_dHeight     = pValue->GetValueDouble(0);
  103.                             pVP->m_pPort->m_eHeightType = pValue->GetCSS2Type(0);
  104.                             bQueueVP = TRUE;
  105.                         }
  106.                         break;
  107.                 }
  108.                 if (bQueueVP)
  109.                 {
  110.                     if (!m_pAnimTopLayoutMap)
  111.                     {
  112.                         m_pAnimTopLayoutMap = new CHXMapPtrToPtr();
  113.                     }
  114.                     if (m_pAnimTopLayoutMap)
  115.                     {
  116.                         m_pAnimTopLayoutMap->SetAt((void*) pVP, (void*) pVP);
  117.                     }
  118.                 }
  119.             }
  120.             else
  121.             {
  122.                 retVal = HXR_FAIL;
  123.             }
  124.         }
  125. #endif /* #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT) */
  126.         else if (eTag == SMILParam)
  127.         {
  128.             if (m_pSmilParser)
  129.             {
  130.                 CSmilElement* pEl = m_pSmilParser->findElement(pszID);
  131.                 if (pEl &&
  132.                     pEl->m_pNode &&
  133.                     pEl->m_pNode->m_tag == SMILParam &&
  134.                     m_pSmilParser->isMediaObject(pEl->m_pNode->m_pParent))
  135.                 {
  136.                     // Get the CSmilParamElement
  137.                     CSmilParamElement* pParam = (CSmilParamElement*) pEl;
  138.                     // Get the media element id
  139.                     const char* pszMediaID = (const char*) pEl->m_pNode->m_pParent->m_id;
  140.                     // Set this property into the renderer
  141.                     BOOL bChanged = FALSE;
  142.                     retVal = setRendererCStringProperty(pszMediaID,
  143.                                                         (const char*) pParam->m_pName,
  144.                                                         pValue->GetValueString(),
  145.                                                         bChanged);
  146.                     if (SUCCEEDED(retVal) && bChanged)
  147.                     {
  148.                         MLOG_ANIM(m_pErrorMessages,
  149.                                   "setValue() t=%lu Changed param id=%s value to %sn",
  150.                                   m_ulCurrentTime, pszID,
  151.                                   pValue->GetValueString());
  152.                         // Get the renderer site
  153.                         IHXSite* pRendererSite = NULL;
  154.                         retVal = getRendererSite(pszMediaID, pRendererSite);
  155.                         if (SUCCEEDED(retVal))
  156.                         {
  157.                             // Queue the site for redraw
  158.                             queueSiteForAnimationRedraw(pRendererSite);
  159.                         }
  160.                         HX_RELEASE(pRendererSite);
  161.                     }
  162.                 }
  163.                 else
  164.                 {
  165.                     retVal = HXR_FAIL;
  166.                 }
  167.             }
  168.             else
  169.             {
  170.                 retVal = HXR_FAIL;
  171.             }
  172.         }
  173.     }
  174.     return retVal;
  175. }
  176. #endif /* #if defined(HELIX_FEATURE_SMIL2_ANIMATION) */
  177. const char* CSmilDocumentRenderer::getDefaultNamespace()
  178. {
  179.     const char* pRet = NULL;
  180.     if (m_pSmilParser)
  181.     {
  182.         pRet = m_pSmilParser->getDefaultNamespace();
  183.     }
  184.     return pRet;
  185. }
  186. void CSmilDocumentRenderer::resetRendererSites(CSmilBasicRegion* pRegion)
  187. {
  188.     if (pRegion && pRegion->m_pChildRendererSiteList)
  189.     {
  190.         LISTPOSITION pos = pRegion->m_pChildRendererSiteList->GetHeadPosition();
  191.         while (pos)
  192.         {
  193.             IHXSite* pRndSite =
  194.                 (IHXSite*) pRegion->m_pChildRendererSiteList->GetNext(pos);
  195.             if (pRndSite)
  196.             {
  197.                 // Reset the size of the site. Note that
  198.                 // since we have a site watcher, it doesn't
  199.                 // matter what we pass in, because the site
  200.                 // watcher will override it.
  201.                 HXxSize cSize = {1, 1};
  202.                 pRndSite->SetSize(cSize);
  203.                 // Reset the position of the site. Note that
  204.                 // since we have a site watcher, it doesn't
  205.                 // matter what we pass in, because the site
  206.                 // watcher will override it.
  207.                 HXxPoint cPos = {1, 1};
  208.                 pRndSite->SetPosition(cPos);
  209.             }
  210.         }
  211.     }
  212. }
  213. CSmilSiteWatcher* CSmilDocumentRenderer::getRendererSiteWatcher(const char* pszMediaID)
  214. {
  215.     CSmilSiteWatcher* pRet = NULL;
  216.     if (pszMediaID && m_pMediaID2RendererSiteWatcherMap)
  217.     {
  218.         // Look up the site watcher
  219.         void* pVoid = NULL;
  220.         if (m_pMediaID2RendererSiteWatcherMap->Lookup(pszMediaID, pVoid) && pVoid)
  221.         {
  222.             pRet = (CSmilSiteWatcher*) pVoid;
  223.         }
  224.     }
  225.     return pRet;
  226. }
  227. void CSmilDocumentRenderer::addRendererSiteWatcherToMap(const char*       pszMediaID,
  228.                                                         CSmilSiteWatcher* pWatch)
  229. {
  230.     if (pszMediaID && pWatch)
  231.     {
  232.         // Do we already have the map?
  233.         if (!m_pMediaID2RendererSiteWatcherMap)
  234.         {
  235.             // Create it
  236.             m_pMediaID2RendererSiteWatcherMap = new CHXMapStringToOb();
  237.         }
  238.         if (m_pMediaID2RendererSiteWatcherMap)
  239.         {
  240.             // Is this renderer already in the map?
  241.             void* pVoid = NULL;
  242.             if (!m_pMediaID2RendererSiteWatcherMap->Lookup(pszMediaID, pVoid))
  243.             {
  244.                 // AddRef the site
  245.                 pWatch->AddRef();
  246.                 // Add it to the map
  247.                 m_pMediaID2RendererSiteWatcherMap->SetAt(pszMediaID, (void*) pWatch);
  248.             }
  249.         }
  250.     }
  251. }
  252. void CSmilDocumentRenderer::removeRendererSiteWatcherFromMap(const char* pszMediaID)
  253. {
  254.     if (pszMediaID && m_pMediaID2RendererSiteWatcherMap)
  255.     {
  256.         // Is this renderer site in the map
  257.         void* pVoid = NULL;
  258.         if (m_pMediaID2RendererSiteWatcherMap->Lookup(pszMediaID, pVoid) && pVoid)
  259.         {
  260.             // Release the renderer site
  261.             CSmilSiteWatcher* pWatch = (CSmilSiteWatcher*) pVoid;
  262.             HX_RELEASE(pWatch);
  263.             // Remove it from the map
  264.             m_pMediaID2RendererSiteWatcherMap->RemoveKey(pszMediaID);
  265.         }
  266.     }
  267. }
  268. void CSmilDocumentRenderer::clearRendererSiteWatcherMap()
  269. {
  270.     if (m_pMediaID2RendererSiteWatcherMap)
  271.     {
  272.         POSITION pos = m_pMediaID2RendererSiteWatcherMap->GetStartPosition();
  273.         while (pos)
  274.         {
  275.             const char* pszKey = NULL;
  276.             void*       pVoid  = NULL;
  277.             m_pMediaID2RendererSiteWatcherMap->GetNextAssoc(pos, pszKey, pVoid);
  278.             if (pVoid)
  279.             {
  280.                 // Release the renderer site
  281.                 CSmilSiteWatcher* pWatch = (CSmilSiteWatcher*) pVoid;
  282.                 HX_RELEASE(pWatch);
  283.             }
  284.         }
  285.         // Remove all entries from the map
  286.         m_pMediaID2RendererSiteWatcherMap->RemoveAll();
  287.     }
  288. }
  289. HX_RESULT CSmilDocumentRenderer::getRendererSite(const char*    pszMediaID,
  290.                                                  REF(IHXSite*) rpSite)
  291. {
  292.     HX_RESULT retVal = HXR_FAIL;
  293.     if (pszMediaID && m_pMediaID2RendererSiteMap)
  294.     {
  295.         // Is the media ID in the map?
  296.         void* pVoid = NULL;
  297.         if (m_pMediaID2RendererSiteMap->Lookup(pszMediaID, pVoid) && pVoid)
  298.         {
  299.             HX_RELEASE(rpSite);
  300.             rpSite = (IHXSite*) pVoid;
  301.             rpSite->AddRef();
  302.             retVal = HXR_OK;
  303.         }
  304.     }
  305.     return retVal;
  306. }
  307. void CSmilDocumentRenderer::addRendererSiteToMap(const char* pszMediaID,
  308.                                                  IHXSite*   pSite)
  309. {
  310.     if (pszMediaID && pSite)
  311.     {
  312.         // Do we already have the map?
  313.         if (!m_pMediaID2RendererSiteMap)
  314.         {
  315.             // Create it
  316.             m_pMediaID2RendererSiteMap = new CHXMapStringToOb();
  317.         }
  318.         if (m_pMediaID2RendererSiteMap)
  319.         {
  320.             // Is this renderer already in the map?
  321.             void* pVoid = NULL;
  322.             if (!m_pMediaID2RendererSiteMap->Lookup(pszMediaID, pVoid))
  323.             {
  324.                 // AddRef the site
  325.                 pSite->AddRef();
  326.                 // Add it to the map
  327.                 m_pMediaID2RendererSiteMap->SetAt(pszMediaID, (void*) pSite);
  328.             }
  329.         }
  330.     }
  331. }
  332. void CSmilDocumentRenderer::removeRendererSiteFromMap(const char* pszMediaID)
  333. {
  334.     if (pszMediaID && m_pMediaID2RendererSiteMap)
  335.     {
  336.         // Is this renderer site in the map
  337.         void* pVoid = NULL;
  338.         if (m_pMediaID2RendererSiteMap->Lookup(pszMediaID, pVoid) && pVoid)
  339.         {
  340.             // Release the renderer site
  341.             IHXSite* pSite = (IHXSite*) pVoid;
  342.             HX_RELEASE(pSite);
  343.             // Remove it from the map
  344.             m_pMediaID2RendererSiteMap->RemoveKey(pszMediaID);
  345.         }
  346.     }
  347. }
  348. void CSmilDocumentRenderer::clearRendererSiteMap()
  349. {
  350.     if (m_pMediaID2RendererSiteMap)
  351.     {
  352.         POSITION pos = m_pMediaID2RendererSiteMap->GetStartPosition();
  353.         while (pos)
  354.         {
  355.             const char* pszKey = NULL;
  356.             void*       pVoid  = NULL;
  357.             m_pMediaID2RendererSiteMap->GetNextAssoc(pos, pszKey, pVoid);
  358.             if (pVoid)
  359.             {
  360.                 // Release the renderer site
  361.                 IHXSite* pSite = (IHXSite*) pVoid;
  362.                 HX_RELEASE(pSite);
  363.             }
  364.         }
  365.         // Remove all entries from the map
  366.         m_pMediaID2RendererSiteMap->RemoveAll();
  367.     }
  368. }
  369. HX_RESULT CSmilDocumentRenderer::getRenderer(const char*        pszMediaID,
  370.                                              REF(IHXRenderer*) rpRenderer)
  371. {
  372.     HX_RESULT retVal = HXR_FAIL;
  373.     if (pszMediaID && m_pMediaID2RendererMap)
  374.     {
  375.         // Is the media ID in the map?
  376.         void* pVoid = NULL;
  377.         if (m_pMediaID2RendererMap->Lookup(pszMediaID, pVoid) && pVoid)
  378.         {
  379.             HX_RELEASE(rpRenderer);
  380.             rpRenderer = (IHXRenderer*) pVoid;
  381.             rpRenderer->AddRef();
  382.             retVal = HXR_OK;
  383.         }
  384.     }
  385.     return retVal;
  386. }
  387. void CSmilDocumentRenderer::addRendererToMap(const char* pszMediaID,
  388.                                              IHXRenderer* pRenderer)
  389. {
  390.     if (pszMediaID && pRenderer)
  391.     {
  392.         // Do we already have the map?
  393.         if (!m_pMediaID2RendererMap)
  394.         {
  395.             // Create it
  396.             m_pMediaID2RendererMap = new CHXMapStringToOb();
  397.         }
  398.         if (m_pMediaID2RendererMap)
  399.         {
  400.             // Is this renderer already in the map?
  401.             void* pVoid = NULL;
  402.             if (!m_pMediaID2RendererMap->Lookup(pszMediaID, pVoid))
  403.             {
  404.                 // AddRef the renderer
  405.                 pRenderer->AddRef();
  406.                 // Add it to the map
  407.                 m_pMediaID2RendererMap->SetAt(pszMediaID, (void*) pRenderer);
  408.             }
  409.         }
  410.     }
  411. }
  412. void CSmilDocumentRenderer::removeRendererFromMap(const char* pszMediaID)
  413. {
  414.     if (pszMediaID && m_pMediaID2RendererMap)
  415.     {
  416.         // Is this entry in the map?
  417.         void* pVoid = NULL;
  418.         if (m_pMediaID2RendererMap->Lookup(pszMediaID, pVoid) && pVoid)
  419.         {
  420.             // Release the renderer
  421.             IHXRenderer* pRend = (IHXRenderer*) pVoid;
  422.             HX_RELEASE(pRend);
  423.             // Remove it from the map
  424.             m_pMediaID2RendererMap->RemoveKey(pszMediaID);
  425.         }
  426.     }
  427. }
  428. void CSmilDocumentRenderer::clearRendererMap()
  429. {
  430.     if (m_pMediaID2RendererMap)
  431.     {
  432.         // Run through the map, and release the renderer
  433.         POSITION pos = m_pMediaID2RendererMap->GetStartPosition();
  434.         while (pos)
  435.         {
  436.             const char* pszKey = NULL;
  437.             void*       pVoid  = NULL;
  438.             m_pMediaID2RendererMap->GetNextAssoc(pos, pszKey, pVoid);
  439.             if (pVoid)
  440.             {
  441.                 IHXRenderer* pRend = (IHXRenderer*) pVoid;
  442.                 HX_RELEASE(pRend);
  443.             }
  444.         }
  445.         // Remove all entries from the map
  446.         m_pMediaID2RendererMap->RemoveAll();
  447.     }
  448. }
  449. SMILPlayToAssoc*
  450. CSmilDocumentRenderer::getPlayToAssoc(UINT16 uGroupIndex, UINT16 uTrackIndex)
  451. {
  452.     SMILPlayToAssoc* pPlayToAssoc = 0;
  453.     if(m_pPlayToAssocList)
  454.     {
  455. CHXSimpleList::Iterator i;
  456. for(i=m_pPlayToAssocList->Begin();i!=m_pPlayToAssocList->End();++i)
  457. {
  458.     SMILPlayToAssoc* pThisAssoc = (SMILPlayToAssoc*)(*i);
  459.     if((pThisAssoc->m_uGroupIndex == uGroupIndex) &&
  460.        (pThisAssoc->m_uTrackIndex == uTrackIndex))
  461.     {
  462. pPlayToAssoc = pThisAssoc;
  463. break;
  464.     }
  465. }
  466.     }
  467.     return pPlayToAssoc;
  468. }
  469. SMILPlayToAssoc*
  470. CSmilDocumentRenderer::getPlayToAssoc(const char* pPlayTo)
  471. {
  472.     SMILPlayToAssoc* pPlayToAssoc = 0;
  473.     UINT16 uCurGroupIndex = getCurrentGroup();
  474.     if(m_pPlayToAssocList)
  475.     {
  476. CHXSimpleList::Iterator i;
  477. for(i=m_pPlayToAssocList->Begin();i!=m_pPlayToAssocList->End();++i)
  478. {
  479.     SMILPlayToAssoc* pThisAssoc = (SMILPlayToAssoc*)(*i);
  480.     if(pThisAssoc->m_playTo == pPlayTo  &&
  481.     // /Fixes bug where already-removed media was being
  482.     // returned as active:
  483.     !pThisAssoc->m_bRemovePending  &&
  484.     // /Fixes PR 55355 where media from wrong group was
  485.     // being returned since delay values are relative to
  486.     // start of group:
  487.     uCurGroupIndex == pThisAssoc->m_uGroupIndex)
  488.     {
  489. if (!pPlayToAssoc)
  490. {
  491.     pPlayToAssoc = pThisAssoc;
  492. }
  493. // /Fixes bugs (including PR 55355) where multiple media
  494. // play to the same region and this function was always
  495. // returning the first media's playToAssoc even if it had
  496. // ended or been covered by other media; this resulted in
  497. // the new media not getting region mouse events:
  498. else if (pThisAssoc->m_ulDelay >= pPlayToAssoc->m_ulDelay  &&
  499. // /Find the one earlier than but closest to the
  500. // current time; if none such exists, find the one
  501. // closest to and later than current time (for pre-
  502. // scheduling of show/hide event purposes):
  503. (pThisAssoc->m_ulDelay <= m_ulCurrentTime  ||
  504. (pPlayToAssoc->m_ulDelay > m_ulCurrentTime  &&
  505. pThisAssoc->m_ulDelay < pPlayToAssoc->m_ulDelay)) )
  506. {
  507.     pPlayToAssoc = pThisAssoc;
  508. }
  509.     }
  510. }
  511.     }
  512.     return pPlayToAssoc;
  513. }
  514. SMILPlayToAssoc* CSmilDocumentRenderer::getPlayToAssocByMedia(const char* pszMediaID)
  515. {
  516.     SMILPlayToAssoc* pPlayToAssoc = NULL;
  517.     if (pszMediaID && m_pPlayToAssocList)
  518.     {
  519.         LISTPOSITION pos = m_pPlayToAssocList->GetHeadPosition();
  520.         while (pos)
  521.         {
  522.             SMILPlayToAssoc* pListMember =
  523.                 (SMILPlayToAssoc*) m_pPlayToAssocList->GetNext(pos);
  524.             if (pListMember && pListMember->m_id == pszMediaID)
  525.             {
  526.                 pPlayToAssoc = pListMember;
  527.                 break;
  528.             }
  529.         }
  530.     }
  531.     return pPlayToAssoc;
  532. }
  533.                 
  534. void
  535. CSmilDocumentRenderer::setPlayToAssoc(UINT16 uGroupIndex, UINT16 uTrackIndex, 
  536.       const char* pID, 
  537.       const char* pRepeatID,
  538.       const char* pPlayTo,
  539.       const char* pRegionName, 
  540.       const char* pBeginTransition,
  541.       const char* pEndTransition,
  542.       UINT32 lexicalOrder,
  543.                                       BOOL   bXMMSource)
  544. {
  545.     SMILPlayToAssoc* pPlayToAssoc = getPlayToAssoc(uGroupIndex, uTrackIndex);
  546.     if(!pPlayToAssoc)
  547.     {
  548. pPlayToAssoc     = new SMILPlayToAssoc;
  549. pPlayToAssoc->m_uGroupIndex = uGroupIndex;
  550. pPlayToAssoc->m_uTrackIndex = uTrackIndex;
  551. pPlayToAssoc->m_id     = pID;
  552. pPlayToAssoc->m_repeatid    = pRepeatID;
  553. pPlayToAssoc->m_playTo     = pPlayTo;
  554. pPlayToAssoc->m_ulDelay     = 0;
  555. pPlayToAssoc->m_ulDuration  = 0;
  556. pPlayToAssoc->m_bIsPersistentSource = FALSE;
  557. pPlayToAssoc->m_bDurationResolved = FALSE;
  558. pPlayToAssoc->m_bRemoveSite = TRUE; // default is remove
  559. pPlayToAssoc->m_bRemovePending = FALSE;
  560. pPlayToAssoc->m_pHyperlinks = new CHXSimpleList;
  561. pPlayToAssoc->m_pRendererEventHook  = NULL;
  562. pPlayToAssoc->m_pSiteInfoList     = new CHXSimpleList;
  563. pPlayToAssoc->m_ulLexicalOrder = lexicalOrder;
  564.         pPlayToAssoc->m_bXMMSource     = bXMMSource;
  565. pPlayToAssoc->m_bTrackStopped = FALSE;
  566. if (pBeginTransition)
  567. {
  568.     pPlayToAssoc->m_beginTransition  = pBeginTransition;
  569. }
  570. if (pEndTransition)
  571. {
  572.     pPlayToAssoc->m_endTransition = pEndTransition;
  573. }
  574. if(pRegionName)
  575. {
  576.     pPlayToAssoc->m_regionName  = pRegionName;
  577. }
  578. char cTemp[20]; /* Flawfinder: ignore */
  579. ::sprintf(cTemp,"%#010lx",(ULONG32)(void*)pPlayToAssoc); /* Flawfinder: ignore */
  580. pPlayToAssoc->m_tunerName   = (const char*) cTemp;
  581. ::sprintf(cTemp,"%#010lx",(ULONG32)(void*)pPlayToAssoc+1); /* Flawfinder: ignore */
  582. pPlayToAssoc->m_childTunerName = (const char*)cTemp;
  583. // see if the pPlayTo points to a valid CSmilBasicRegion
  584. BOOL bNoRegion = TRUE;
  585. if(pPlayTo)
  586. {
  587.             // First, assume that pPlayTo is an id and see
  588.             // if we can find the region by id
  589.     CSmilBasicRegion* pRegion = getRegionByID(pPlayTo);
  590.     if(pRegion)
  591.     {
  592. bNoRegion = FALSE;
  593.     }
  594.             else
  595.             {
  596.                 // We didn't find it by id, so try and find it
  597.                 // by regionName
  598.                 pRegion = getFirstRegionByName(pPlayTo);
  599.                 if (pRegion)
  600.                 {
  601.                     bNoRegion = FALSE;
  602.                 }
  603.             }
  604. }
  605. if(bNoRegion)
  606. {
  607.     // region name is tuner name if it's anonymous
  608.     pPlayToAssoc->m_playTo = pPlayToAssoc->m_childTunerName;
  609. }
  610. else
  611. {
  612.     pPlayToAssoc->m_playTo = pPlayTo;
  613. }
  614. if(!m_pPlayToAssocList)
  615. {
  616.     m_pPlayToAssocList = new CHXSimpleList;
  617. }
  618. m_pPlayToAssocList->AddTail(pPlayToAssoc);
  619.     }
  620. }
  621. void 
  622. CSmilDocumentRenderer::removeSourcemap(SMILPlayToAssoc* pPlayToAssoc)
  623. {
  624.     // get to the site manager and remove event hook
  625.     IHXEventHookMgr* pHookMgr = NULL;
  626.     m_pSiteMgr->QueryInterface(IID_IHXEventHookMgr, (void**)&pHookMgr);
  627.     CHXMapLongToObj::Iterator j = pPlayToAssoc->m_sourceMap.Begin();
  628.     for(; j != pPlayToAssoc->m_sourceMap.End(); ++j)
  629.     {
  630. CHXSimpleList* pRendererList = (CHXSimpleList*)(*j);
  631. HX_ASSERT(pRendererList);
  632. // /Check for NULL (fixes part of PR 120999) in case we are flippling
  633. // back and forth between nested meta clip and another clip in a list:
  634. if (pRendererList)
  635. {
  636.     CHXSimpleList::Iterator k = pRendererList->Begin();
  637.     for (; k != pRendererList->End(); ++k)
  638.     {
  639.         SMILSourceInfo* pSMILSourceInfo = (SMILSourceInfo*)(*k);
  640.         if (pSMILSourceInfo->m_pRendererEventHook && pHookMgr)     
  641.         {
  642.     pHookMgr->RemoveHook(pSMILSourceInfo->m_pRendererEventHook, 
  643.          pSMILSourceInfo->m_pRendererEventHook->GetChannelName(), 0);
  644.         }
  645.         HX_RELEASE(pSMILSourceInfo->m_pRendererEventHook);
  646.         HX_RELEASE(pSMILSourceInfo->m_pStream);
  647.         HX_RELEASE(pSMILSourceInfo->m_pRenderer);
  648.         HX_DELETE(pSMILSourceInfo);
  649.     }
  650.         }
  651. HX_DELETE(pRendererList);
  652.     }
  653.     pPlayToAssoc->m_sourceMap.RemoveAll();
  654.     HX_RELEASE(pHookMgr);
  655. }
  656. void
  657. CSmilDocumentRenderer::removeAllPlayToAssoc()
  658. {
  659.     if(m_pPlayToAssocList)
  660.     {
  661. CHXSimpleList::Iterator i = m_pPlayToAssocList->Begin();
  662. for(; i != m_pPlayToAssocList->End(); ++i)
  663. {
  664.     SMILPlayToAssoc* pPlayToAssoc = (SMILPlayToAssoc*)(*i);
  665.     
  666.     HX_DELETE(pPlayToAssoc->m_pHyperlinks);
  667.     
  668.     removeSourcemap(pPlayToAssoc);
  669.     if (pPlayToAssoc->m_pSiteInfoList)
  670.     {
  671. pPlayToAssoc->m_pSiteInfoList->RemoveAll();
  672. HX_DELETE(pPlayToAssoc->m_pSiteInfoList);
  673.     }
  674.     
  675.     HX_DELETE(pPlayToAssoc);
  676. }
  677.     }
  678.     HX_DELETE(m_pPlayToAssocList);
  679. }
  680. void
  681. CSmilDocumentRenderer::removeGroupsPlayToAssoc(UINT16 uGroupIndex)
  682. {
  683.     if(m_pPlayToAssocList)
  684.     {
  685. CHXSimpleList::Iterator i = m_pPlayToAssocList->Begin();
  686. for(; i != m_pPlayToAssocList->End(); ++i)
  687. {
  688.     SMILPlayToAssoc* pPlayToAssoc = (SMILPlayToAssoc*)(*i);
  689.     
  690.     /*
  691.     if the PlayToAssoc has the same group number as the group index,
  692.     then remove it.
  693.     */
  694.     
  695.     if ( pPlayToAssoc->m_uGroupIndex == uGroupIndex )
  696.     {
  697. removeSourcemap(pPlayToAssoc);
  698. if (pPlayToAssoc->m_pSiteInfoList)
  699. {
  700.     pPlayToAssoc->m_pSiteInfoList->RemoveAll();
  701. }
  702. break;
  703.     }     
  704. }
  705.     }
  706. }
  707. void
  708. CSmilDocumentRenderer::removeTracksPlayToAssoc(UINT16 uGroupIndex, UINT16 uTrackIndex)
  709. {
  710.     if (!m_pPlayToAssocList)
  711.     {
  712. return;
  713.     }
  714.     LISTPOSITION pos = m_pPlayToAssocList->GetHeadPosition();
  715.     while(pos)
  716.     {
  717. SMILPlayToAssoc* pPlayToAssoc = (SMILPlayToAssoc*)m_pPlayToAssocList->GetAt(pos);
  718. if (pPlayToAssoc->m_uGroupIndex == uGroupIndex &&
  719.     pPlayToAssoc->m_uTrackIndex == uTrackIndex)
  720. {
  721.     removeSourcemap(pPlayToAssoc);
  722.     HX_DELETE(pPlayToAssoc->m_pHyperlinks);         
  723.     HX_DELETE(pPlayToAssoc->m_pSiteInfoList);
  724.     HX_DELETE(pPlayToAssoc);
  725.     m_pPlayToAssocList->RemoveAt(pos);
  726.     break;
  727. }
  728. m_pPlayToAssocList->GetNext(pos);
  729.     }
  730.     
  731.     return;
  732. }
  733. BOOL
  734. CSmilDocumentRenderer::isMediaPausedAndDisabled(const char* pID)
  735. {
  736.     BOOL bIsPausedAndDisabled = FALSE;
  737.     CHXString* pTmpCStr;
  738.     if (m_pPausedAndDisabledIDMap  &&
  739.     m_pPausedAndDisabledIDMap->Lookup(pID, (void*&)pTmpCStr))
  740.     {
  741. bIsPausedAndDisabled = TRUE;
  742.     }
  743.     return bIsPausedAndDisabled;
  744. }
  745. BOOL
  746. CSmilDocumentRenderer::reenablePausedAndDisabledMedia(const char* pID,
  747. UINT16 uGroupIndex)
  748. {
  749.     BOOL bWasPausedAndDisabledAndNowIsNot = FALSE;
  750.     CHXString* pTmpCStr;
  751.     if (m_pPausedAndDisabledIDMap  &&
  752.     m_pPausedAndDisabledIDMap->Lookup(pID, (void*&)pTmpCStr))
  753.     {
  754. bWasPausedAndDisabledAndNowIsNot = TRUE;
  755. if(!m_pPausedAndDisabledIDMap->RemoveKey(pID))
  756. {
  757.     HX_ASSERT(0); //RemoveKey() should never fail, but...
  758.     (*m_pPausedAndDisabledIDMap)[pID] = NULL;
  759. }
  760. HX_DELETE(pTmpCStr);
  761.     }
  762.     float* pfPrePauseBrightness = NULL;
  763.     if (m_pPausedAndDisabledBrightnessMap  &&
  764.     m_pPausedAndDisabledBrightnessMap->Lookup(pID,
  765.     (void*&)pfPrePauseBrightness))
  766.     {
  767. if(!m_pPausedAndDisabledBrightnessMap->RemoveKey(pID))
  768. {
  769.     HX_ASSERT(0); //RemoveKey() should never fail, but...
  770.     (*m_pPausedAndDisabledBrightnessMap)[pID] = NULL;
  771. }
  772. // /Reset it to old brightness.  First get the renderer site:
  773. HX_ASSERT(m_pSiteInfoList);
  774. if(m_pSiteInfoList)
  775. {
  776.     CHXSimpleList::Iterator i = m_pSiteInfoList->Begin();
  777.     for(; i != m_pSiteInfoList->End(); ++i)
  778.     {
  779. SMILSiteInfo* pSiteInfo =(SMILSiteInfo*)(*i);
  780. if(pSiteInfo->m_uGroupIndex == uGroupIndex  &&
  781. pSiteInfo->m_MediaID == pID)
  782. {
  783.     IHXVideoControl* pVidCntrls = NULL;
  784.     HX_RESULT pnrVC =
  785.     pSiteInfo->m_pRendererSite->QueryInterface(
  786.     IID_IHXVideoControl, (void**)&pVidCntrls);
  787.     if (SUCCEEDED(pnrVC))
  788.     {
  789. HX_RESULT rsltSetBrtness = pVidCntrls->SetBrightness(
  790. *pfPrePauseBrightness);
  791. pSiteInfo->m_pRendererSite->ForceRedraw();
  792. HX_RELEASE(pVidCntrls);
  793.     }
  794.     HX_DELETE(pfPrePauseBrightness);
  795. }
  796.     }
  797. }
  798.     }
  799.     return bWasPausedAndDisabledAndNowIsNot;
  800. }
  801. CSmilAAnchorElement*
  802. CSmilDocumentRenderer::findHyperlinkElement(const char* pID, // region ID
  803.                                             const char* pMediaID,
  804.                                             UINT16      uXPos,
  805.                                             UINT16      uYPos,
  806.                                             BOOL        bResolveBeginOfFragmentTarget)
  807. {
  808.     // This code is not needed with new windowless site impl. of fullscreen 
  809.     if (IsFullScreen())
  810.     {
  811. IHXSiteWindowless* pSiteWndless = NULL;
  812. if (m_pRootLayout && m_pRootLayout->m_pSite)
  813. {
  814.     m_pRootLayout->m_pSite->QueryInterface(IID_IHXSiteWindowless, (void**) &pSiteWndless);
  815. }
  816. // need to do this conversion only for the OLD site implementation
  817. if (m_pRootLayout && m_pRootLayout->m_pSite && pSiteWndless == NULL)
  818. {
  819.     // If we are at full screen, then we need to scale the x and y
  820.     // mouse locations down to the original size, since for full
  821.     // screen we do not get a resizeSite.
  822.     //
  823.             // Get the current size
  824.     HXxSize cCurSize;
  825.     m_pRootLayout->m_pSite->GetSize(cCurSize);
  826.             // Scale it down
  827.     if (cCurSize.cx  &&  ANCHOR_POS_DONTCARE != uXPos)
  828.     {
  829. uXPos = (UINT16) (uXPos * m_topSiteOriginalSize.cx / cCurSize.cx);
  830.     }
  831.     if (cCurSize.cy  &&  ANCHOR_POS_DONTCARE != uYPos)
  832.     {
  833. uYPos = (UINT16) (uYPos * m_topSiteOriginalSize.cy / cCurSize.cy);
  834.     }
  835. }
  836. HX_RELEASE(pSiteWndless);
  837.     }
  838.     // /In order to fix PR 55110, we need to find the link that is on top in
  839.     // the region, not just the first active link in the list.  The one that
  840.     // is on top is the one that has the highest delay time of all those that
  841.     // are active at the time and place of the click:
  842.     CSmilAAnchorElement* pMostRecentValidAnchor = NULL;
  843.     ULONG32 ulMostRecentValidAnchorBegin = (UINT32)-1;
  844.     CHXSimpleList::Iterator i = m_pPlayToAssocList->Begin();
  845.     for(; i != m_pPlayToAssocList->End(); ++i)
  846.     {
  847. SMILPlayToAssoc* pAssoc = (SMILPlayToAssoc*)(*i);
  848. if(strcmp((const char*)pAssoc->m_playTo, pID) == 0 &&
  849.            strcmp((const char*)pAssoc->m_id, pMediaID) == 0 &&
  850.    pAssoc->m_uGroupIndex == m_uCurrentGroupIndex &&
  851.    pAssoc->m_pHyperlinks)
  852. {
  853.     if(pAssoc->m_ulDelay == (UINT32)-1)
  854.     {
  855. // not resolved yet
  856. return NULL;
  857.     }
  858.     // see if this site is current (visible) now;
  859.     // if it isn't then no hyperlinks can be active
  860.     // on that site.
  861.     if (pAssoc->m_pSiteInfoList)
  862.     {
  863. CHXSimpleList::Iterator j = pAssoc->m_pSiteInfoList->Begin();
  864. for (; j != pAssoc->m_pSiteInfoList->End(); ++j)
  865. {
  866.     BOOL bCurrentSite = TRUE; // if no site info, then
  867. // the site is always current
  868.     SMILSiteInfo* pSiteInfo = (SMILSiteInfo*)(*j);
  869.     ULONG32 ulTime = m_ulCurrentTime;
  870.     if (m_bSMILPresentationHasEnded)
  871.     {
  872. // /1/2 sec grace for last time sync to come
  873. // after end of presentation:
  874. ulTime -= (ulTime>500? 500: ulTime);
  875.     }
  876.     if(pSiteInfo->m_bRemoveSite)
  877.     {
  878. // /Fix for PR 34836:
  879. // live sources that have 0 dur, which means they play
  880. // forever, should have MAX_ULONG32, not 0, used as
  881. // their dur when calculating whether or not they're
  882. // visible at the current time:
  883. ULONG32 ulDur = pAssoc->m_ulDuration;
  884. if (pAssoc->m_bLiveSource  &&  0 == ulDur)
  885. {
  886.     ulDur = (ULONG32)(-1);
  887. }
  888. bCurrentSite = ulTime >= pSiteInfo->m_ulDelay &&
  889.        ulTime <= pSiteInfo->m_ulDelay + 
  890.        ulDur;
  891.     }
  892.     else
  893.     {
  894. bCurrentSite = ulTime >= pSiteInfo->m_ulDelay;
  895.     }
  896.     
  897.     if(bCurrentSite)
  898.     {
  899. UINT32 ulRelativeTime = ulTime - pAssoc->m_ulDelay;
  900. CHXSimpleList::Iterator j = pAssoc->m_pHyperlinks->Begin();
  901. for(; j != pAssoc->m_pHyperlinks->End(); ++j)
  902. {
  903.     CSmilAAnchorElement* pAnchor = (CSmilAAnchorElement*)(*j);
  904.     CSmilBasicRegion* pRegion = getRegionByID(pAssoc->m_playTo);
  905.     if (pRegion)
  906.     {
  907. HXxRect mediaRect;
  908. mediaRect.left = 0;
  909. mediaRect.top = 0;
  910. if(pRegion->m_bMediaSizeSet)
  911. {
  912.     mediaRect.right = pRegion->m_mediaSize.cx;
  913.     mediaRect.bottom = pRegion->m_mediaSize.cy;
  914. }
  915. else
  916. {
  917.     mediaRect.right = pRegion->m_rect.right;
  918.     mediaRect.bottom = pRegion->m_rect.bottom;
  919. }
  920. // /ulRelativeTime is begin of anchor element
  921. // relative to begin of element that got this
  922. // mouse event, so we need to adjust for begin
  923. // offset from its sync-base in the case where
  924. // this is an 'a' element which actually has
  925. // the same sync-base, i.e., its sync-base is
  926. // *not* (its child) element that got the mouse
  927. // event:
  928. ULONG32 ulBeginAdjustmentIfIsAAnchor = 0;
  929. ULONG32 ulCurElementDelay = pAnchor->m_ulDelay;
  930. if (pAnchor->isAAnchor())
  931. {
  932.     CSmilElement* pThisElement =
  933.     m_pSmilParser->findElement(pAssoc->m_id);
  934.     if (pThisElement  &&  pThisElement->
  935.     m_bCurBeginIsOffsetFromSyncBase)
  936.     {
  937. ulBeginAdjustmentIfIsAAnchor =
  938. pThisElement->
  939. m_ulBeginOffsetFromSyncBase;
  940.     }
  941.     ulRelativeTime +=
  942.     ulBeginAdjustmentIfIsAAnchor;
  943.     // /If anchor delay isn't set, just use it's
  944.     // child media's delay:
  945.     if ((UINT32)-1 == ulCurElementDelay)
  946.     {
  947. ulCurElementDelay = pThisElement->m_ulDelay;
  948.     }
  949. }
  950. if(pAnchor->isCurrentLink(ulRelativeTime,
  951. uXPos, uYPos, mediaRect,
  952. (ResizeZoom == pRegion->m_eResizeBehavior),
  953. pRegion->m_dZoomScaleFactorX,
  954. pRegion->m_dZoomScaleFactorY))
  955. {
  956.     if ((UINT32)-1 ==
  957.     ulMostRecentValidAnchorBegin  ||
  958.     ulMostRecentValidAnchorBegin <=
  959.     ulCurElementDelay)
  960.     {
  961. ulMostRecentValidAnchorBegin = ulCurElementDelay;
  962. pMostRecentValidAnchor = pAnchor;
  963.     }
  964. }
  965.     }
  966. }
  967.     }
  968. }
  969.     }
  970. }
  971.     }
  972.     if (pMostRecentValidAnchor)
  973.     {
  974. //Now, we have to see if this points to a
  975. // fragment in the current SMIL presentation and,
  976. // if so, make sure that the begin time of the
  977. // associated element has been resolved.  If not,
  978. // we need to resolve it, per the SMIL 2.0 spec,
  979. // but only if on an activation of this hyperlink,
  980. // i.e., if bResolveTargetBeginIfFragment==TRUE:
  981. const char* pFragment = pMostRecentValidAnchor->m_href.GetBuffer(2);
  982. HX_ASSERT(pFragment);
  983. //Only do the following if this is a fragment:
  984. if(pFragment  &&  '#' == *pFragment)
  985. {
  986.     BOOL bFragFoundAndResolved = TRUE;
  987.     UINT32 ulFragmentOffset = m_pSmilParser->getFragmentOffset(
  988.     &(pFragment[1]), 
  989.     /* This is passed by ref:*/
  990.     bFragFoundAndResolved, bResolveBeginOfFragmentTarget,
  991.     m_ulCurrentTime); 
  992.     //Fixes PR 22655:
  993.     //Ignore if not found or not yet resolved:
  994.     if (!bFragFoundAndResolved)
  995.     {
  996. return NULL;
  997.     }
  998. }
  999. return pMostRecentValidAnchor;
  1000.     }
  1001.     return NULL;
  1002. }
  1003. // /Returns NULL if element doesn't have either an alt or a
  1004. // longdesc value, otherwise returns the element with the pID:
  1005. CSmilElement*
  1006. CSmilDocumentRenderer::findIfCurElementHasAltOrLongdesc(const char* pID,
  1007. UINT16 ulXPos, UINT16 ulYPos)
  1008. {
  1009.     CSmilElement* pRetElement = NULL;
  1010.     CHXSimpleList::Iterator i = m_pPlayToAssocList->Begin();
  1011.     // /We need to return the one who's on top in this region in case there
  1012.     // are multiple media playing to this region:
  1013.     for(; i != m_pPlayToAssocList->End(); ++i)
  1014.     {
  1015. SMILPlayToAssoc* pAssoc = (SMILPlayToAssoc*)(*i);
  1016. if(strcmp((const char*)pAssoc->m_playTo, pID) == 0  &&
  1017. pAssoc->m_uGroupIndex == m_uCurrentGroupIndex)
  1018. {
  1019.     if(pAssoc->m_ulDelay == (UINT32)-1)
  1020.     {
  1021. // not resolved yet
  1022. continue; // /Check for other media playing to this region.
  1023.     }
  1024.     // /Optimization: helps speed up the decision as to whether or not
  1025.     // this one should even be considered:
  1026.     if (pAssoc->m_ulDuration + pAssoc->m_ulDelay <= m_ulCurrentTime  &&
  1027.     pAssoc->m_bRemoveSite)
  1028.     {
  1029. continue; // /Check for other media playing to this region.
  1030.     }
  1031.     // /First, see if this (x,y) point is over the media in this
  1032.     // region:
  1033.     CSmilBasicRegion* pRegion = getRegionByID(pAssoc->m_playTo);
  1034.     if (pRegion)
  1035.     {
  1036. HXxRect mediaRect;
  1037. mediaRect.left = 0;
  1038. mediaRect.top = 0;
  1039. if(pRegion->m_bMediaSizeSet)
  1040. {
  1041.     mediaRect.right = pRegion->m_mediaSize.cx;
  1042.     mediaRect.bottom = pRegion->m_mediaSize.cy;
  1043. }
  1044. else
  1045. {
  1046.     mediaRect.right = pRegion->m_rect.right;
  1047.     mediaRect.bottom = pRegion->m_rect.bottom;
  1048. }
  1049. UINT32 ulWidth =
  1050. mediaRect.right - mediaRect.left;
  1051. UINT32 ulHeight =
  1052. mediaRect.bottom - mediaRect.top;
  1053. if(ulXPos > ulWidth  ||  ulYPos > ulHeight)
  1054. {
  1055.     // /It's not in bounds, so keep looking:
  1056.     continue;
  1057. }
  1058.     }
  1059.     // see if this site is current (visible) now;
  1060.     // if it isn't then no element can be active
  1061.     // in that site:
  1062.     if (pAssoc->m_pSiteInfoList)
  1063.     {
  1064. CHXSimpleList::Iterator j = pAssoc->m_pSiteInfoList->Begin();
  1065. for (; j != pAssoc->m_pSiteInfoList->End(); ++j)
  1066. {
  1067.     BOOL bCurrentSite = TRUE; // if no site info, then
  1068. // the site is always current
  1069.     SMILSiteInfo* pSiteInfo = (SMILSiteInfo*)(*j);
  1070.     if(pSiteInfo->m_bRemoveSite)
  1071.     {
  1072. // /Live sources that have 0 dur, meaning they play
  1073. // forever, should have MAX_ULONG32, not 0, used as
  1074. // their dur when calculating whether or not they're
  1075. // visible at the current time:
  1076. ULONG32 ulDur = pAssoc->m_ulDuration;
  1077. if (pAssoc->m_bLiveSource  &&  0 == ulDur)
  1078. {
  1079.     ulDur = (ULONG32)(-1);
  1080. }
  1081. bCurrentSite =
  1082.        m_ulCurrentTime >= pSiteInfo->m_ulDelay  &&
  1083.        m_ulCurrentTime <= pSiteInfo->m_ulDelay+ulDur;
  1084.     }
  1085.     else
  1086.     {
  1087. bCurrentSite = m_ulCurrentTime >= pSiteInfo->m_ulDelay;
  1088.     }
  1089.     
  1090.     if(bCurrentSite)
  1091.     {
  1092. CSmilElement* pElement = m_pSmilParser->findElement(
  1093. pAssoc->m_id);
  1094. // /Now, see if element has alt tag:
  1095. if (pElement)
  1096. {
  1097.     if (pElement->m_alt.GetLength() > 0  ||
  1098.     pElement->m_longdesc.GetLength() > 0)
  1099.     {
  1100. // /Found it, so assign it as temp winner:
  1101. pRetElement = pElement;
  1102. // /Fixes PR 53282 by continuing (instead of
  1103. // quitting & returning the first one found):
  1104. // this one is on top of all others in this
  1105. // region so far; resolveZOrder() says it has
  1106. // sorted them so that the highest z-ordered
  1107. // one is the last in the list, so all we
  1108. // have to do is continue looking but keep
  1109. // this one as the temporary winner until
  1110. // another, later one is found:
  1111. continue;
  1112.     }
  1113. }
  1114.     }
  1115. }
  1116.     }
  1117. }
  1118.     }
  1119.     return pRetElement;
  1120. }
  1121. STDMETHODIMP CSmilDocumentRenderer::HandleMouseMove(
  1122.     void*       pWindow,
  1123.     const char* pID, // Region ID
  1124.                                     const char* pMediaID,
  1125.     UINT16      uXPos,
  1126.     UINT16      uYPos,
  1127.     UINT32 kRMAEvent,
  1128.     REF(BOOL)   bHandleSetCursor)
  1129. {
  1130.     // since IHXStatusMessage::SetStatus() effectively
  1131.     // results in a mouse move (and I don't want to loop
  1132.     // forever) don't do anything if this mouse move event
  1133.     // has the same xy as the previous mouse move event
  1134.     bHandleSetCursor = FALSE;
  1135.     if(uXPos == m_usOldXPos &&
  1136. uYPos == m_usOldYPos)
  1137.     {
  1138. // /We don't want to claim HXR_OK in case media itself needs this
  1139. // mouse event:
  1140. return HXR_CANCELLED;
  1141.     }
  1142.     m_usOldXPos = uXPos;
  1143.     m_usOldYPos = uYPos;
  1144.     HX_RESULT rc = HXR_FAIL;
  1145.     BOOL bIsMouseLeaveEvent = (HX_MOUSE_LEAVE == kRMAEvent);
  1146.     if (pMediaID)
  1147.     {
  1148. HX_RESULT rslt = HXR_FAILED;
  1149. switch (kRMAEvent)
  1150. {
  1151.     case HX_MOUSE_MOVE:
  1152.     {
  1153.     }
  1154.     break;
  1155.     case HX_MOUSE_ENTER:
  1156.     {
  1157. rslt = m_pSmilParser->tryToResolveBeginEndEvents(
  1158. "inBoundsEvent", pMediaID, m_ulCurrentTime+1);
  1159.     }
  1160.     break;
  1161.     case HX_MOUSE_LEAVE:
  1162.     {
  1163. HX_RESULT rslt = m_pSmilParser->tryToResolveBeginEndEvents(
  1164. "outOfBoundsEvent", pMediaID, m_ulCurrentTime);
  1165.     }
  1166.     break;
  1167.     default:
  1168.     {
  1169. HX_ASSERT(kRMAEvent  &&  "unexpected mouse event");
  1170. break;
  1171.     }
  1172. }
  1173. if (SUCCEEDED(rslt)  &&
  1174. // /Fixes PR 56052: don't do anything after end of
  1175. // presentation otherwise layout
  1176. !m_bSMILPresentationHasEnded)
  1177. {
  1178.     handleElements();
  1179. }
  1180.     }
  1181. #if defined(_WINDOWS)
  1182.     HCURSOR hCurrentCursor = GetCursor();
  1183. #endif
  1184.     CSmilAAnchorElement* pAnchor = NULL;
  1185.     HX_ASSERT(pMediaID);
  1186.     if (pMediaID  &&  !isMediaPausedAndDisabled(pMediaID)  &&
  1187.     // /For mouse leave event, don't find hyperlink:
  1188.     !bIsMouseLeaveEvent)
  1189.     {
  1190. pAnchor = findHyperlinkElement(pID, pMediaID, uXPos, uYPos);
  1191.     }
  1192.     // /Fixes PR 56503: if any element will begin or end when pID is clicked
  1193.     // (i.e., if any has begin|end="pID.activateEvent[+|-n]") then we should
  1194.     // show the hand cursor:
  1195.     BOOL bHasActivateEventListener = FALSE;
  1196.     if (!pAnchor  &&  HX_MOUSE_MOVE == kRMAEvent  &&  pMediaID  &&
  1197.     // /Fixes case where presentation has stopped; we don't want
  1198.     // to show the hand cursor for activateEvents because they
  1199.     // won't do anything when presentation is done:
  1200.     !m_bSMILPresentationHasEnded)
  1201.     {
  1202. bHasActivateEventListener = m_pSmilParser->hasActivateEventListener(
  1203. pMediaID, m_uCurrentGroupIndex);
  1204.     }
  1205.     if(pAnchor  ||  bHasActivateEventListener)
  1206.     {
  1207. #if defined(_WINDOWS)
  1208. if(hCurrentCursor != m_hHyperlinkCursor)
  1209. {
  1210.     m_bNeedToSetHyperlinkCursor = TRUE;
  1211. }
  1212. #elif defined(_MACINTOSH)
  1213.         if (m_hHyperlinkCursor)
  1214.         {
  1215.     m_bResetCursor = TRUE;
  1216.     ::SetCursor(*m_hHyperlinkCursor);
  1217.         }
  1218. #endif
  1219. #if defined(_UNIX)  &&  (!(defined(_BEOS)))  &&  defined(USE_XWINDOWS)
  1220. if (m_pDisplay && m_Window && m_hHyperlinkCursor && m_hCurrentCursor != m_hHyperlinkCursor)
  1221. {
  1222.     XLockDisplay(m_pDisplay);
  1223.     XDefineCursor(m_pDisplay, m_Window, m_hHyperlinkCursor);
  1224.     XUnlockDisplay(m_pDisplay);
  1225.     m_hCurrentCursor = m_hHyperlinkCursor;
  1226. }
  1227. #endif
  1228. if (m_pStatusMessage  &&  pAnchor)
  1229. {
  1230.     // /Override displaying of URL if alt can be shown instead:
  1231.     if (pAnchor->m_alt.GetLength() > 0)
  1232.     {
  1233. m_pStatusMessage->SetStatus (pAnchor->m_alt);
  1234.     }
  1235.     else
  1236.     {
  1237. m_pStatusMessage->SetStatus (pAnchor->m_href);
  1238.     }
  1239.     m_bStatusMessageSet = TRUE;
  1240. }
  1241. rc = HXR_OK; // handled
  1242.     }
  1243.     else
  1244.     {
  1245. BOOL bOKToResetStatusMessage = TRUE;
  1246. // /There's no anchor displayed in the status bar, so look to see
  1247. // if this element has an alt tag value (or longdesc) and, if so,
  1248. // display it:
  1249. CSmilElement* pElemAltOrLongdesc =
  1250. findIfCurElementHasAltOrLongdesc(pID, uXPos, uYPos);
  1251. if (pElemAltOrLongdesc)
  1252. {
  1253.     if (m_pStatusMessage)
  1254.     {
  1255. if (pElemAltOrLongdesc->m_alt.GetLength() > 0)
  1256. {
  1257.     m_pStatusMessage->SetStatus(
  1258.     pElemAltOrLongdesc->m_alt);
  1259.     m_bStatusMessageSet = TRUE;
  1260.     bOKToResetStatusMessage = FALSE;
  1261. }
  1262.     }
  1263. }
  1264. #if defined(_WINDOWS)
  1265. if(hCurrentCursor == m_hHyperlinkCursor)
  1266. {
  1267.     //We need to change it back -- we just moved off of a hyperlink:
  1268.     m_bNeedToSetHyperlinkCursor = FALSE;
  1269.     // /Do opposite logic for for mouse Leave event:
  1270.     if (bIsMouseLeaveEvent)
  1271.     {
  1272. // /We need to force a cursor update because
  1273. // handleSetCursor() doesn't get called when we move off of
  1274. // linked media and onto an area where there is no media:
  1275. bHandleSetCursor = TRUE;
  1276.     }
  1277. }
  1278. #elif defined(_MACINTOSH)
  1279. if (m_bResetCursor)
  1280. {
  1281.     m_bResetCursor = FALSE;
  1282.     InitCursor();
  1283. }
  1284. #elif defined(_UNIX)  &&  (!(defined(_BEOS)))  &&  defined(USE_XWINDOWS)
  1285. if (m_pDisplay && m_Window && m_hCurrentCursor == m_hHyperlinkCursor)
  1286. {
  1287.     XLockDisplay(m_pDisplay);
  1288.     XUndefineCursor(m_pDisplay, m_Window);
  1289.     XUnlockDisplay(m_pDisplay);
  1290.     m_hCurrentCursor = 0;
  1291. }
  1292. #endif
  1293. if (m_pStatusMessage &&  bOKToResetStatusMessage  &&
  1294.     m_bStatusMessageSet)
  1295. {
  1296.     m_pStatusMessage->SetStatus(NULL);
  1297.     m_bStatusMessageSet = FALSE;
  1298. }
  1299.     }
  1300.     return rc;
  1301. }
  1302. STDMETHODIMP_(BOOL) CSmilDocumentRenderer::HandleSetCursor()
  1303. {
  1304.     BOOL rc = FALSE;
  1305. #ifdef _WINDOWS
  1306.     if(m_bNeedToSetHyperlinkCursor)
  1307.     {
  1308. // We don't want to overwrite our pre hyperlink cursor
  1309. HCURSOR hTemp = SetCursor(m_hHyperlinkCursor);
  1310. if (hTemp != m_hHyperlinkCursor)
  1311. {
  1312.     m_hPreHyperlinkCursor = hTemp;
  1313. }
  1314. rc = TRUE;
  1315.     }
  1316.     else if (m_hPreHyperlinkCursor)
  1317.     {
  1318. SetCursor(m_hPreHyperlinkCursor);
  1319. m_hPreHyperlinkCursor = NULL;
  1320. rc = TRUE;
  1321.     }
  1322. #endif
  1323.     return rc;
  1324. }
  1325. STDMETHODIMP CSmilDocumentRenderer::HandleLButtonUp(const char* pRegionID,
  1326.                                                     const char* pMediaID,
  1327.                                                     UINT16      uXPos,
  1328.                                                     UINT16      uYPos,
  1329.                                                     REF(BOOL)   rbHandled)
  1330. {
  1331. #if defined(_UNIX)  &&  (!(defined(_BEOS)))  &&  defined(USE_XWINDOWS)
  1332. //Clear the previously set cursors before leaving this window
  1333.     if(m_Window)
  1334.     {
  1335.  XLockDisplay(m_pDisplay);
  1336.         XUndefineCursor(m_pDisplay, m_Window);
  1337.  XUnlockDisplay(m_pDisplay);
  1338.     }
  1339. #endif
  1340.     // /Note: "activateEvent" is equivalent to a click event on
  1341.     // the primary mouse button or when a series of keystrokes
  1342.     // activates the visual element.  We got here because of a
  1343.     // mouse click, so we need to fire a "focusInEvent" if the
  1344.     // element didn't already have the "focus":
  1345. /* // /XXXEH- TODO: add and manage variable that keeps track of 
  1346.     // which element has the focus, if any, and fire it if this
  1347.     // element does not have it when clicked:
  1348.     if (!hasSMIL2_20000731Draft_Focus((const char*)pPlayToAssoc->m_playTo))
  1349.     {
  1350. rslt = m_pSmilParser->tryToResolveBeginEndEvents(
  1351. "focusInEvent",
  1352. (const char*)pPlayToAssoc->m_id,m_ulCurrentTime);
  1353.     }
  1354. */
  1355.     HX_RESULT rc = HXR_OK;
  1356.     rbHandled = FALSE;
  1357.     CSmilAAnchorElement* pAnchor = NULL;
  1358.     if (!isMediaPausedAndDisabled(pMediaID))
  1359.     {
  1360. BOOL bResolveTargetBeginIfFragment = TRUE;
  1361. pAnchor = findHyperlinkElement(pRegionID, pMediaID, uXPos, uYPos,
  1362. bResolveTargetBeginIfFragment);
  1363.         rc = handleNamedEvent(pRegionID, pMediaID, "activateEvent");
  1364.     }
  1365.     HX_RESULT rcHLT = HXR_OK;
  1366.     
  1367.     if (pAnchor)
  1368.     {
  1369. rcHLT = handleHyperlinkTraversal(pAnchor);
  1370.         if (SUCCEEDED(rcHLT))
  1371.         {
  1372.             rbHandled = TRUE;
  1373.         }
  1374.     }
  1375.     rc = (HXR_OK == rc)? rcHLT : rc;
  1376.     return rc;
  1377. }
  1378. HX_RESULT
  1379. CSmilDocumentRenderer::handleHyperlinkTraversal(CSmilAAnchorElement* pAnchor,
  1380.                                                 BOOL bCalledFromCallback)
  1381. {
  1382.     HX_RESULT rc = HXR_OK;
  1383.     HX_RESULT rsltOfRaisingActivateEvent = HXR_FAIL;
  1384.     if(pAnchor && pAnchor->m_href.GetLength() > 0)
  1385.     {
  1386. if(m_pParent)
  1387. {
  1388.     IHXPlayer* pPlayer = m_pParent->getPlayer();
  1389.     if(pPlayer)
  1390.     {
  1391. const char* pTarget = "_player";
  1392. const char* pSendTo = NULL;
  1393. if (pAnchor->m_sendTo.GetLength())
  1394. {
  1395.     pSendTo = (const char*)pAnchor->m_sendTo;
  1396. }
  1397. BOOL bIsOnLoadActuation =
  1398. (0 == strcmp(pAnchor->m_actuate, "onLoad"));
  1399. BOOL bForceCallbackForNonExternalLinks =
  1400. !bCalledFromCallback  &&  !pAnchor->m_bExternal;
  1401. if ((bIsOnLoadActuation  &&
  1402. ("pause"==pAnchor->m_show  ||
  1403. "replace"==pAnchor->m_show))  ||
  1404. // /Always schedule callback if on Mac and
  1405. // PR84836 conditions exist:
  1406. // /Also, to help fix PR 91817, force callback for non-
  1407. // external links in case this is from accesskey press
  1408. // or some other link-activating event on main thread:
  1409. bForceCallbackForNonExternalLinks)
  1410. {
  1411.                     if (!bCalledFromCallback)
  1412.                     {
  1413.                         if (!m_pHyperlinkCallback)
  1414.                         {
  1415.                             m_pHyperlinkCallback = new CHyperlinkCallback(this);
  1416.                             m_pHyperlinkCallback->AddRef();
  1417. }
  1418. if (!(m_pHyperlinkCallback->IsCallbackPending()))
  1419. {
  1420.     m_pHyperlinkCallback->SetAnchor(pAnchor);
  1421.     m_pHyperlinkCallback->SetCallbackPending(TRUE);
  1422.     CallbackHandle hand = m_pScheduler->RelativeEnter(
  1423.     m_pHyperlinkCallback, 0);
  1424.     m_pHyperlinkCallback->SetCallbackHandle(hand);
  1425.                         }
  1426. else
  1427. {
  1428.     // /Helps fix problem brought on by fix for PR 67170
  1429.     // and PR 67536: allow for multiple simultaneous
  1430.     // hurls at the same time.  This will only happen
  1431.     // right after a seek as long as findNextPendingOn..
  1432.     // only returns more than one anchor after a seek:
  1433.     HX_RESULT pnrslt =
  1434. m_pHyperlinkCallback->AddAdditionalAnchor(pAnchor);
  1435.     HX_ASSERT (HXR_OK == pnrslt);
  1436. }
  1437.                         return HXR_OK;
  1438.                     }
  1439.                 }
  1440. if (pAnchor->m_bExternal)
  1441. {
  1442.     if (pAnchor->m_target.GetLength() > 0)
  1443.     {
  1444. // /Viper now has control over the "external" browser
  1445. // that is integrated into the Viper player UI.
  1446. // Sending the SMIL-file-specifed link's target value
  1447. // instead of just "_browser" fixes PR 56073:
  1448. pTarget = (const char*)pAnchor->m_target;
  1449.     }
  1450.     else // /Use old-school value:
  1451.     {
  1452. pTarget = "_browser";
  1453.     }
  1454. }
  1455. // /This is possibly used in at least two places, below:
  1456. const char* pszEventName = "activateEvent";
  1457. // /In order to decide what to do when pAnchor->m_target is
  1458. // set, we need to figure out if that string matches a region
  1459. // in the current presentation's layout.  If so, we need to
  1460. // play the URL in that region, else we need to play it to
  1461. // an external player (or to a browser if external="true"):
  1462. BOOL bNeedToTargetANamedPlayerInstance = FALSE;
  1463. if (pAnchor->m_target.GetLength() > 0)
  1464. {
  1465.     HX_ASSERT("replace(ignored)"==pAnchor->m_show);
  1466.     if (!pAnchor->m_bTargetIsARegion  &&  !pAnchor->m_bExternal)
  1467.     {
  1468. // /Setting this and using it, below, fixes PR 55404:
  1469. bNeedToTargetANamedPlayerInstance = TRUE;
  1470.     }
  1471.     // /Helps fix PR 52891: pAnchor targets a region, so
  1472.     // activate the element that's been set up to play when
  1473.     // this link gets activated:
  1474.     else if (pAnchor->m_pNode  &&
  1475.     // /Fixes PR 57845: above if() could have failed
  1476.     // for other reasons, so make sure this is TRUE:
  1477.     pAnchor->m_bTargetIsARegion)
  1478.     {
  1479. HX_RESULT rslt = HXR_OK;
  1480. rslt = m_pSmilParser->tryToResolveBeginEndEvents(
  1481. pszEventName, // /"activateEvent"
  1482. (const char*)pAnchor->m_pNode->m_id,
  1483. m_ulCurrentTime);
  1484. if SUCCEEDED(rslt)
  1485. {
  1486.     handleElements();
  1487. }
  1488. goto cleanup;
  1489.     }
  1490. }
  1491. // /This fixes PR 77583 so that a, area, anchor all raise
  1492. // activateEvents so that other elements can begin/end on
  1493. // them, but only if the link is going to an external source,
  1494. // i.e., not replacing the current presentation.  Some members
  1495. // of the W3C SYMM Working Group that defined SMIL 2.0 said
  1496. // that our implementation was faulty for not raising
  1497. // activateEvents on anchors, but the spec isn't specific
  1498. // about whether or not you need to raise this.   It's useful,
  1499. // however, so just do it:
  1500. if (pAnchor->m_bExternal  ||  pAnchor->m_show != "replace")
  1501. {
  1502.     rsltOfRaisingActivateEvent =
  1503.     m_pSmilParser->tryToResolveBeginEndEvents(
  1504.     pszEventName, // /"activateEvent"
  1505.     (const char*)pAnchor->m_pNode->m_id,
  1506.     m_ulCurrentTime);
  1507. }
  1508. if(pAnchor->m_href[0] == '#')
  1509. {
  1510.     pPlayer->AddRef();
  1511.     // relative URL, just seek...
  1512.     CHXString fragID = pAnchor->m_href.Mid(1);
  1513.     seekTo(fragID);
  1514.     pPlayer->Release();
  1515. }
  1516. else
  1517. {
  1518.     IHXHyperNavigate* pHyper = 0;
  1519.     /* Calculate source player's play state noting that
  1520.      * show's value can override the m_sourcePlaystate val:
  1521.      * The logic comes out to:
  1522.      * if (show=="pause"  ||  show="replace")
  1523.      *   := pause 
  1524.      * else
  1525.      *   := m_sourcePlaystate
  1526.      */
  1527.     SMILLinkPlaystate sourcePlaystate =
  1528.     SMILLinkPlaystatePause;
  1529.     if ( ("pause"==pAnchor->m_show  ||
  1530.     "replace"==pAnchor->m_show)  &&
  1531.     !pAnchor->m_bExternal)
  1532.     {
  1533. sourcePlaystate = SMILLinkPlaystatePause;
  1534.     }
  1535.     else
  1536.     {
  1537. sourcePlaystate = pAnchor->m_sourcePlaystate;
  1538.     }
  1539.     m_bDestPlaystateIsPause = (SMILLinkPlaystatePause ==
  1540.      pAnchor->m_destinationPlaystate);
  1541.     BOOL bIsOldSMIL1ShowEqualsPause =
  1542.     ("pause" == pAnchor->m_show);
  1543.     // /If the destination player is different from the
  1544.     // source (current) player, and if the source player
  1545.     // is going to keep playing, then we need to set its
  1546.     // relative audio volume level:
  1547.     if (SMILLinkPlaystatePlay == sourcePlaystate  ||
  1548.     // /Helps fix PR 55120: even if src player pauses,
  1549.     // we may need to set dest player's audio level:
  1550.     SMILLinkPlaystatePause == sourcePlaystate)
  1551.     {
  1552. // /Re-wrote this to implement destinationLevel on new
  1553. // or existing LPPlayer; helps fix PR 55120 & PR 55791:
  1554. if (pAnchor->m_ulSourceLevel_pct != 100  ||
  1555. pAnchor->m_ulDestinationLevel_pct != 100)
  1556. {
  1557.     UINT16 uCurVol = 50;
  1558.     IHXAudioPlayer* pAudioPlayer = NULL;
  1559.     if (HXR_OK== pPlayer->QueryInterface(IID_IHXAudioPlayer,
  1560.     (void **)&pAudioPlayer))
  1561.     {
  1562. #if 0 /*XXXEH- need TLC work in order to enable this: */
  1563. // /XXXH- as soon as I can figure out how to
  1564. // get at the player (LPP) that gets created
  1565. // by the command:openWindow() call that'll
  1566. // happen, below, we'll be able to use
  1567. // pAudioPlayer->GetAudioVolume() instead, on
  1568. // both it and the current (source) player.
  1569. // With those IHXVolume objects that are
  1570. // returned for the respective players, we'll
  1571. // be able to set each players' volume level
  1572. // independently, & without affecting any other
  1573. // players' volumes in the process.
  1574. IHXVolume* pSourceAudioPlayerVolume =
  1575. pAudioPlayer->GetAudioVolume();
  1576. if (pSourceAudioPlayerVolume)
  1577. {
  1578.     uCurVol = pSourceAudioPlayerVolume->GetVolume();
  1579.     {
  1580. // /Same, so just set shared-by-all-
  1581. // players volume level to new val:
  1582. double fNewSourceVol = (double)(
  1583. (float)uCurVol * (double(float(
  1584. pAnchor->m_ulSourceLevel_pct)) /
  1585. 100.0) );
  1586. pSourceAudioVPlayerVolume->SetVolume(0);
  1587.     }
  1588. }
  1589. HX_ASSERT(pSourceAudioPlayerVolume);
  1590. HX_RELEASE(pSourceAudioPlayerVolume);
  1591. #else
  1592. IHXVolume* pSourceVolume =
  1593. pAudioPlayer->GetDeviceVolume();
  1594. if (pSourceVolume)
  1595. {
  1596.     uCurVol = pSourceVolume->GetVolume();
  1597.     if (pAnchor->m_ulSourceLevel_pct  ==
  1598.     pAnchor->m_ulDestinationLevel_pct)
  1599.     {
  1600. // /Same, so just set shared-by-all-
  1601. // players volume level to new val:
  1602. double fNewSourceVol = (double)(
  1603. (float)uCurVol * (double(float(
  1604. pAnchor->m_ulSourceLevel_pct)) /
  1605. 100.0) );
  1606. pSourceVolume->SetVolume(
  1607. UINT16(ULONG32(
  1608. (float)fNewSourceVol)));
  1609.     }
  1610.     else if (100 ==
  1611.     pAnchor->m_ulDestinationLevel_pct)
  1612.     {
  1613. // /Dest. level==100: just adjust
  1614. // current player's tracks' soundLevels
  1615. // to sourceLevel.  Fixed PR 55791:
  1616. AdjustSoundLevelsOfAllCurrentTracks(
  1617. (UINT16)m_uCurrentGroupIndex,
  1618. pAnchor->m_ulSourceLevel_pct, NULL);
  1619.     }
  1620.     else
  1621.     {
  1622. // /Dest. level (d) != current player's
  1623. // audio level (s), so set soundLevel to
  1624. // (s*(100/d)) for all source player
  1625. // tracks, then set IHXAudioPlayer
  1626. // volume to d:
  1627. double fS = double((float)
  1628. pAnchor->m_ulSourceLevel_pct);
  1629. double fD = double((float)
  1630. pAnchor->m_ulDestinationLevel_pct);
  1631. // /Avoid divide/0:
  1632. if (fD < XXXEH_MIN_DEST_AUDIOPLAYER_VOL)
  1633. {
  1634.     fD = XXXEH_MIN_DEST_AUDIOPLAYER_VOL;
  1635. }
  1636. UINT32 ulNewSourceLevel_pct =
  1637. UINT32(float(fS * (100.0 / fD)));
  1638. // /Avoid too-loud source player trcks:
  1639. if (ulNewSourceLevel_pct <
  1640. XXXEH_MIN_DEST_AUDIOPLAYER_VOL)
  1641. {
  1642.     ulNewSourceLevel_pct =
  1643.     XXXEH_MIN_DEST_AUDIOPLAYER_VOL;
  1644. }
  1645. // /Adjust current player's tracks:
  1646. AdjustSoundLevelsOfAllCurrentTracks(
  1647. (UINT16)m_uCurrentGroupIndex,
  1648. ulNewSourceLevel_pct, NULL);
  1649. // /Then adjust shared players'
  1650. // volume to get correct dest player
  1651. // volume (fixes PR 55791 case 3):
  1652.                                         double dNewVolumeOfAllPlayers  =
  1653.                                             ((double) fD) * ((double) uCurVol) / 100.0;
  1654.                                         UINT32 ulNewVolumeOfAllPlayers =
  1655.                                             (UINT32) dNewVolumeOfAllPlayers;
  1656. pSourceVolume->SetVolume(ulNewVolumeOfAllPlayers);
  1657.     }
  1658. }
  1659. HX_ASSERT(pSourceVolume);
  1660. HX_RELEASE(pSourceVolume);
  1661. #endif
  1662.     }
  1663.     HX_ASSERT(pAudioPlayer);
  1664.     HX_RELEASE(pAudioPlayer);
  1665. }
  1666.     }
  1667.     // /Changing to "if()" from "else if()", here, fixes
  1668.     // PR 85007: sourcePlaystate="pause" code was being
  1669.     // ignored due to new soundLevel code, above, that
  1670.     // co-opted the prior conditional of the if() statement
  1671.     // without allowing this original "pause" handling-code to
  1672.     // run:
  1673.     if (SMILLinkPlaystatePause == sourcePlaystate)
  1674.     {
  1675. // /If external or new player, then just pause the
  1676. // current player, otherwise save our spot and launch
  1677. // the new URL in the current player, then wait until
  1678. // that presentation stops and restart the saved one
  1679. // at the saved spot:
  1680. if (pAnchor->m_bExternal  ||  "new"==pAnchor->m_show  ||
  1681. bIsOldSMIL1ShowEqualsPause  ||
  1682. bNeedToTargetANamedPlayerInstance)
  1683. {
  1684.     pPlayer->Pause();
  1685. }
  1686. // /Else save where we are so we can retart where we
  1687. // left off when the new presentation finishes:
  1688. else
  1689. {
  1690.     if (!m_pPlayerResumeStack)
  1691.     {
  1692. m_pPlayerResumeStack = new CHXStack;
  1693.     }
  1694.     if (m_pPlayerResumeStack)
  1695.     {
  1696. CSmilPlayerResumePos* pResumePos =
  1697. new CSmilPlayerResumePos(
  1698. m_uCurrentGroupIndex,
  1699. m_ulCurrentTime,
  1700. sourcePlaystate);
  1701. m_pPlayerResumeStack->Push(pResumePos);
  1702.     }
  1703. }
  1704.     }
  1705.     // /sourcePlaystate == stop, so stop it:
  1706.     else if (SMILLinkPlaystateStop == sourcePlaystate)
  1707.     {
  1708. // /m_show must be "new" (not "pause" or "replace"):
  1709. HX_ASSERT("new"==pAnchor->m_show);
  1710. pPlayer->Stop();
  1711.     }
  1712.     else
  1713.     {
  1714. // /sourcePlaystate had better be play, already
  1715. // handled above in prior if():
  1716. HX_ASSERT(SMILLinkPlaystatePlay == sourcePlaystate);
  1717.     }
  1718.     CHXString urlString;
  1719.     convertURL((const char*) m_pParent->getURLRoot(),
  1720.                                (const char*) m_pParent->getURLPrefix(),
  1721.                                (const char*) pAnchor->m_href,
  1722.                                urlString);
  1723.     BOOL bIsMailtoURL = !(strncmp("mailto:", urlString, 7));
  1724.     if (bIsMailtoURL)
  1725.     {
  1726. pTarget = "_browser";
  1727.     }
  1728.     BOOL bIsCommandOpenWindowURL = FALSE;
  1729.     // /Now, if show="new", we need to create a new player
  1730.     // and open the URL in it:
  1731.     // This is also true of the old SMIL 1.0 show="pause":
  1732. #if defined(XXXEH_USE_OPENWINDOW_METHOD)
  1733.     BOOL bIsCommandURL = !(strncmp("command:", urlString, 8));
  1734.     if (bIsCommandURL)
  1735.     {
  1736. const char* pCommandAction = ((const char*)urlString)+8;
  1737. // /Look for "command:[s*]openwindow" where [s*] is 0
  1738. // or more white-space characters:
  1739. while (isspace(*pCommandAction))
  1740. {
  1741.     pCommandAction++;
  1742. }
  1743. if (*pCommandAction)
  1744. {
  1745.     bIsCommandOpenWindowURL = !(strnicmp("openWindow",
  1746. pCommandAction, 10));
  1747. }
  1748.     }
  1749.     if (!bIsCommandURL  &&
  1750.     (!strncmp("new", pAnchor->m_show,3)  ||
  1751.     bIsOldSMIL1ShowEqualsPause  ||
  1752.     bNeedToTargetANamedPlayerInstance) )
  1753. #else
  1754.     if (!strncmp("new", pAnchor->m_show,3)  ||
  1755.     bIsOldSMIL1ShowEqualsPause  ||
  1756.     bNeedToTargetANamedPlayerInstance)
  1757. #endif
  1758.     {
  1759. // /If show is 'new' then either fire off a new
  1760. // player or send it to the browser, depending on
  1761. // what the value of m_bExternal is:
  1762. if (pAnchor->m_bExternal)
  1763. {
  1764.     // /If it's external, then go ahead and open in
  1765.     // the browser and let it possibly send the URL
  1766.     // back to the current player; the SMIL2 Linking
  1767.     // Module Draft is silent on what to do here (as
  1768.     // of 2001-02-01):
  1769.     if(HXR_OK == pPlayer->QueryInterface(
  1770.     IID_IHXHyperNavigate, (void**)&pHyper))
  1771.     {
  1772.                                 // XXXMEH - use updated method which checks
  1773.                                 // for <rn:param> children
  1774.                                 GoToURLWithParamCheck(urlString, pTarget, pSendTo,
  1775.                                                       pHyper, pAnchor, m_pContext,
  1776.       !bIsOnLoadActuation);
  1777. //                                pHyper->GoToURL(urlString, pTarget);
  1778.                                 pHyper->Release();
  1779.     }
  1780. }
  1781. else // /Create new player and open URL in it:
  1782. {
  1783. #if defined(XXXEH_USE_OPENWINDOW_METHOD)
  1784.     // /Have the TLC create a new player for us via
  1785.     // "command:openWindow(windowName,URL,behavior)":
  1786.     CHXString pOpenWindowURL = "command:openWindow(";
  1787.     // /Now, add the "target", if specified:
  1788.     if (pAnchor->m_target.GetLength() > 0)
  1789.     {
  1790. pOpenWindowURL += pAnchor->m_target;
  1791.     }
  1792.     // /Otherwise, we need to make up a unique name:
  1793.     else
  1794.     {
  1795. pOpenWindowURL += pAnchor->m_pNode->m_id;
  1796. char* pTmp = new char[64];
  1797. ULONG32 ulCurTime = HX_GET_TICKCOUNT();
  1798. itoa(ulCurTime, pTmp, 16);
  1799. pOpenWindowURL += pTmp;
  1800. delete [] pTmp;
  1801.     }
  1802.     pOpenWindowURL += ",";
  1803.     pOpenWindowURL += urlString;
  1804.     // /Set the source (current) player's behavior:
  1805.     switch (sourcePlaystate)
  1806.     {
  1807. case SMILLinkPlaystatePlay:
  1808. {
  1809.     pOpenWindowURL += ",behavior=continue";
  1810. }
  1811. break;
  1812. case SMILLinkPlaystatePause:
  1813. {
  1814.     pOpenWindowURL += ",behavior=pause";
  1815. }
  1816. break;
  1817. case SMILLinkPlaystateStop:
  1818. {
  1819.     pOpenWindowURL += ",behavior=stop";
  1820. }
  1821. break;
  1822. default:
  1823. {
  1824.     HX_ASSERT(0&&"bad sourcePlaystate");
  1825. }
  1826. break;
  1827.     }
  1828.     pOpenWindowURL += ")";
  1829.     if(HXR_OK == pPlayer->QueryInterface(
  1830.     IID_IHXHyperNavigate, (void**)&pHyper))
  1831.     {
  1832.                                 // XXXMEH - use updated method which checks
  1833.                                 // for <rn:param> children
  1834.                                 GoToURLWithParamCheck(pOpenWindowURL, pTarget, 
  1835. // /Ignore sendTo if external="false":
  1836. NULL,
  1837.                                         pHyper, pAnchor, m_pContext,
  1838. !bIsOnLoadActuation);
  1839. // pHyper->GoToURL(pOpenWindowURL, pTarget);
  1840. pHyper->Release();
  1841.     }
  1842. #else
  1843. #pragma message(" Non-command:openWindow() new-player creation not finished")
  1844.     IHXClientEngine* pClientEngine =
  1845.     m_pParent->getClientEngine();
  1846.     if (pClientEngine)
  1847.     {
  1848. IHXPlayer* pNewPlayer = NULL;
  1849. if (HXR_OK == pClientEngine->CreatePlayer(
  1850. pNewPlayer)  &&  pNewPlayer)
  1851. {
  1852.     pNewPlayer->SetClientContext(m_pContext);
  1853.     // /XXXEH- delete player when done!
  1854.     HX_RESULT openrslt = pNewPlayer->OpenURL(
  1855.     (const char*)urlString);
  1856.     if (HXR_OK == openrslt)
  1857.     {
  1858. // /If playstate is pause, then we
  1859. // don't want to begin the player:
  1860. if (SMILLinkPlaystatePause !=
  1861.      pAnchor->m_destinationPlaystate) 
  1862. {
  1863.     pNewPlayer->Begin();
  1864. }
  1865. return HXR_OK; 
  1866.     }
  1867. }
  1868.     }
  1869. #endif /* (else ndef) XXXEH_USE_OPENWINDOW_METHOD.*/
  1870. }
  1871.     }
  1872.     else if (pAnchor->m_bExternal  ||
  1873.     // /This fixes PR 76406, as was done below to
  1874.     // fix PR 62276: if it's *any* kind of "command:.."
  1875.     // URL, send it through IRMAHypernav:
  1876.     bIsCommandURL  ||
  1877.     // /Fixes PR 78480: if it's a "mailto:..." link
  1878.     // it needs to go through IMRAHypernav:
  1879.     bIsMailtoURL  ||
  1880.     // /This fixes PR 62276 by making sure
  1881.     // command:openwindow ULRs go through IRMAHypernav
  1882.     // and pPlayer->OpenURL().  This could be construed
  1883.     // as being contrary to the SMIL 2.0 spec by
  1884.     // effectively overriding show="replace", but it is
  1885.     // a proprietary URL and thus can be handled in a
  1886.     // proprietary way, i.e, won't break interoperability:
  1887.     bIsCommandOpenWindowURL)
  1888.     {
  1889. if(HXR_OK == pPlayer->QueryInterface(
  1890. IID_IHXHyperNavigate, (void**)&pHyper))
  1891. {
  1892.                             // XXXMEH - use updated method which checks
  1893.                             // for <rn:param> children
  1894.                             GoToURLWithParamCheck(urlString, pTarget, pSendTo,
  1895.                                                   pHyper, pAnchor, m_pContext,
  1896.   !bIsOnLoadActuation);
  1897. //     pHyper->GoToURL(urlString, pTarget);
  1898.     HX_RELEASE(pHyper);
  1899. }
  1900.     }
  1901.     else // /Open in same window:
  1902.     {
  1903. // /Fixes PR 67630: OpenURL() call resulted in player
  1904. // destroying our parent CSmilRenderer which in turn
  1905. // destroyed us, and subsequent HandleSetCursor() call
  1906. // was causing hang as "this" has been deleted.  Fix
  1907. // is to AddRef the parent before calling OpenURL:
  1908. m_pParent->AddRef();
  1909. // /This fixes the subsequent problem (hang) in PR 91817
  1910. // When multiple links are queued to hurl simultaneously,
  1911. // just hurl the first replace-presentation-in-main-
  1912. // player one we come to and delete all the rest:
  1913. if (m_pHyperlinkCallback)
  1914. {
  1915.     m_pHyperlinkCallback->ClearExtraAnchorList();
  1916. }
  1917. HX_RESULT openrslt = HXR_FAIL;
  1918. BOOL bHandledByPlayer2 = FALSE;
  1919. IHXCommonClassFactory* pFactory=
  1920. m_pParent->getFactory();
  1921. IHXPlayer2* pPlayer2 = NULL;
  1922. if (pFactory  &&  HXR_OK == 
  1923. pPlayer->QueryInterface(IID_IHXPlayer2,
  1924. (void**)&pPlayer2))
  1925. {
  1926.     IHXRequest* pRequest = NULL;
  1927.     pFactory->CreateInstance(CLSID_IHXRequest,
  1928.     (void**) &pRequest);
  1929.     if (pRequest)
  1930.     {
  1931. IHXValues* pValues = 0;
  1932. if(HXR_OK == pFactory->CreateInstance(
  1933. CLSID_IHXValues, (void**)&pValues))
  1934. {
  1935.     // /Fixes open-in-same-window version of
  1936.     // PR 84160: call OpenRequest() (with
  1937.     // AutoActivated prop) instead of OpenURL:
  1938.     pValues->SetPropertyULONG32("AutoActivated",
  1939.     (ULONG32)(bIsOnLoadActuation));
  1940.     pRequest->SetRequestHeaders(pValues);
  1941.     pRequest->SetURL((const char*)urlString);
  1942.     bHandledByPlayer2 = TRUE;
  1943.     openrslt = pPlayer2->OpenRequest(pRequest);
  1944.     HX_RELEASE(pValues);
  1945. }
  1946. HX_RELEASE(pRequest);
  1947.     }
  1948.     HX_RELEASE(pPlayer2);
  1949. }
  1950. // /No IHXPlayer2 or other prob; just call OpenURL():
  1951. if (!bHandledByPlayer2)
  1952. {
  1953.     openrslt = pPlayer->OpenURL((const char*)urlString);
  1954. }
  1955. if (HXR_OK == openrslt)
  1956. {
  1957.     // /First, set cursor back to pre-hyperlink one
  1958.     // so that the new presentation doesn't have the
  1959.     // link "hand" cursor on it at first:
  1960. #if defined(_WINDOWS)
  1961.     m_bNeedToSetHyperlinkCursor = FALSE;
  1962. #endif
  1963.     HandleSetCursor();
  1964.     pPlayer->Begin();
  1965.     // /NOTE: if m_bDestPlaystateIsPause, then we'll
  1966.     // pause the player after
  1967.     // IHXClientAdviseSink::OnBuffering() has been
  1968.     // called with 100% done.
  1969. }
  1970. // /Remove ref added prior to OpenURL(), above:
  1971. m_pParent->Release();
  1972.     }
  1973. }
  1974.     }
  1975. }
  1976.     }
  1977. cleanup:
  1978.     if SUCCEEDED(rsltOfRaisingActivateEvent)
  1979.     {
  1980. handleElements();
  1981.     }
  1982.     return rc;
  1983. }
  1984.  
  1985. STDMETHODIMP CSmilDocumentRenderer::HandleCharEvent(UINT16 uChar)
  1986.     HX_RESULT rc = HXR_FAIL;
  1987.     // /XXXEH- TODO: fix this after interop.  We should probably treat this 
  1988.     // separate from events and have a "tryToResolveCharPressEvents()" func. 
  1989.     // Also, handle wide characters (right???): 
  1990.     char* pEventName = new char[32];
  1991.     sprintf(pEventName,"accesskey(%c)", uChar); /* Flawfinder: ignore */
  1992. // /#define XXXEHODGE_DEBUG_OUTPUT_HANDLECHAREVENT
  1993. #if defined(_DEBUG)  &&  defined(XXXEHODGE_DEBUG_OUTPUT_HANDLECHAREVENT)
  1994. {FILE* f1 = ::fopen("c:\smil2.txt", "a+"); ::fprintf(f1, "nHandleCharEvent(%u), currentTime: %lun", uChar, m_ulCurrentTime);::fclose(f1);}
  1995. #endif
  1996.     rc = m_pSmilParser->tryToResolveBeginEndEvents(pEventName,
  1997.     // /Fixes PR 69849 (and needed for PR 58290): the new optimized
  1998.     // code that uses maps instead of lists didn't take into account
  1999.     // the fact that accesskey events have no associated event-element
  2000.     // ID since they come from the keyboard, so we now use this string
  2001.     //(which is an invalid XML id) as the fake ID:
  2002.     ACCESSKEY_EVENT_FAKE_ID_STRING,
  2003.     m_ulCurrentTime);
  2004.     if SUCCEEDED(rc)
  2005.     {
  2006. #if defined(_DEBUG)  &&  defined(XXXEHODGE_DEBUG_OUTPUT_HANDLECHAREVENT)
  2007. {FILE* f1 = ::fopen("c:\smil2.txt", "a+"); ::fprintf(f1, "n    HandleCharEvent(%u): calling tryToResolveBeginEndEvents() returned HXR_OK at time: %lun", uChar, m_ulCurrentTime);::fclose(f1);}
  2008. #endif
  2009. handleElements();
  2010.     }
  2011.     // /Next, let's see if we have an anchor|a|area tag awaiting an
  2012.     // accesskey event.  Go through all currently-playing media and see if
  2013.     // any of their anchors are awaiting a keypress:
  2014.     if (m_pPlayToAssocList)
  2015.     {
  2016.         CHXSimpleList::Iterator indx = m_pPlayToAssocList->Begin();
  2017.         for(; indx != m_pPlayToAssocList->End(); ++indx)
  2018.         {
  2019.     SMILPlayToAssoc* pAssoc = (SMILPlayToAssoc*)(*indx);
  2020.     if(pAssoc->m_uGroupIndex == m_uCurrentGroupIndex &&
  2021.        pAssoc->m_pHyperlinks)
  2022.     {
  2023.         if(pAssoc->m_ulDelay == (UINT32)-1)
  2024.         {
  2025.     // not resolved yet
  2026.     break;
  2027.         }
  2028.         CHXSimpleList::Iterator indxA = pAssoc->m_pHyperlinks->Begin();
  2029.         for(; indxA != pAssoc->m_pHyperlinks->End(); ++indxA)
  2030.         {
  2031.     CSmilAAnchorElement* pAnchor = 
  2032.     (CSmilAAnchorElement*)(*indxA);
  2033.     // /XXXEH- TODO: handle wide chars here:
  2034.     if (pAnchor->m_accesskey[0] == uChar)
  2035.     {
  2036.         HXxRect regionRect;
  2037.         regionRect.left = 0;
  2038.         regionRect.top = 0;
  2039.         regionRect.right = (INT32)ANCHOR_POS_DONTCARE;
  2040.         regionRect.bottom = (INT32)ANCHOR_POS_DONTCARE;
  2041.         ULONG32 ulTime = m_ulCurrentTime;
  2042.         if (m_bSMILPresentationHasEnded)
  2043.         {
  2044.     // /1/2 sec grace for last time sync to come
  2045.     // after end of presentation:
  2046.     ulTime -= (ulTime>500? 500: ulTime);
  2047.         }
  2048.         if (pAnchor->isCurrentLink(ulTime,
  2049.         ANCHOR_POS_DONTCARE, ANCHOR_POS_DONTCARE,
  2050.         regionRect,
  2051.         // /XXXEH- need to maybe deal with resized region
  2052.         // if multiple hotspots (links w/coords) exist on
  2053.         // same media:
  2054.         FALSE, 1.0, 1.0))
  2055.         {
  2056.     // /BE VERY CAREFUL HERE!!!: the following might
  2057.     // cause a replacement of this renderer instance by
  2058.     // launching a new presentation, so we need to be
  2059.     // sure not to do anything but return after this:
  2060.     rc = handleHyperlinkTraversal(pAnchor);
  2061.     return rc;
  2062.         }
  2063.     }
  2064.         }
  2065.     }
  2066.         }
  2067.     }
  2068.     return rc;
  2069. }
  2070. HX_RESULT 
  2071. CSmilDocumentRenderer::handleNamedEvent(const char* pRegionID,
  2072.                                         const char* pMediaID,
  2073. const char* pEventName)
  2074.     HX_RESULT rc = HXR_OK;
  2075.     if (m_pSmilParser)
  2076.     {
  2077.         HX_RESULT rslt = HXR_OK;
  2078.         rslt = m_pSmilParser->tryToResolveBeginEndEvents(pEventName,
  2079.                                                          pMediaID,
  2080.                                                          m_ulCurrentTime);
  2081.         if (SUCCEEDED(rslt))
  2082.         {
  2083.     handleElements();
  2084.         }
  2085.     }
  2086.     return rc;
  2087. }
  2088. STDMETHODIMP CSmilDocumentRenderer::HandleGotFocus(const char* pRegionID,
  2089.                                                    const char* pMediaID)
  2090. {
  2091.     return handleNamedEvent(pRegionID, pMediaID, "focusInEvent");
  2092. }
  2093. STDMETHODIMP CSmilDocumentRenderer::HandleLostFocus(const char* pRegionID,
  2094.                                                     const char* pMediaID)
  2095. {
  2096.     return handleNamedEvent(pRegionID, pMediaID, "focusOutEvent");
  2097. }
  2098. HX_RESULT
  2099. CSmilDocumentRenderer::detachSite(IHXSite* pSite)
  2100. {
  2101.     HX_RESULT rc = HXR_OK;
  2102.     // remove site from site info list
  2103.     LISTPOSITION pos = m_pSiteInfoList->GetHeadPosition();
  2104.     while(pos)
  2105.     {
  2106. SMILSiteInfo* pSiteInfo = 
  2107.     (SMILSiteInfo*)m_pSiteInfoList->GetAt(pos);
  2108. if(pSiteInfo->m_pRendererSite == pSite)
  2109. {
  2110.     CSmilBasicRegion* pRegion = getRegionByID(pSiteInfo->m_regionID);
  2111.     if(pRegion)
  2112.     {
  2113. pRegion->m_pSite->DestroyChild(pSite);
  2114.     }
  2115.     m_pSiteInfoList->RemoveAt(pos);
  2116.     // at this time go through the PlayToAssocList list and
  2117.     // change any that reference the soon to be removed 
  2118.     // site info.
  2119.     if (m_pPlayToAssocList)
  2120.     {
  2121. CHXSimpleList::Iterator i = m_pPlayToAssocList->Begin();
  2122. for (; i!=m_pPlayToAssocList->End(); ++i)
  2123. {
  2124.     SMILPlayToAssoc* pPlayToAssoc = (SMILPlayToAssoc*)(*i);
  2125.     
  2126.     LISTPOSITION pos = pPlayToAssoc->m_pSiteInfoList->Find(pSiteInfo);
  2127.     pPlayToAssoc->m_pSiteInfoList->RemoveAt(pos);
  2128. }
  2129.     }
  2130.     
  2131.     HX_DELETE(pSiteInfo);
  2132.     break;
  2133. }
  2134. m_pSiteInfoList->GetNext(pos);
  2135.     }
  2136.     return rc;
  2137. }
  2138. HX_RESULT 
  2139. CSmilDocumentRenderer::doSourceUpdate(SMILPlayToAssoc* pPlayToAssoc,
  2140.       CSmilSourceUpdate* pUpdateElement)
  2141. {
  2142.     HX_RESULT     rc = HXR_OK;
  2143.     BOOL     bUpdated = FALSE;
  2144.     const char*     pID = (const char*)pUpdateElement->m_srcID;    
  2145.     CSmilElement*   pThisElement = m_pSmilParser->findElement(pID);
  2146.     if (pUpdateElement->m_updateTag == UpdateDuration)
  2147.     {
  2148. if(pThisElement->m_bBeginOffsetSet  &&
  2149. // /Helps fix PR 79699 et al:
  2150. !pUpdateElement->m_bDurationIsPureOfDelay)
  2151. {     
  2152.     if((INT32)pUpdateElement->m_ulUpdatedDuration > pThisElement->m_lBeginOffset)
  2153.     {
  2154. pPlayToAssoc->m_ulDuration = pUpdateElement->m_ulUpdatedDuration -
  2155. pThisElement->m_lBeginOffset;
  2156.     }
  2157.     else
  2158.     {
  2159. pPlayToAssoc->m_ulDuration = 0;
  2160.     }
  2161. }
  2162. else
  2163. {
  2164.     pPlayToAssoc->m_ulDuration = pUpdateElement->m_ulUpdatedDuration;
  2165. }
  2166. bUpdated = TRUE;
  2167.     }
  2168.     else if (pUpdateElement->m_updateTag == UpdateDelay)
  2169.     {
  2170. pPlayToAssoc->m_ulDelay = pUpdateElement->m_ulUpdatedDelay;
  2171. bUpdated = TRUE;
  2172.     }
  2173.     if (bUpdated)
  2174.     {
  2175. CHXMapLongToObj::Iterator j = pPlayToAssoc->m_sourceMap.Begin();    
  2176. CHXSimpleList* pRendererInfoList = (CHXSimpleList*)(*j);
  2177. SMILSourceInfo* pSourceInfo = (SMILSourceInfo*)pRendererInfoList->GetHead();
  2178. IHXLayoutStream* pLayoutStream = NULL;
  2179. if(HXR_OK == 
  2180.    pSourceInfo->m_pStream->QueryInterface(IID_IHXLayoutStream, 
  2181.     (void**)&pLayoutStream))
  2182. {
  2183.     IHXValues* pStreamProps = NULL;
  2184.     if(HXR_OK == pLayoutStream->GetProperties(pStreamProps))
  2185.     {
  2186. if (pUpdateElement->m_updateTag == UpdateDuration)
  2187. {
  2188. #if defined(_DEBUG)  &&  defined(XXXEH_DEBUG_HANDLESOURCE_AND_TRACKDURATIONSET)
  2189. ULONG32 ulPriorDuration = pPlayToAssoc->m_ulDuration;
  2190. BOOL bPriorDuration = TRUE;
  2191. if (HXR_OK != pStreamProps->GetPropertyULONG32("duration", ulPriorDuration))
  2192. {
  2193.     bPriorDuration = FALSE;
  2194. }
  2195. {FILE* f1 = ::fopen("c:\smil2AddDuration.txt", "a+");
  2196. ::fprintf(f1, "$$$ CSmilDocumentRenderer::doSourceUpdate(pID=%s, "
  2197.      "pPlayToAssoc->m_ulDuration=%lu, pThisElement->m_ulDuration=%lu,"
  2198.      "prior stream duration=%lu%sn", (const char*)pID,
  2199.      pPlayToAssoc->m_ulDuration, pThisElement->m_ulDuration, ulPriorDuration,
  2200.      bPriorDuration?"":"(NO PRIOR DUR)");  ::fclose(f1);}
  2201. #endif
  2202.     pStreamProps->SetPropertyULONG32("duration",
  2203. pPlayToAssoc->m_ulDuration);
  2204. }
  2205. else if (pUpdateElement->m_updateTag == UpdateDelay)
  2206. {
  2207. #if defined(_DEBUG)  &&  defined(XXXEH_DEBUG_HANDLESOURCE_AND_TRACKDURATIONSET)
  2208. ULONG32 ulPriorDelay = pPlayToAssoc->m_ulDelay;
  2209. BOOL bPriorDelay = TRUE;
  2210. if (HXR_OK != pStreamProps->GetPropertyULONG32("delay", ulPriorDelay))
  2211. {
  2212.     bPriorDelay = FALSE;
  2213. }
  2214. {FILE* f1 = ::fopen("c:\smil2AddDuration.txt", "a+");
  2215. ::fprintf(f1, "$$$ CSmilDocumentRenderer::doSourceUpdate(pID=%s, "
  2216.      "pPlayToAssoc->m_ulDelay=%lu, pThisElement->m_ulDelay=%lu,"
  2217.      "prior stream delay=%lu%sn", (const char*)pID,
  2218.      pPlayToAssoc->m_ulDelay, pThisElement->m_ulDelay, ulPriorDelay,
  2219.      bPriorDelay?"":"(NO PRIOR DELAY)");  ::fclose(f1);}
  2220. #endif
  2221.     pStreamProps->SetPropertyULONG32("delay",
  2222.     pPlayToAssoc->m_ulDelay);
  2223. }
  2224. pLayoutStream->SetProperties(pStreamProps);
  2225. HX_RELEASE(pStreamProps);
  2226.     }
  2227.     HX_RELEASE(pLayoutStream);
  2228. }
  2229. updateSiteEvents(pPlayToAssoc->m_uGroupIndex);
  2230.     }
  2231.     return rc;
  2232. }
  2233. HX_RESULT
  2234. CSmilDocumentRenderer::updateStreamTiming(const char* pElementID,
  2235.   UINT32 ulDuration)
  2236. {
  2237.     HX_RESULT rc = HXR_OK;
  2238.     CSmilElement* pElement = m_pSmilParser->findElement(pElementID);
  2239.     if(pElement)
  2240.     {
  2241. // find the SMILPlayToAssoc associated with this element ID
  2242. SMILPlayToAssoc* pPlayToAssoc = NULL;
  2243. if(m_pPlayToAssocList)
  2244. {
  2245.     CHXSimpleList::Iterator i = m_pPlayToAssocList->Begin();
  2246.     for (; i!=m_pPlayToAssocList->End(); ++i)
  2247.     {
  2248. SMILPlayToAssoc* pThisAssoc = (SMILPlayToAssoc*)(*i);
  2249. if(pThisAssoc->m_id == (const char*)pElement->m_pNode->m_id  &&
  2250. // /Added this while re-fixing PR 69639; be sure to
  2251. // ignore already-stopped track & keep looking in
  2252. // case element restart made new track w/same id:
  2253. !pThisAssoc->m_bTrackStopped)
  2254. {
  2255.     pPlayToAssoc = pThisAssoc;
  2256.     break;
  2257. }
  2258.     }
  2259. }
  2260. if(pPlayToAssoc && 
  2261.    pPlayToAssoc->m_sourceMap.GetCount() > 0)
  2262. {
  2263.     pPlayToAssoc->m_ulDuration = ulDuration;
  2264.     CHXMapLongToObj::Iterator j = pPlayToAssoc->m_sourceMap.Begin();
  2265.     CHXSimpleList* pRendererInfoList = (CHXSimpleList*)(*j);
  2266.     SMILSourceInfo* pSourceInfo = (SMILSourceInfo*)pRendererInfoList->GetHead();
  2267.     IHXLayoutStream* pLayoutStream = NULL;
  2268.     if(HXR_OK == 
  2269. pSourceInfo->m_pStream->QueryInterface(IID_IHXLayoutStream, 
  2270.     (void**)&pLayoutStream))
  2271.     {
  2272. IHXValues* pStreamProps = NULL;
  2273. if(HXR_OK == pLayoutStream->GetProperties(pStreamProps))
  2274. {
  2275. #if defined(_DEBUG)  &&  defined(XXXEH_DEBUG_HANDLESOURCE_AND_TRACKDURATIONSET)
  2276. {FILE* f1 = ::fopen("c:\smil2AddDuration.txt", "a+");
  2277. ::fprintf(f1, "^v^ CSmilDocumentRenderer::updateStreamTiming(%s, duration=%lu),"
  2278.   "pPlayToAssoc->m_ulDuration=%lu, pElement->m_ulDuration=%lun",
  2279.     (const char*)pElementID, ulDuration, pPlayToAssoc->m_ulDuration, pElement->m_ulDuration);
  2280. ::fclose(f1);}
  2281. #endif
  2282.     pStreamProps->SetPropertyULONG32("duration", ulDuration);
  2283.     pLayoutStream->SetProperties(pStreamProps);
  2284.     pStreamProps->Release();
  2285.     // XXX HP THIS IS NO-OP!!
  2286.     // update delay for subsequent elements
  2287.     //updateStreamDelay(pPlayToAssoc->m_uGroupIndex,
  2288.     //       pPlayToAssoc->m_ulDelay);
  2289. }
  2290. pLayoutStream->Release();
  2291.     }
  2292.     updateSiteEvents(pPlayToAssoc->m_uGroupIndex);
  2293. }
  2294.     }
  2295.     return rc;
  2296. }
  2297. HX_RESULT
  2298. CSmilDocumentRenderer::updateStreamDelay(UINT16 uGroupIndex,
  2299.  UINT32 ulInitialDelay)
  2300. {
  2301.     HX_RESULT rc = HXR_OK;
  2302.     if(m_pPlayToAssocList)
  2303.     {
  2304. CHXSimpleList::Iterator i = m_pPlayToAssocList->Begin();
  2305. for (; i!=m_pPlayToAssocList->End(); ++i)
  2306. {
  2307.     SMILPlayToAssoc* pPlayToAssoc = (SMILPlayToAssoc*)(*i);
  2308.     if(pPlayToAssoc->m_uGroupIndex == uGroupIndex &&
  2309. pPlayToAssoc->m_ulDelay > ulInitialDelay)
  2310.     {
  2311. UINT32 ulNewDelay = pPlayToAssoc->m_ulDelay;
  2312. pPlayToAssoc->m_ulDelay = ulNewDelay;
  2313. if(pPlayToAssoc->m_sourceMap.GetCount() > 0)
  2314. {
  2315.     CHXMapLongToObj::Iterator j = pPlayToAssoc->m_sourceMap.Begin();
  2316.     CHXSimpleList* pRendererList = (CHXSimpleList*)(*j);
  2317.     CHXSimpleList::Iterator k = pRendererList->Begin();
  2318.     for (; k != pRendererList->End(); ++k)
  2319.     {
  2320. SMILSourceInfo* pSMILSourceInfo = (SMILSourceInfo*)(*k);
  2321. IHXLayoutStream* pLayoutStream = NULL;
  2322. if(HXR_OK == 
  2323.     pSMILSourceInfo->m_pStream->QueryInterface(
  2324.     IID_IHXLayoutStream,
  2325.     (void**)&pLayoutStream))
  2326. {
  2327.     IHXValues* pStreamProps = NULL;
  2328.     if(HXR_OK == pLayoutStream->GetProperties(
  2329. pStreamProps))
  2330.     {
  2331. pStreamProps->SetPropertyULONG32("delay", 
  2332.     pPlayToAssoc->m_ulDelay);
  2333. pLayoutStream->SetProperties(pStreamProps);
  2334. pStreamProps->Release();
  2335.     }
  2336.     pLayoutStream->Release();
  2337. }
  2338.     }
  2339. }
  2340.     }
  2341. }
  2342.     }
  2343.     return rc;
  2344. }
  2345. HX_RESULT CSmilDocumentRenderer::updateSiteEvents(UINT16 uGroupIndex)
  2346. {
  2347.     HX_RESULT rc = HXR_OK;
  2348.     if(m_pPlayToAssocList)
  2349.     {
  2350. #if defined(XXXMEH_OLD_UPDATE_SITE_EVENTS)
  2351.         // Save the animation events so we 
  2352.         // can re-add them later
  2353.         // XXXMEH - TODO - if an animation beging is tied
  2354.         // to the begin of a media element whose previously-scheduled
  2355.         // begin time changes, then we need to be able change 
  2356.         // the animate event.
  2357.         CHXSimpleList cTmp;
  2358.         if (m_pEventList)
  2359.         {
  2360.             LISTPOSITION pos = m_pEventList->GetHeadPosition();
  2361.             while (pos)
  2362.             {
  2363.                 CSmilLayoutEvent* pEvent =
  2364.                     (CSmilLayoutEvent*) m_pEventList->GetNext(pos);
  2365.                 if (pEvent && pEvent->m_type == CSmilLayoutEvent::eAnimate)
  2366.                 {
  2367.                     // Cast this to an animate event
  2368.                     CSmilAnimateEvent* pAnim = (CSmilAnimateEvent*) pEvent;
  2369.                     // Create a copy
  2370.                     CSmilAnimateEvent* pNew = new CSmilAnimateEvent(*pAnim);
  2371.                     if (pNew)
  2372.                     {
  2373.                         // Add this to the temporary list
  2374.                         cTmp.AddTail((void*) pNew);
  2375.                     }
  2376.                 }
  2377.             }
  2378.         }
  2379. #endif
  2380.         // blow away current events
  2381.         // XXXMEH - 06/27/2001 Why do we want to do this? I'm going to 
  2382.         // comment this out now and simply do a *check* below to 
  2383.         // see if the show or hide time for the event changed. If
  2384.         // it didn't, then I'm going to leave the event alone.
  2385. #if defined(XXXMEH_OLD_UPDATE_SITE_EVENTS)
  2386.         removeGroupEvents(uGroupIndex);
  2387. #endif
  2388.         removeActiveTransitions();
  2389.         LISTPOSITION ptPos = m_pPlayToAssocList->GetHeadPosition();
  2390.         while (ptPos)
  2391.         {
  2392.             SMILPlayToAssoc* pPlayToAssoc = (SMILPlayToAssoc*) m_pPlayToAssocList->GetNext(ptPos);
  2393.             if (pPlayToAssoc &&
  2394.                 pPlayToAssoc->m_uGroupIndex == uGroupIndex &&
  2395.                 pPlayToAssoc->m_pSiteInfoList)
  2396.             {
  2397.                 LISTPOSITION siPos = pPlayToAssoc->m_pSiteInfoList->GetHeadPosition();
  2398.                 while (siPos)
  2399.                 {
  2400.                     SMILSiteInfo* pSiteInfo = (SMILSiteInfo*) pPlayToAssoc->m_pSiteInfoList->GetNext(siPos);
  2401.                     if (pSiteInfo)
  2402.                     {
  2403.                         IHXSite* pRegionSite = NULL;
  2404.                         CSmilBasicRegion* pRegion = getRegionByID(pSiteInfo->m_regionID);
  2405.                         if(pRegion)
  2406.                         {
  2407.                             pRegionSite = pRegion->m_pSite;
  2408.                         }
  2409.                         // Start time is delay
  2410.                         // End time is delay plus duration
  2411.                         UINT32 ulStartTime = pPlayToAssoc->m_ulDelay;
  2412.                         UINT32 ulEndTime   = pPlayToAssoc->m_ulDelay + pPlayToAssoc->m_ulDuration;
  2413.                         // Assign the playTo start and end times to the siteinfo
  2414.                         // delay and duration
  2415.                         pSiteInfo->m_ulDelay    = ulStartTime;
  2416.                         pSiteInfo->m_ulDuration = ulEndTime;
  2417.                         // Get the currently scheduled show event for this media
  2418.                         CSmilShowSiteEvent* pCurShowEvent = getShowHideEvent(pPlayToAssoc->m_id,
  2419.                                                                              pSiteInfo->m_regionID,
  2420.                                                                              TRUE);
  2421.                         if (pCurShowEvent)
  2422.                         {
  2423.                             // Is the currently scheduled show event time different
  2424.                             // from the current start time? If so, then we need to
  2425.                             // update the start time.
  2426.                             if (ulStartTime != pCurShowEvent->m_ulEventTime)
  2427.                             {
  2428. // /Note: we can get here when x in seq gets
  2429. // duration extended during playback & next-
  2430. // in-seq gets further delayed as a consequence.
  2431.                                 // First remove the event from the list
  2432.                                 removeEvent(pCurShowEvent);
  2433.                                 // Update the event time
  2434.                                 pCurShowEvent->m_ulEventTime = ulStartTime;
  2435.                                 // Add the event back in
  2436.                                 insertEvent(pCurShowEvent);
  2437.                             }
  2438.                         }
  2439.                         // Get the currently scheduled hide event for this media
  2440.                         CSmilShowSiteEvent* pCurHideEvent = getShowHideEvent(pPlayToAssoc->m_id,
  2441.                                                                              pSiteInfo->m_regionID,
  2442.                                                                              FALSE);
  2443.                         if (pCurHideEvent)
  2444.                         {
  2445.                             // Get the remove time for this media
  2446.                             UINT32 ulRemoveTime = 0;
  2447.                             HX_RESULT rv = m_pSmilParser->computeRemoveTime((const char*) pPlayToAssoc->m_id,
  2448.                                                                             ulRemoveTime);
  2449.                             if (FAILED(rv))
  2450.                             {
  2451.                                 // We couldn't currently compute the remove
  2452.                                 // time, so we set it way out, assuming it will
  2453.                                 // get pulled back later
  2454.                                 ulRemoveTime = WAY_IN_THE_FUTURE;
  2455.                             }
  2456.                             // Is the currently scheduled show event time different
  2457.                             // from the current start time? If so, then we need to
  2458.                             // update the start time.
  2459.                             if (ulRemoveTime != pCurHideEvent->m_ulEventTime)
  2460.                             {
  2461.                                 // First remove the event from the list
  2462.                                 removeEvent(pCurHideEvent);
  2463.                                 // Update the event time
  2464.                                 pCurHideEvent->m_ulEventTime = ulRemoveTime;
  2465.                                 // Get the this event's group duration
  2466.                                 UINT32 ulGroupDur = 0;
  2467.                                 if (getGroupDuration(pCurHideEvent->m_uGroupIndex, ulGroupDur))
  2468.                                 {
  2469.                                     // Get the fill behavior
  2470.                                     FillType eFill = getMediaFillBehavior((const char*) pCurHideEvent->getMediaID());
  2471.                                     // We got the group duration.
  2472.                                     // Is our new hide time scheduled for the
  2473.                                     // group duration?
  2474.                                     if (pCurHideEvent->m_ulEventTime == ulGroupDur &&
  2475.                                         eFill                        != FillRemove)
  2476.                                     {
  2477.                                         // Yes, it is, so set the flag that
  2478.                                         // says to ignore the hide
  2479.                                         pCurHideEvent->m_bIgnorEvent = TRUE;
  2480.                                     }
  2481.                                     else
  2482.                                     {
  2483.                                         // No, the hide is NOT scheduled for the group
  2484.                                         // duration, so clear the flag that
  2485.                                         // says to ignore the hide
  2486.                                         pCurHideEvent->m_bIgnorEvent = FALSE;
  2487.                                     }
  2488.                                 }
  2489.                                 // Add the event back in
  2490.                                 insertEvent(pCurHideEvent);
  2491.                                 // Set the event time into the element
  2492.                                 setElementRemoveTime(pPlayToAssoc->m_id, ulRemoveTime);
  2493.                             }
  2494.                         }
  2495. #if defined(HELIX_FEATURE_SMIL2_TRANSITIONS)
  2496.                         // Do we have a transIn?
  2497.                         if (pPlayToAssoc->m_beginTransition.GetLength() > 0)
  2498.                         {
  2499.                             CSmilTransitionInfo* pTransInfo = getTransition(pPlayToAssoc->m_beginTransition);
  2500.                             if (pTransInfo)
  2501.                             {
  2502.                                 if (pSiteInfo->m_ulDelay < m_ulCurrentTime)
  2503.                                 {
  2504.                                     CSmilTransitionEvent* pTransEvent =
  2505.                                         new CSmilTransitionEvent(pPlayToAssoc->m_ulDelay,
  2506.                                                                  pPlayToAssoc,
  2507.                                                                  pSiteInfo,
  2508.                                                                  TRUE,
  2509.                                                                  this);
  2510.                                     if (pTransEvent)
  2511.                                     {
  2512.                                         insertEvent(pTransEvent);
  2513.                                     }
  2514.                                 }
  2515.                                 else if (m_ulCurrentTime <
  2516.                                          pSiteInfo->m_ulDelay + pTransInfo->m_pTrans->m_ulDuration)
  2517.                                 {
  2518.                                     // don't schedule the transition... but build a state
  2519.                                     // and start the transition...
  2520.                                     startTransition(pSiteInfo->m_ulDelay,
  2521.                                                     pTransInfo,
  2522.                                                     pSiteInfo,
  2523.                                                     pPlayToAssoc,
  2524.                                                     NULL,
  2525.                                                     m_ulCurrentTime,
  2526.                                                     TRUE);
  2527.                                 }
  2528.                             }
  2529.                         }
  2530.                         // Do we have a transOut?
  2531.                         if (pPlayToAssoc->m_endTransition.GetLength() > 0)
  2532.                         {
  2533.                             CSmilTransitionInfo* pTransInfo = getTransition(pPlayToAssoc->m_endTransition);
  2534.                             if (pTransInfo)
  2535.                             {
  2536.                                 // if the end of the clip minus the duration of the 
  2537.                                 // transition is greater than the current time...
  2538.                                 if (pSiteInfo->m_ulDuration - pTransInfo->m_pTrans->m_ulDuration > m_ulCurrentTime)
  2539.                                 {
  2540.                                     HX_ASSERT(pSiteInfo->m_ulDelay + pSiteInfo->m_ulDuration < m_ulCurrentTime);
  2541.                                     // simply schedule a transition event to occur when the
  2542.                                     // current time reaches the end of the clip minus the 
  2543.                                     // duration of the transition.
  2544.                                     CSmilTransitionEvent* pTransEvent =
  2545.                                         new CSmilTransitionEvent(pSiteInfo->m_ulDuration -
  2546.                                                                  pTransInfo->m_pTrans->m_ulDuration,
  2547.                                                                  pPlayToAssoc,
  2548.                                                                  pSiteInfo,
  2549.                                                                  FALSE,
  2550.                                                                  this);
  2551.                                     if (pTransEvent)
  2552.                                     {
  2553.                                         insertEvent(pTransEvent);
  2554.                                     }
  2555.                                 }
  2556.                                 else if (pSiteInfo->m_ulDuration < m_ulCurrentTime)
  2557.                                 {
  2558.                                     startTransition(pSiteInfo->m_ulDelay +
  2559.                                                     pSiteInfo->m_ulDuration, 
  2560.                                                     pTransInfo,
  2561.                                                     pSiteInfo,
  2562.                                                     pPlayToAssoc,
  2563.                                                     NULL,
  2564.                                                     m_ulCurrentTime,
  2565.                                                     FALSE);
  2566.                                 }
  2567.                             }
  2568.                         }
  2569. #endif /* #if defined(HELIX_FEATURE_SMIL2_TRANSITIONS) */
  2570.                     } // if (pSiteInfo)
  2571.                 }
  2572.             }
  2573.         }
  2574. #if defined(XXXMEH_OLD_UPDATE_SITE_EVENTS)
  2575.         // Now add back in the animate events
  2576.         if (cTmp.GetCount() > 0)
  2577.         {
  2578.             LISTPOSITION pos = cTmp.GetHeadPosition();
  2579.             while (pos)
  2580.             {
  2581.                 CSmilAnimateEvent* pAnim = (CSmilAnimateEvent*) cTmp.GetNext(pos);
  2582.                 if (pAnim)
  2583.                 {
  2584.                     insertEvent(pAnim);
  2585.                 }
  2586.             }
  2587.             cTmp.RemoveAll();
  2588.         }
  2589. #endif
  2590.     }
  2591.     return rc;
  2592. }
  2593. #if defined(HELIX_FEATURE_SMIL2_TRANSITIONS)
  2594. HX_RESULT CSmilDocumentRenderer::checkSitesHideTime(SMILSiteInfo*        pOtherSiteInfo,
  2595.                                                     SMILSiteInfo*        pSiteInfo,
  2596.                                                     CSmilTransitionInfo* pTransInfo,
  2597.                                                     REF(IHXSite*)       pSiteToTransition,
  2598.                                                     BOOL                 bBeginTransition)
  2599. {
  2600.     HX_RESULT ret = HXR_OK;
  2601.     if (pOtherSiteInfo->m_pRegionSite   == pSiteInfo->m_pRegionSite &&
  2602.         pOtherSiteInfo->m_pRendererSite != pSiteInfo->m_pRendererSite)
  2603.     {
  2604.         pSiteToTransition = pSiteInfo->m_pRendererSite;
  2605.         if (bBeginTransition && pOtherSiteInfo->m_ulDuration == pSiteInfo->m_ulDelay)
  2606.         {
  2607.             // find the site with the closest but still lowest 
  2608.             // z-order that and the source must start when we end...
  2609.             // we need to move back the hide event for this site
  2610.             // by our the duration
  2611.             INT32 otherZOrder = getSiteZIndex(pOtherSiteInfo->m_pRendererSite);
  2612.             INT32 ourZOrder   = getSiteZIndex(pSiteInfo->m_pRendererSite);
  2613.             if (otherZOrder < ourZOrder)
  2614.             {
  2615.                 pSiteToTransition = pSiteInfo->m_pRendererSite;
  2616.                 // we want to transition from/to this site...
  2617.                 // -- move back its hide event... 
  2618.                 // (change the hide event to only hide the site too.)
  2619.                 ret = moveHideEventForSiteBack(pOtherSiteInfo, 
  2620.                     pOtherSiteInfo->m_ulDuration,
  2621.                     pTransInfo->m_pTrans->m_ulDuration, TRUE);
  2622.             }
  2623.         }
  2624.     }
  2625.     else if (bBeginTransition &&
  2626.              pOtherSiteInfo->m_ulDuration == pSiteInfo->m_ulDelay &&
  2627.              SitesOverlap(pOtherSiteInfo->m_pRegionSite, pSiteInfo->m_pRegionSite))
  2628.     {
  2629.         ret = moveHideEventForSiteBack(pOtherSiteInfo, 
  2630.             pOtherSiteInfo->m_ulDuration,
  2631.             pTransInfo->m_pTrans->m_ulDuration, FALSE);
  2632.     }
  2633.     return ret;
  2634. }
  2635. CSmilTransitionInfo* CSmilDocumentRenderer::getTransition(const char* pID)
  2636. {
  2637.     CSmilTransitionInfo* pTransition = NULL;
  2638.     if(m_pRegionMap)
  2639.     {
  2640. m_pTransitionMap->Lookup(pID, (void*&)pTransition);
  2641.     }
  2642.     return pTransition;
  2643. }
  2644. HX_RESULT CSmilDocumentRenderer::makeTransitionValues(CSmilTransitionInfo* pInfo,
  2645.                                                       BOOL                 bTransIn,
  2646.                                                       REF(IHXValues*)     rpValues)
  2647. {
  2648.     HX_RESULT retVal = HXR_OK;
  2649.     if (pInfo && pInfo->m_pTrans && m_pContext)
  2650.     {
  2651.         // Get an IHXCommonClassFactory interface
  2652.         IHXCommonClassFactory* pFact = NULL;
  2653.         retVal = m_pContext->QueryInterface(IID_IHXCommonClassFactory, (void**) &pFact);
  2654.         if (SUCCEEDED(retVal))
  2655.         {
  2656.             // Create an IHXValues
  2657.             HX_RELEASE(rpValues);
  2658.             retVal = pFact->CreateInstance(CLSID_IHXValues, (void**) &rpValues);
  2659.             if (SUCCEEDED(retVal))
  2660.             {
  2661.                 addStringProperty(rpValues, m_pContext, "type",
  2662.                                   (const char*) pInfo->m_pTrans->m_Type);
  2663.                 addStringProperty(rpValues, m_pContext, "subtype",
  2664.                                   (const char*) pInfo->m_pTrans->m_SubType);
  2665.                 addStringProperty(rpValues, m_pContext, "reverse",
  2666.                                   (pInfo->m_pTrans->m_eDirection == TransitionDirectionReverse ? "1" : "0"));
  2667.                 addStringProperty(rpValues, m_pContext, "TranIn",
  2668.                                   (bTransIn ? "1" : "0"));
  2669.                 char        szTmp[16]; /* Flawfinder: ignore */
  2670.                 const char* pszTmp = (const char*) &szTmp[0];
  2671.                 sprintf(szTmp, "%lu", pInfo->m_pTrans->m_ulVertRepeat); /* Flawfinder: ignore */
  2672.                 addStringProperty(rpValues, m_pContext, "VerticalRepeat",   pszTmp);
  2673.                 sprintf(szTmp, "%lu", pInfo->m_pTrans->m_ulHorzRepeat); /* Flawfinder: ignore */
  2674.                 addStringProperty(rpValues, m_pContext, "HorizontalRepeat", pszTmp);
  2675.                 sprintf(szTmp, "%lu", pInfo->m_pTrans->m_ulBorderWidth); /* Flawfinder: ignore */
  2676.                 addStringProperty(rpValues, m_pContext, "BorderWidth",      pszTmp);
  2677.                 sprintf(szTmp, "%lu", pInfo->m_pTrans->m_ulBorderColor); /* Flawfinder: ignore */
  2678.                 addStringProperty(rpValues, m_pContext, "BorderColor",      pszTmp);
  2679.                 addStringProperty(rpValues, m_pContext, "BlendBorder",
  2680.                                   (pInfo->m_pTrans->m_bBlendBorder ? "1" : "0"));
  2681.                 sprintf(szTmp, "%lu", pInfo->m_pTrans->m_ulFadeColor); /* Flawfinder: ignore */
  2682.                 addStringProperty(rpValues, m_pContext, "FadeColor",      pszTmp);
  2683.             }
  2684.         }
  2685.         HX_RELEASE(pFact);
  2686.     }
  2687.     else
  2688.     {
  2689.         retVal = HXR_FAIL;
  2690.     }
  2691.     return retVal;
  2692. }
  2693. HX_RESULT CSmilDocumentRenderer::startTransition(UINT32               ulStartTime,
  2694.                                                  CSmilTransitionInfo* pTransInfo,
  2695.                                                  SMILSiteInfo*        pSiteInfo,
  2696.                                                  SMILPlayToAssoc*     pAssoc,
  2697.                                                  IHXSite*            pSite,
  2698.                                                  UINT32               ulActualTime,
  2699.                                                  BOOL                 bBeginTransition)
  2700. {
  2701.     HX_RESULT retVal = HXR_OK;
  2702.     if (pTransInfo && pTransInfo->m_pTrans && pSiteInfo && pAssoc)
  2703.     {
  2704.         // Get our transition id
  2705.         CHXString cOurID;
  2706.         UINT32    ulOurDuration = pTransInfo->m_pTrans->m_ulDuration;
  2707.         if (pTransInfo->m_pTrans->m_pNode)
  2708.         {
  2709.             cOurID = pTransInfo->m_pTrans->m_pNode->m_id;
  2710.         }
  2711.         // Make sure the duration of the site is greater
  2712.         // than the duration of the transition
  2713.         if (pSiteInfo->m_ulDuration >= pTransInfo->m_pTrans->m_ulDuration)
  2714.         {
  2715.             // Get the site which will be doing the transition. If we are
  2716.             // not a coordinated transition, then we will do the transition
  2717.             // always on the renderer site. If we are a coordinated 
  2718.             // transition, then we will do the transition on the parent
  2719.             // region site.
  2720.             //
  2721.             // Initially we set the renderer site to be the site
  2722.             // we will transition on
  2723.             IHXSite* pSiteToTransition = pSiteInfo->m_pRendererSite;
  2724.             if (pSiteToTransition)
  2725.             {
  2726.                 // Create a SMILTransitionState struct
  2727.                 SMILTransitionState* pState = new SMILTransitionState;
  2728.                 if (pState)
  2729.                 {
  2730.                     // Null out the struct's memory
  2731.                     memset((void*) pState, 0, sizeof(SMILTransitionState));
  2732.                     // Init the values
  2733.                     pState->m_bBegin         = bBeginTransition;
  2734.                     pState->m_ulEndPercent   = (UINT32) (pTransInfo->m_pTrans->m_dEndProgress   * 1000.0);
  2735.                     pState->m_ulStartPercent = (UINT32) (pTransInfo->m_pTrans->m_dStartProgress * 1000.0);
  2736.                     pState->m_ulDuration     = pTransInfo->m_pTrans->m_ulDuration;
  2737.                     pState->m_ulEndTime      = ulStartTime + pTransInfo->m_pTrans->m_ulDuration;
  2738.                     pState->m_uGroupIndex    = pAssoc->m_uGroupIndex;
  2739.                     pState->m_id             = pTransInfo->m_pTrans->m_pNode->m_id;
  2740.                     // Now initialize the IHXSiteTransition interface
  2741.                     retVal = pSiteToTransition->QueryInterface(IID_IHXSiteTransition,
  2742.                                                                (void**) &pState->m_pSiteTransition);
  2743.                     if (SUCCEEDED(retVal))
  2744.                     {
  2745.                         IHXValues* pValues = NULL;
  2746.                         retVal = makeTransitionValues(pTransInfo, bBeginTransition, pValues);
  2747.                         if (SUCCEEDED(retVal))
  2748.                         {
  2749.                             MLOG_TRANS(m_pErrorMessages,
  2750.                                        "%lutIRMASiteTransition::Initialize(0x%08x) m_ulCurrentTime=%lun",
  2751.                                        HX_GET_BETTERTICKCOUNT(), m_ulCurrentTime);
  2752.                             retVal = pState->m_pSiteTransition->Initialize(pValues);
  2753.                             if (SUCCEEDED(retVal))
  2754.                             {
  2755.                                 if (!m_pActiveTransitions)
  2756.                                 {
  2757.                                     m_pActiveTransitions = new CHXSimpleList();
  2758.                                 }
  2759.                                 if (m_pActiveTransitions)
  2760.                                 {
  2761.                                     // Add to the list
  2762.                                     LISTPOSITION pos = m_pActiveTransitions->AddTail((void*) pState);
  2763.                                     // Do the transition the first time
  2764.                                     doTransition(pos, ulActualTime);
  2765.                                 }
  2766.                                 else
  2767.                                 {
  2768.                                     retVal = HXR_OUTOFMEMORY;
  2769.                                 }
  2770.                             }
  2771.                         }
  2772.                         HX_RELEASE(pValues);
  2773.                     }
  2774.                 }
  2775.                 else
  2776.                 {
  2777.                     retVal = HXR_OUTOFMEMORY;
  2778.                 }
  2779.             }
  2780.         }
  2781.     }
  2782.     else
  2783.     {
  2784.         HX_ASSERT(FALSE);
  2785.         retVal = HXR_FAIL;
  2786.     }
  2787.     return retVal;
  2788. }
  2789. #endif /* #if defined(HELIX_FEATURE_SMIL2_TRANSITIONS) */
  2790. BOOL CSmilDocumentRenderer::SitesOverlap(IHXSite* pCanidate, IHXSite* pSite)
  2791. {
  2792. /*          calculate if our region overlaps with this region.
  2793.             check to see if the site has a lower z-order, than our region.
  2794.             if these two tests pass and the region is visible:
  2795.                 search for a hide event on this current region & site,
  2796.                 pushing back the hide to the end of our duration if one is
  2797. found.
  2798. */
  2799.     BOOL bRet = FALSE;
  2800.     HXxPoint pntCan;
  2801.     HXxPoint pntSite;
  2802.     pCanidate->GetPosition(pntCan);
  2803.     pSite->GetPosition(pntSite);
  2804.     if (pntSite.x == pntCan.x &&
  2805. pntSite.y == pntCan.y)
  2806.     {
  2807. HXxSize sizeCan;
  2808. HXxSize sizeSite;
  2809. pCanidate->GetSize(sizeCan);
  2810. pCanidate->GetSize(sizeSite);
  2811. if (sizeCan.cx == sizeSite.cx &&
  2812.     sizeCan.cy == sizeSite.cy)
  2813. {
  2814.     // check to make sure canidate is behind us in the z-order.
  2815.             INT32 canZ  = getSiteZIndex(pCanidate);
  2816.             INT32 siteZ = getSiteZIndex(pSite);
  2817.             if (canZ < siteZ)
  2818.             {
  2819.                 bRet = TRUE;
  2820.             }
  2821. }
  2822.     }
  2823.     return bRet;
  2824. }
  2825. HX_RESULT
  2826. CSmilDocumentRenderer::moveHideEventForSiteBack(SMILSiteInfo* pInfo, UINT32 ulEndTime,
  2827. UINT32 len, 
  2828. BOOL bJustRenderer)
  2829. {
  2830.     LISTPOSITION lPos = NULL;
  2831.     if (m_ulEventListPosition)
  2832.     {
  2833. lPos = m_ulEventListPosition;
  2834.     }
  2835.     else
  2836.     {
  2837. lPos = m_pEventList->GetHeadPosition();
  2838.     }
  2839.     while (lPos)
  2840.     {
  2841. CSmilLayoutEvent* pThisEvent = (CSmilLayoutEvent*)
  2842.     m_pEventList->GetAt(lPos);
  2843. // we can consider all events because we are starting at
  2844. // the m_ulEventListPosition, therefore, we should start
  2845. // after all events have been executed...
  2846. // if Events are set to happen at the same time, Transitions
  2847. // always are at the top of the list, therefore we can catch
  2848. // hide events that are set to happen right after us, even
  2849. // though the current time is past the event time.
  2850. // pThisEvent->m_ulEventTime >= m_ulCurrentTime &&
  2851. if (pThisEvent->getRegionSite() == pInfo->m_pRegionSite &&
  2852.     pThisEvent->getRendererSite() == pInfo->m_pRendererSite &&
  2853.     pThisEvent->m_ulEventTime == ulEndTime)
  2854. {
  2855.     if (pThisEvent->m_type == CSmilLayoutEvent::eHideSite)
  2856.     {
  2857. m_pEventList->RemoveAt(lPos);
  2858. pThisEvent->m_ulEventTime += len;
  2859. pThisEvent->m_bOnlyHideSite = bJustRenderer;
  2860. LISTPOSITION pos = m_ulEventListPosition;
  2861. insertEvent(pThisEvent);
  2862. m_ulEventListPosition = pos;
  2863. break;
  2864.     }
  2865.     else if (pThisEvent->m_type == CSmilLayoutEvent::eShowSite)
  2866.     {
  2867. break;
  2868.     }
  2869. }
  2870. m_pEventList->GetNext(lPos);
  2871.     }
  2872.     return HXR_OK;
  2873. }
  2874. HX_RESULT 
  2875. CSmilDocumentRenderer::doTransition(LISTPOSITION pos, UINT32 ulTime)
  2876. {
  2877.     HX_RESULT ret = HXR_OK;
  2878.     if (m_pActiveTransitions)
  2879.     {
  2880. if (pos)
  2881. {
  2882.     SMILTransitionState* pState = (SMILTransitionState*)
  2883. m_pActiveTransitions->GetAt(pos);
  2884.     if (pState)
  2885.     {
  2886. INT32 percent = (((INT32)ulTime - (INT32)pState->m_ulEndTime 
  2887.     + (INT32)pState->m_ulDuration)*
  2888.     ((INT32)pState->m_ulEndPercent - (INT32)pState->m_ulStartPercent)/
  2889.     (INT32)pState->m_ulDuration) + (INT32)pState->m_ulStartPercent;
  2890. if (percent < (INT32)pState->m_ulStartPercent)
  2891. {
  2892.     percent = pState->m_ulStartPercent;
  2893. }
  2894. else if (percent > (INT32)pState->m_ulEndPercent)
  2895. {
  2896.     percent = pState->m_ulEndPercent;
  2897. }
  2898.                 MLOG_TRANS(m_pErrorMessages, "tIRMATransition::SetPercentage(%ld)n", percent);
  2899. pState->m_pSiteTransition->SetPercentage(percent);
  2900.     }
  2901.     else
  2902.     {
  2903. ret = HXR_FAIL;
  2904.     }
  2905. }
  2906.     }
  2907.     else
  2908.     {
  2909. ret = HXR_FAIL;
  2910.     }
  2911.     return ret;
  2912. }
  2913. HX_RESULT
  2914. CSmilDocumentRenderer::seekTo(const char* pElementID)
  2915. {
  2916.     HX_RESULT rc = HXR_OK;
  2917.     CSmilElement* pElement = m_pSmilParser->findElement(pElementID);
  2918.     if(pElement)
  2919.     {
  2920. HX_VECTOR_DELETE(m_pFragment);
  2921. m_pFragment = new_string(pElementID);
  2922. IHXPlayer* pPlayer = m_pParent->getPlayer();
  2923. IHXGroupManager* pMgr = 0;
  2924. if(HXR_OK == pPlayer->QueryInterface(IID_IHXGroupManager, (void**)&pMgr))
  2925. {
  2926.     UINT16 uFragmentGroup = m_pSmilParser->getFragmentGroup(m_pFragment);
  2927.     if(uFragmentGroup != m_uCurrentGroupIndex)
  2928.     {
  2929. m_bSettingFragment = TRUE;
  2930.      m_nFragmentTracks = 0;
  2931. pMgr->SetCurrentGroup(uFragmentGroup);
  2932.     }
  2933.     else
  2934.     {
  2935. BOOL bFragFoundAndResolved =TRUE;
  2936. UINT32 ulFragmentOffset = 
  2937.     m_pSmilParser->getFragmentOffset(m_pFragment,
  2938.     /* This is passed by reference: */
  2939.     bFragFoundAndResolved);
  2940. //If getFragmentOffset() failed to find the fragment or
  2941. // found it but it did not yet have a resolved begin time,