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

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: smltime.cpp,v 1.2.12.1 2004/07/09 01:57:38 hubbe Exp $
  3.  * 
  4.  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
  5.  * 
  6.  * The contents of this file, and the files included with this file,
  7.  * are subject to the current version of the RealNetworks Public
  8.  * Source License (the "RPSL") available at
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10.  * the file under the current version of the RealNetworks Community
  11.  * Source License (the "RCSL") available at
  12.  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
  13.  * will apply. You may also obtain the license terms directly from
  14.  * RealNetworks.  You may not use this file except in compliance with
  15.  * the RPSL or, if you have a valid RCSL with RealNetworks applicable
  16.  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
  17.  * the rights, obligations and limitations governing use of the
  18.  * contents of the file.
  19.  * 
  20.  * Alternatively, the contents of this file may be used under the
  21.  * terms of the GNU General Public License Version 2 or later (the
  22.  * "GPL") in which case the provisions of the GPL are applicable
  23.  * instead of those above. If you wish to allow use of your version of
  24.  * this file only under the terms of the GPL, and not to allow others
  25.  * to use your version of this file under the terms of either the RPSL
  26.  * or RCSL, indicate your decision by deleting the provisions above
  27.  * and replace them with the notice and other provisions required by
  28.  * the GPL. If you do not delete the provisions above, a recipient may
  29.  * use your version of this file under the terms of any one of the
  30.  * RPSL, the RCSL or the GPL.
  31.  * 
  32.  * This file is part of the Helix DNA Technology. RealNetworks is the
  33.  * developer of the Original Code and owns the copyrights in the
  34.  * portions it created.
  35.  * 
  36.  * This file, and the files included with this file, is distributed
  37.  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
  38.  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
  39.  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
  40.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
  41.  * ENJOYMENT OR NON-INFRINGEMENT.
  42.  * 
  43.  * Technology Compatibility Kit Test Suite(s) Location:
  44.  *    http://www.helixcommunity.org/content/tck
  45.  * 
  46.  * Contributor(s):
  47.  * 
  48.  * ***** END LICENSE BLOCK ***** */
  49. #include <stdlib.h>
  50. #include <stdio.h>
  51. #include <ctype.h>
  52. #include "hxtypes.h"
  53. #include "hxresult.h"
  54. #include "hxcom.h"
  55. #include "hxcomm.h"
  56. #include "ihxpckts.h"
  57. #include "hxfiles.h"
  58. #include "hxformt.h"
  59. #include "hxengin.h"
  60. #include "hxplugn.h"
  61. #include "hxpends.h"
  62. #include "hxasm.h"
  63. #include "hxprefs.h"
  64. #include "hxassert.h"
  65. #include "chxpckts.h"
  66. #include "nptime.h"
  67. #include "smpte.h"
  68. #include "debug.h"
  69. #include "hxstrutl.h"
  70. #include "hxstring.h"
  71. #include "cbqueue.h"
  72. #include "hxslist.h"
  73. #include "hxmap.h"
  74. #include "hxstack.h"
  75. #include "hxwintyp.h"
  76. #include "chxxtype.h"
  77. #include "hxxml.h"
  78. #include "hxxmlprs.h"
  79. #include "xmlreslt.h"
  80. #include "looseprs.h"
  81. #include "sm1elem.h"
  82. #include "sm1parse.h"
  83. #include "sm1time.h"
  84. /*
  85.  * CSmil1TimelineElementManager methods
  86.  */
  87. CSmil1TimelineElementManager::CSmil1TimelineElementManager():
  88.     m_pElementMap(NULL),
  89.     m_pNotifierMap(NULL)
  90. {
  91. }
  92. CSmil1TimelineElementManager::~CSmil1TimelineElementManager()
  93. {
  94.     HX_DELETE(m_pElementMap);
  95.     if(m_pNotifierMap)
  96.     {
  97. CHXMapStringToOb::Iterator i = m_pNotifierMap->Begin();
  98. for(; i != m_pNotifierMap->End(); ++i)
  99. {
  100.     CHXSimpleList* pList = (CHXSimpleList*)(*i);
  101.     delete pList;
  102. }
  103. HX_DELETE(m_pNotifierMap);
  104.     }
  105. }
  106. void
  107. CSmil1TimelineElementManager::addTimelineElement(CSmil1TimelineElement* pElement)
  108. {
  109.     if(!m_pElementMap)
  110.     {
  111. m_pElementMap = new CHXMapStringToOb;
  112.     }
  113.     (*m_pElementMap)[pElement->m_pID] = pElement;
  114. }
  115. CSmil1TimelineElement*
  116. CSmil1TimelineElementManager::getTimelineElement(const char* pID)
  117. {
  118.     CSmil1TimelineElement* pElement = NULL;
  119.     if(m_pElementMap)
  120.     {
  121. m_pElementMap->Lookup(pID, (void*&)pElement);
  122.     }
  123.     return pElement;
  124. }
  125. void
  126. CSmil1TimelineElementManager::addNotification(const char* pID,
  127.      CSmil1TimelineElement* pElement)
  128. {
  129.     if(!m_pNotifierMap)
  130.     {
  131. m_pNotifierMap = new CHXMapStringToOb;
  132.     }
  133.     CHXSimpleList* pNotifyList = NULL;
  134.     if(!m_pNotifierMap->Lookup(pID, (void*&)pNotifyList))
  135.     {
  136. pNotifyList = new CHXSimpleList;
  137. (*m_pNotifierMap)[pID] = pNotifyList;
  138.     }
  139.     pNotifyList->AddTail(pElement);
  140. }
  141. void
  142. CSmil1TimelineElementManager::notify(const char* pID)
  143. {
  144.     CHXSimpleList* pNotifyList = NULL;
  145.     if(m_pNotifierMap)
  146.     {
  147. if(m_pNotifierMap->Lookup(pID, (void*&)pNotifyList))
  148. {
  149.     CSmil1TimelineElement* pDependentElement = NULL;
  150.     if(m_pElementMap->Lookup(pID, (void*&)pDependentElement))
  151.     {
  152. CHXSimpleList::Iterator i = pNotifyList->Begin();
  153. for(; i != pNotifyList->End(); ++i)
  154. {
  155.     CSmil1TimelineElement* pElement = 
  156. (CSmil1TimelineElement*)(*i);
  157.     pElement->elementResolved(pDependentElement);
  158. }
  159.     }
  160. }
  161.     }
  162. }
  163. void
  164. CSmil1TimelineElementManager::resetTimeline()
  165. {
  166.     if(m_pElementMap)
  167.     {
  168. CHXMapStringToOb::Iterator i = m_pElementMap->Begin();
  169. for(; i != m_pElementMap->End(); ++i)
  170. {
  171.     CSmil1TimelineElement* pElement = 
  172. (CSmil1TimelineElement*)(*i);
  173.     pElement->reset();
  174. }
  175.     }
  176. }
  177. /*
  178.  * CSmil1TimelineElement methods
  179.  */
  180. CSmil1TimelineElement::CSmil1TimelineElement(CSmil1Element* pSourceElement,
  181.    CSmil1Parser* pParser):
  182.     m_pSourceElement(pSourceElement),
  183.     m_pParser(pParser),
  184.     m_bDurationSet(FALSE),
  185.     m_bMaxDurationSet(FALSE),
  186.     m_bDelaySet(FALSE),
  187.     m_bDontResetDuration(FALSE),
  188.     m_bNonEventDelaySet(FALSE),
  189.     m_bDelayEvent(FALSE),
  190.     m_bDurationEvent(FALSE),
  191.     m_pParent(NULL),
  192.     m_pChildren(NULL),
  193.     m_pDependent(NULL)
  194. {
  195.     m_pID = new char[pSourceElement->m_pNode->m_id.GetLength() + 1];
  196.     strcpy(m_pID, (const char*)m_pSourceElement->m_pNode->m_id); /* Flawfinder: ignore */
  197.     if (m_pParser && m_pParser->m_pTimelineElementManager)
  198.     {
  199.         m_pParser->m_pTimelineElementManager->addTimelineElement(this);
  200.         if(pSourceElement->m_nBeginEventSourceTag == SMILEventSourceBegin ||
  201.     pSourceElement->m_nBeginEventSourceTag == SMILEventSourceEnd ||
  202.     pSourceElement->m_nBeginEventSourceTag == SMILEventSourceClock)
  203.         {
  204.     m_pParser->m_pTimelineElementManager->addNotification(pSourceElement->m_BeginEventSourceID,
  205.         this);
  206.     m_bDelayEvent = TRUE;
  207.         }
  208.         if(pSourceElement->m_nEndEventSourceTag == SMILEventSourceBegin ||
  209.     pSourceElement->m_nEndEventSourceTag == SMILEventSourceEnd ||
  210.     pSourceElement->m_nEndEventSourceTag == SMILEventSourceClock)
  211.         {
  212.     m_pParser->m_pTimelineElementManager->addNotification(pSourceElement->m_EndEventSourceID,
  213.         this);
  214.     m_bDurationEvent = TRUE;
  215.         }
  216.         if(pSourceElement->m_nEndsyncEventSourceTag == SMILEventSourceID)
  217.         {
  218.     m_pParser->m_pTimelineElementManager->addNotification(pSourceElement->m_EndsyncEventSourceID,
  219.         this);
  220.     m_bDurationEvent = TRUE;
  221.         }
  222.     }
  223. }
  224. CSmil1TimelineElement::~CSmil1TimelineElement()
  225. {
  226.     delete m_pChildren;
  227.     delete[] m_pID;
  228. }
  229. void
  230. CSmil1TimelineElement::reset()
  231. {
  232.     m_bDelaySet = FALSE;
  233.     m_bNonEventDelaySet = FALSE;
  234.     m_bDurationSet = FALSE;
  235.     m_bMaxDurationSet = FALSE;
  236. }
  237. void 
  238. CSmil1TimelineElement::setDelay(UINT32 ulDelay)
  239. {
  240.     if(!m_bDelaySet)
  241.     {
  242. if(!m_bDelayEvent)
  243. {
  244.     if(m_pSourceElement->m_ulBeginOffset != (UINT32)-1)
  245.     {
  246. m_pSourceElement->m_ulDelay = ulDelay + 
  247.     m_pSourceElement->m_ulBeginOffset;
  248.     }
  249.     else
  250.     {
  251. m_pSourceElement->m_ulDelay = ulDelay;
  252.     }
  253.     m_bDelaySet = TRUE;
  254.     m_pParser->insertTimelineElement(m_pID, 
  255. m_pSourceElement->m_ulDelay);
  256. }
  257.     }
  258.     else
  259.     {
  260. if(m_pSourceElement->m_ulBeginOffset != (UINT32)-1)
  261. {
  262.     m_pSourceElement->m_ulDelay = ulDelay + 
  263. m_pSourceElement->m_ulBeginOffset;
  264. }
  265. else
  266. {
  267.     m_pSourceElement->m_ulDelay = ulDelay;
  268. }
  269.     }
  270. }
  271. void 
  272. CSmil1TimelineElement::setDuration(UINT32 ulDuration, BOOL bSetFromParent)
  273. {
  274.     if(bSetFromParent)
  275.     {
  276. m_pSourceElement->m_ulDuration = ulDuration;
  277. m_bDurationSet = m_bDontResetDuration = TRUE;
  278. m_pParser->resetTimelineElementDuration(m_pID,
  279.     m_pSourceElement->m_ulDuration);
  280.     }
  281.     else
  282.     {
  283. if(!m_bDurationSet)
  284. {
  285.     if(m_pSourceElement->m_ulBeginOffset != (UINT32)-1)
  286.     {
  287. m_pSourceElement->m_ulDuration = ulDuration + 
  288.     m_pSourceElement->m_ulBeginOffset;
  289.     }
  290.     else
  291.     {
  292. m_pSourceElement->m_ulDuration = ulDuration;
  293.     }
  294.     m_bDurationSet = TRUE;
  295.     if(m_pParent)
  296.     {
  297. m_pParent->addDuration(m_pSourceElement->m_ulDuration, 
  298.     m_pSourceElement->m_ulDelay, m_pID);
  299.     }
  300. }
  301. else if(!m_bDontResetDuration)
  302. {
  303.     m_pSourceElement->m_ulDuration = ulDuration;
  304.     m_pParser->resetTimelineElementDuration(m_pID,
  305. m_pSourceElement->m_ulDuration);
  306. }
  307.     }
  308.     if(m_pDependent)
  309.     {
  310. //Removed the addition of m_pSourceElement->m_ulDelay from the
  311. // source's duration because the source's duration already includes
  312. // its delay; we don't want to count the delay twice. Fixes PR 13983:
  313. // /*XXXEH- UNFIXES 13983 by adding back in the ...m_ulDelay addition;
  314. // the full fix for 13983 requires keeping track of begin=... delay
  315. // (as opposed to seq-related delay) and then subtracting that begin
  316. // delay from the m_ulDelay below:
  317. adjustDependentDuration(m_pDependent);
  318. m_pDependent->setDelay(m_pSourceElement->m_ulDelay + m_pSourceElement->m_ulDuration);
  319.     }
  320.     if (m_pParser && m_pParser->m_pTimelineElementManager)
  321.     {
  322.         m_pParser->m_pTimelineElementManager->notify(m_pID);
  323.     }
  324. }
  325. void
  326. CSmil1TimelineElement::setMaxDuration(UINT32 ulMaxDuration)
  327. {
  328.     m_bMaxDurationSet = TRUE;
  329.     m_pSourceElement->m_ulMaxDuration = ulMaxDuration;
  330. }
  331. void 
  332. CSmil1TimelineElement::adjustDependentDuration(CSmil1TimelineElement* pDependent)
  333. {
  334.     if (m_pParent)
  335.     {
  336. m_pParent->adjustDependentDuration(m_pDependent);
  337.     }
  338. }
  339. void
  340. CSmil1TimelineElement::elementResolved(CSmil1TimelineElement* pEventElement)
  341. {
  342.     //First, let's see if we have a begin event to resolve:
  343.     if(m_pSourceElement->m_nBeginEventSourceTag == SMILEventSourceBegin)
  344.     {
  345. if(pEventElement->m_bDelaySet)
  346. {
  347.     m_bDelaySet = TRUE;
  348.     m_pSourceElement->m_ulDelay = 
  349. pEventElement->m_pSourceElement->m_ulDelay;
  350.     m_pParser->insertTimelineElement(m_pID, 
  351. m_pSourceElement->m_ulDelay);
  352. }
  353.     }
  354.     else if(m_pSourceElement->m_nBeginEventSourceTag == SMILEventSourceEnd)
  355.     {
  356. if(pEventElement->m_bDurationSet)
  357. {
  358.     m_bDelaySet = TRUE;
  359.     m_pSourceElement->m_ulDelay = 
  360. pEventElement->m_pSourceElement->m_ulDuration +
  361.     pEventElement->m_pSourceElement->m_ulDelay;
  362.     m_pParser->insertTimelineElement(m_pID, 
  363. m_pSourceElement->m_ulDelay);
  364. }
  365.     }
  366.     else if(m_pSourceElement->m_nBeginEventSourceTag == SMILEventSourceClock)
  367.     {
  368. //We want event *BEGIN* plus clock therefor check for m_bDelaySet not
  369. // m_bDurationSet; after all, it's the eventElement's m_ulDelay
  370. // that's used, below:
  371. if(pEventElement->m_bDelaySet)
  372. {
  373.     m_bDelaySet = TRUE;
  374.     m_pSourceElement->m_ulDelay = 
  375.     pEventElement->m_pSourceElement->m_ulDelay;
  376.     //[SMIL 1.0 compliance] helps fix 23025:
  377.     // Rather than putting all the offset into m_ulDelay,
  378.     // we want to put the event element's delay into our
  379.     // delay and then put the event clock value into our
  380.     // m_ulBeginOffset so that we can properly adjust
  381.     // for any timing imposed on us later by our container
  382.     // (parent):
  383.     HX_ASSERT(m_pSourceElement->m_ulBeginOffset == UINT32(-1));
  384.     m_pSourceElement->m_ulBeginOffset =
  385.     m_pSourceElement->m_ulBeginEventClockValue;
  386.             m_pParser->insertTimelineElement(m_pID, 
  387. m_pSourceElement->m_ulDelay +
  388. //Allows SYMM 3/13/2000 test case 1.13 to work again
  389. // while allowing 23025 to keep working:
  390. m_pSourceElement->m_ulBeginOffset);
  391. }
  392.     }
  393.     //[SMIL 1.0 compliance] Fixes PR 16629:
  394.     //Next, let's see if we have an end event to resolve:
  395.     if(m_pSourceElement->m_nEndEventSourceTag == SMILEventSourceBegin)
  396.     {
  397. if(pEventElement->m_bDelaySet)
  398. {
  399.     m_bDurationSet = TRUE;
  400.     m_pSourceElement->m_ulDuration = 
  401. pEventElement->m_pSourceElement->m_ulDelay;
  402.     m_pParser->insertTimelineElement(m_pID, 
  403. m_pSourceElement->m_ulDelay);
  404. }
  405.     }
  406.     else if(m_pSourceElement->m_nEndEventSourceTag == SMILEventSourceEnd)
  407.     {
  408. if(pEventElement->m_bDurationSet)
  409. {
  410.     m_bDurationSet = TRUE;
  411.     m_pSourceElement->m_ulDuration = 
  412. pEventElement->m_pSourceElement->m_ulDuration +
  413.     pEventElement->m_pSourceElement->m_ulDelay;
  414.     m_pParser->insertTimelineElement(m_pID, 
  415. m_pSourceElement->m_ulDelay);
  416. }
  417.     }
  418.     //[SMIL 1.0 compliance] Fixes PR 16629; we need to set our duration
  419.     // to the event element's end time plus the clock offset:
  420.     else if(m_pSourceElement->m_nEndEventSourceTag == SMILEventSourceClock)
  421.     {
  422. if(pEventElement->m_bDelaySet)
  423. {
  424.     m_bDurationSet = TRUE;
  425.     m_pSourceElement->m_ulDuration = 
  426.     pEventElement->m_pSourceElement->m_ulDelay +
  427.     m_pSourceElement->m_ulEndEventClockValue;
  428.     m_pParser->insertTimelineElement(m_pID, 
  429. m_pSourceElement->m_ulDelay);
  430. }
  431.     }
  432. }
  433. #if 0
  434. void
  435. CSmil1TimelineElement::setEvent(SMILEventSourceTag eTag,
  436. SMILSyncAttributeTag aTag,
  437. const char* pEventSourceID,
  438. UINT32 ulEventClockValue)
  439. {
  440.     m_eEventSourceTag = eTag;
  441.     m_eSyncAttributeTag = aTag;
  442.     if(pEventSourceID)
  443.     {
  444. m_pEventSourceID = new char[strlen(pEventSourceID)+1];
  445. strcpy(m_pEventSourceID, pEventSourceID); /* Flawfinder: ignore */
  446.         if (m_pParser && m_pParser->m_pTimelineElementManager)
  447.         {
  448.             m_pParser->m_pTimelineElementManager->addNotification(pEventSourceID, this);
  449.         }
  450.     }
  451.     m_ulEventClockValue = ulEventClockValue;
  452. }
  453. #endif
  454. void 
  455. CSmil1TimelineElement::addChild(CSmil1TimelineElement* pChild)
  456. {
  457.     if(!m_pChildren)
  458.     {
  459. m_pChildren = new CHXSimpleList;
  460.     }
  461.     m_pChildren->AddTail(pChild);
  462.     pChild->setParent(this);
  463. }
  464. UINT32
  465. CSmil1TimelineElement::getDuration()
  466. {
  467.     return m_pSourceElement->m_ulDuration;
  468. }
  469. UINT32
  470. CSmil1TimelineElement::getDelay()
  471. {
  472.     return m_pSourceElement->m_ulDelay;
  473. }
  474. void 
  475. CSmil1TimelineElement::dump()
  476. {
  477. }
  478. /*
  479.  * CSmil1TimelinePar methods
  480.  */
  481. CSmil1TimelinePar::CSmil1TimelinePar(CSmil1Element* pSourceElement,
  482.    CSmil1Parser* pParser):
  483.     CSmil1TimelineElement(pSourceElement, pParser),
  484.     m_nDurationAdded(0),
  485.     m_ulFirstDuration(0),
  486.     m_ulLastDuration(0)
  487. {
  488. }
  489. CSmil1TimelinePar::~CSmil1TimelinePar()
  490. {
  491. }
  492. void 
  493. CSmil1TimelinePar::setDelay(UINT32 ulDelay)
  494. {
  495.     if(m_pSourceElement->m_ulBeginOffset != (UINT32)-1)
  496.     {
  497. m_pSourceElement->m_ulDelay = ulDelay + 
  498.     m_pSourceElement->m_ulBeginOffset;
  499.     }
  500.     else
  501.     {
  502. m_pSourceElement->m_ulDelay = ulDelay;
  503.     }
  504.     if (!m_bDelayEvent) //[SMIL 1.0 compliance] helps fix PR 14420.
  505.     {
  506. m_bDelaySet = TRUE;
  507. if(m_pChildren)
  508. {
  509.     CHXSimpleList::Iterator i = m_pChildren->Begin();
  510.     for(; i != m_pChildren->End(); ++i)
  511.     {
  512. CSmil1TimelineElement* pElement = (CSmil1TimelineElement*)(*i);
  513. pElement->setDelay(m_pSourceElement->m_ulDelay);
  514.     }
  515. }
  516. if (m_pSourceElement->m_ulDuration != (UINT32)-1)
  517. {
  518.     setDuration(m_pSourceElement->m_ulDuration);
  519. }
  520.     }
  521.     else //[SMIL 1.0 compliance] for PR 14420:
  522. // let's not claim that the delay is set when we still
  523. // are awaiting a delay (begin) event; we *do* need to
  524. // add the delay of this to the event's begin offset.
  525. // This is done by setting the new "m_bNonEventDelaySet"
  526. // variable to TRUE and leaving m_bDelaySet to FALSE
  527. // until the ElementResolved() call sets it to true:
  528.     {
  529. //Parent calls setDelay before we get to ElementResolved,
  530. // thus m_bDelaySet should never be TRUE if we have a
  531. // delay event:
  532. HX_ASSERT(!m_bDelaySet);
  533. m_bNonEventDelaySet = TRUE; //ElementResolved will look at this.
  534.     }
  535. }
  536. void
  537. CSmil1TimelinePar::setDuration(UINT32 ulDuration, BOOL bSetFromParent)
  538. {
  539.     m_pSourceElement->m_ulDuration = ulDuration;
  540.     m_bDurationSet = TRUE;
  541.     if(m_pChildren)
  542.     {
  543. CHXSimpleList::Iterator i = m_pChildren->Begin();
  544. for(; i != m_pChildren->End(); ++i)
  545. {
  546.     CSmil1TimelineElement* pElement = (CSmil1TimelineElement*)(*i);
  547.     pElement->setDuration(m_pSourceElement->m_ulDuration, TRUE);
  548.         }
  549.     }
  550.     
  551.     if(m_pDependent)
  552.     {
  553. adjustDependentDuration(m_pDependent);
  554. m_pDependent->setDelay(m_pSourceElement->m_ulDelay + m_pSourceElement->m_ulDuration);
  555.     }
  556.     //[SMIL 1.0 comliance] Helps fix PR 14420 and 23025:
  557.     if (m_pParser && m_pParser->m_pTimelineElementManager)
  558.     {
  559.         m_pParser->m_pTimelineElementManager->notify(m_pID);
  560.     }
  561. }
  562. void
  563. CSmil1TimelinePar::setMaxDuration(UINT32 ulMaxDuration)
  564. {
  565.     HX_ASSERT(m_pChildren);
  566.     m_bMaxDurationSet = TRUE;
  567.     m_pSourceElement->m_ulMaxDuration = ulMaxDuration;
  568.     if (m_pChildren)
  569.     {
  570. CHXSimpleList::Iterator i = m_pChildren->Begin();
  571. for(; i != m_pChildren->End(); ++i)
  572. {
  573.     CSmil1TimelineElement* pElement = (CSmil1TimelineElement*)(*i);
  574.     pElement->setMaxDuration(ulMaxDuration);
  575. }
  576.     }
  577. }
  578. void 
  579. CSmil1TimelinePar::adjustDependentDuration(CSmil1TimelineElement* pDependent)
  580. {
  581.     if (m_pParent)
  582.     {
  583. m_pParent->adjustDependentDuration(pDependent);
  584.     }
  585.     return;
  586. }
  587. void 
  588. CSmil1TimelinePar::addDuration(UINT32 ulDuration,
  589.       UINT32 ulDelay,
  590.       const char* pElementID)
  591. {
  592.     if(m_pSourceElement->m_ulDuration == (UINT32)-1)
  593.     {
  594. m_pSourceElement->m_ulDuration = ulDuration;
  595. m_ulFirstDuration = ulDuration;
  596. m_ulLastDuration = ulDuration;
  597.     }
  598.     else
  599.     {
  600. m_pSourceElement->m_ulDuration = 
  601.     (ulDuration > m_pSourceElement->m_ulDuration) ?
  602.     ulDuration : m_pSourceElement->m_ulDuration;
  603. if(ulDuration < m_ulFirstDuration)
  604. {
  605.     m_ulFirstDuration = ulDuration;
  606. }
  607. if(ulDuration > m_ulLastDuration)
  608. {
  609.     m_ulLastDuration = ulDuration;
  610. }
  611.     }
  612.     m_nDurationAdded++;
  613.     if(m_nDurationAdded == m_pChildren->GetCount() &&
  614. !m_bDurationEvent)
  615.     {
  616. if(m_pSourceElement->m_nEndsyncEventSourceTag == 
  617.     SMILEventSourceFirst)
  618. {
  619.     durationResolved(m_ulFirstDuration, TRUE);
  620. }
  621. else if(m_pSourceElement->m_nEndsyncEventSourceTag == 
  622.     SMILEventSourceLast)
  623. {
  624.     durationResolved(m_ulLastDuration, TRUE);
  625. }
  626. else
  627. {
  628.     durationResolved(m_pSourceElement->m_ulDuration, FALSE);
  629. }
  630.     }
  631. }
  632. void
  633. CSmil1TimelinePar::elementResolved(CSmil1TimelineElement* pEventElement)
  634. {
  635. //XXXEH: do we really want to check m_bDurationSet and m_bDelaySet...etc.
  636. // first???? (as in old version)
  637. //XXXEH: also, shouldn't we be making sure the pEventElement's id
  638. // matches the m_[XXX]EventSourceID?  Otherwise, a begin event on one id
  639. // and an end event on another may cause problems...
  640.     //First, let's see if we have a begin event to resolve:
  641.     if(m_pSourceElement->m_nBeginEventSourceTag == SMILEventSourceBegin)
  642.     {
  643. if(pEventElement->m_bDelaySet)
  644. {
  645.     //[SMIL 1.0 Compliance] Helps fix 14420:
  646.     if (m_bNonEventDelaySet)
  647.     {
  648. //Add non-event delay to begin event delay:
  649. m_pSourceElement->m_ulDelay += 
  650.     pEventElement->m_pSourceElement->m_ulDelay;
  651.     }
  652.     else
  653.     {
  654. //Just set delay to event delay:
  655. m_pSourceElement->m_ulDelay = 
  656.     pEventElement->m_pSourceElement->m_ulDelay;
  657.     }
  658.     m_bNonEventDelaySet = m_bDelaySet = TRUE;
  659.     if(m_pChildren)
  660.     {
  661. CHXSimpleList::Iterator i = m_pChildren->Begin();
  662. for(; i != m_pChildren->End(); ++i)
  663. {
  664.     CSmil1TimelineElement* pElement =
  665.     (CSmil1TimelineElement*)(*i);
  666.     pElement->setDelay(m_pSourceElement->m_ulDelay);
  667. }
  668.     }
  669. }
  670.     }
  671.     else if(m_pSourceElement->m_nBeginEventSourceTag == SMILEventSourceEnd)
  672.     {
  673. if(pEventElement->m_bDurationSet)
  674. {
  675.     //[SMIL 1.0 Compliance] Helps fix 14420:
  676.     if (m_bNonEventDelaySet)
  677.     {
  678. //Add non-event delay to begin event delay:
  679. m_pSourceElement->m_ulDelay += 
  680.     pEventElement->m_pSourceElement->m_ulDuration +
  681.     pEventElement->m_pSourceElement->m_ulDelay;
  682.     }
  683.     else
  684.     {
  685. //Just set delay to event delay:
  686. m_pSourceElement->m_ulDelay = 
  687.     pEventElement->m_pSourceElement->m_ulDuration +
  688.     pEventElement->m_pSourceElement->m_ulDelay;
  689.     }
  690.     m_bNonEventDelaySet = m_bDelaySet = TRUE;
  691.     if(m_pChildren)
  692.     {
  693. CHXSimpleList::Iterator i = m_pChildren->Begin();
  694. for(; i != m_pChildren->End(); ++i)
  695. {
  696.     CSmil1TimelineElement* pElement =
  697.     (CSmil1TimelineElement*)(*i);
  698.     pElement->setDelay(m_pSourceElement->m_ulDelay);
  699. }
  700.     }
  701. }
  702.     }
  703.     else if(m_pSourceElement->m_nBeginEventSourceTag == SMILEventSourceClock)
  704.     {
  705. //We want event *BEGIN* plus clock therefor check for m_bDelaySet not
  706. // m_bDurationSet; after all, it's the eventElement's m_ulDelay
  707. // that's used, below:
  708. if(pEventElement->m_bDelaySet)
  709. {
  710.     if (m_bNonEventDelaySet)
  711.     {
  712. //Add non-event delay to begin event delay + clock val:
  713. m_pSourceElement->m_ulDelay += 
  714.     pEventElement->m_pSourceElement->m_ulDelay +
  715.     m_pSourceElement->m_ulBeginEventClockValue;
  716.     }
  717.     else
  718.     {
  719. //Just set delay to event delay:
  720. m_pSourceElement->m_ulDelay = 
  721.     pEventElement->m_pSourceElement->m_ulDelay +
  722.     m_pSourceElement->m_ulBeginEventClockValue;
  723.     }
  724.     m_bNonEventDelaySet = m_bDelaySet = TRUE;
  725.     if(m_pChildren)
  726.     {
  727. CHXSimpleList::Iterator i = m_pChildren->Begin();
  728. for(; i != m_pChildren->End(); ++i)
  729. {
  730.     CSmil1TimelineElement* pElement =
  731.     (CSmil1TimelineElement*)(*i);
  732.     pElement->setDelay(m_pSourceElement->m_ulDelay);
  733. }
  734.     }
  735. }
  736.     }
  737.     
  738. //XXXEH: shouldn't we be making sure the pEventElement's id
  739. // matches the m_[XXX]EventSourceID, otherwise a begin event on one id
  740. // and an end event on another will cause problems.
  741. #if defined(XXXEH_UNTESTED_AND_NOT_EXAMINED_WELL)
  742.     if(m_pSourceElement->m_nEndEventSourceTag == SMILEventSourceBegin)
  743.     {
  744. if(pEventElement->m_bDelaySet)
  745. {
  746.     durationResolved(pEventElement->m_pSourceElement->m_ulDelay,
  747.     TRUE);
  748. }
  749.     }
  750.     else if(m_pSourceElement->m_nEndEventSourceTag == SMILEventSourceEnd)
  751.     {
  752. if(pEventElement->m_bDurationSet)
  753. {
  754.     durationResolved(pEventElement->getDuration(), TRUE);
  755. }
  756.     }
  757.     else if(m_pSourceElement->m_nEndEventSourceTag == SMILEventSourceClock)
  758.     {
  759. if(pEventElement->m_bDelaySet)
  760. {
  761.     durationResolved(pEventElement->m_pSourceElement->m_ulDelay +
  762.     m_pSourceElement->m_ulEndEventClockValue, TRUE);
  763. }
  764.     }
  765. #endif // defined(XXXEH_UNTESTED_AND_NOT_EXAMINED_WELL).
  766.     //[SMIL 1.0 compliance] Helps fix PR 32578:
  767.     if (m_pSourceElement->m_nEndsyncEventSourceTag == SMILEventSourceID)
  768.     {
  769. if(pEventElement->m_bDurationSet)
  770. {
  771.     durationResolved(pEventElement->getDuration(), TRUE);
  772. }
  773.     }
  774. }
  775. void
  776. CSmil1TimelinePar::durationResolved(UINT32 ulDuration, BOOL bUpdateChildren)
  777. {
  778.     if(!m_bDurationSet)
  779.     {
  780. m_bDurationSet = TRUE;
  781. m_pSourceElement->m_ulDuration = ulDuration;
  782. if(m_pParent)
  783. {
  784.     m_pParent->addDuration(ulDuration, 
  785. m_pSourceElement->m_ulDelay, m_pID);
  786. }
  787. if(m_pDependent)
  788. {
  789.     //XXXEH- should "m_pSourceElement->m_ulDelay +" be removed, too?
  790.     // I can't get any content to hit this line so I'm not going to
  791.     // change it.  See fix for PR SMIL/13983:
  792.     adjustDependentDuration(m_pDependent);
  793.     m_pDependent->setDelay(m_pSourceElement->m_ulDelay +
  794. m_pSourceElement->m_ulDuration);     
  795. }
  796. if(bUpdateChildren)
  797. {
  798.     CHXSimpleList::Iterator i = m_pChildren->Begin();
  799.     for(; i != m_pChildren->End(); ++i)
  800.     {
  801. CSmil1TimelineElement* pElement = (CSmil1TimelineElement*)(*i);
  802. pElement->setDuration(m_pSourceElement->m_ulDuration, TRUE);
  803.     }
  804. }
  805.     }
  806. }
  807. #if 0
  808. void 
  809. CSmil1TimelinePar::setEndsync(EndsyncType eType, 
  810.      const char* pEndsyncID,
  811.      UINT32 ulEndsyncClockValue)
  812. {
  813.     m_eEndsyncType = eType;
  814.     m_ulEndsyncClockValue = ulEndsyncClockValue;
  815.     if(pEndsyncID)
  816.     {
  817. m_pEndsyncID = new char[strlen(pEndsyncID)+1];
  818. strcpy(m_pEndsyncID, pEndsyncID); /* Flawfinder: ignore */
  819.     }
  820. }
  821. #endif
  822. /*
  823.  * CSmil1TimelineSeq methods
  824.  */
  825. CSmil1TimelineSeq::CSmil1TimelineSeq(CSmil1Element* pSourceElement,
  826.    CSmil1Parser* pParser):
  827.     CSmil1TimelineElement(pSourceElement, pParser),
  828.     m_nDurationAdded(0)
  829. {
  830. }
  831. void 
  832. CSmil1TimelineSeq::addDuration(UINT32 ulDuration, 
  833.       UINT32 ulDelay,
  834.       const char* pID)
  835. {
  836.     ASSERT(m_pChildren);
  837.     if(!m_bDurationSet)
  838.     {
  839. if(m_pSourceElement->m_ulDuration == (UINT32)-1)
  840. {
  841.     m_pSourceElement->m_ulDuration = ulDuration;
  842. }
  843. else
  844. {
  845.     m_pSourceElement->m_ulDuration += ulDuration;
  846. }
  847.     }
  848.     m_nDurationAdded++;
  849.     if(m_nDurationAdded == m_pChildren->GetCount())
  850.     {
  851. m_bDurationSet = TRUE;
  852. if(m_pParent)
  853. {
  854.     m_pParent->addDuration(
  855. m_pSourceElement->m_ulDuration, 
  856. m_pSourceElement->m_ulDelay, m_pID);
  857. }
  858. if(m_pDependent)
  859. {
  860.     //XXXEH- should "m_pSourceElement->m_ulDelay +" be removed, too?
  861.     // I can't get any content to hit this line so I'm not going to
  862.     // change it.  See fix for PR SMIL/13983:
  863.     adjustDependentDuration(m_pDependent);
  864.     m_pDependent->setDelay(m_pSourceElement->m_ulDelay +
  865. m_pSourceElement->m_ulDuration);     
  866. }
  867. // /[SMIL 1.0 Compliance] Fixes PR 23779:
  868. // if a source has event-based timing based on this seq's
  869. // duration, then we need to notify that source that we've
  870. // resolved this value:
  871.         if (m_pParser && m_pParser->m_pTimelineElementManager)
  872.         {
  873.             m_pParser->m_pTimelineElementManager->notify(m_pID);
  874.         }
  875.     }
  876. }
  877. void 
  878. CSmil1TimelineSeq::setDelay(UINT32 ulDelay)
  879. {
  880.     if(m_pSourceElement->m_ulBeginOffset != (UINT32)-1)
  881.     {
  882. m_pSourceElement->m_ulDelay = ulDelay + 
  883.     m_pSourceElement->m_ulBeginOffset;
  884.     }
  885.     else
  886.     {
  887. m_pSourceElement->m_ulDelay = ulDelay;
  888.     }
  889.     //XXXJHUG - we need to prevent overwriting the delay when
  890.     // setInitalDelay is called on THIS element, changing this
  891.     // bool causes initialDelaySet to return TRUE.
  892.     m_bDelaySet = TRUE;
  893.     if(m_pChildren && m_pChildren->GetCount() > 0)
  894.     {
  895. // set delay on first child of seq
  896. CSmil1TimelineElement* pElement = 
  897.     (CSmil1TimelineElement*)m_pChildren->GetHead();
  898. pElement->setDelay(m_pSourceElement->m_ulDelay);
  899.     }
  900.     if (m_pSourceElement->m_ulDuration != (UINT32)-1)
  901.     {
  902. setDuration(m_pSourceElement->m_ulDuration);
  903.     }
  904.     //[SMIL 1.0 Compliance] Helps fix PR 14420 and 23025:
  905.     // if a source has event-based timing based on this seq's
  906.     // begin time (delay) then we need to notify that source
  907.     // that we've resolved this value:
  908.     if (m_pParser && m_pParser->m_pTimelineElementManager)
  909.     {
  910.         m_pParser->m_pTimelineElementManager->notify(m_pID);
  911.     }
  912. }
  913. void
  914. CSmil1TimelineSeq::setDuration(UINT32 ulDuration, BOOL bSetFromParent)
  915. {
  916.     ASSERT(m_pChildren);
  917.     if(!m_bDurationSet)
  918.     {
  919. m_pSourceElement->m_ulDuration = ulDuration;
  920. m_bDurationSet = TRUE;
  921.     }
  922.     UINT32 ulDurationLeft = m_pSourceElement->m_ulDuration;
  923.     RepeatTag repeatTag = RepeatUnknown;
  924.     CHXSimpleList::Iterator i = m_pChildren->Begin();
  925.     for(; i != m_pChildren->End(); ++i)
  926.     {
  927. CSmil1TimelineElement* pElement = (CSmil1TimelineElement*)(*i);
  928. if (!setElementDuration(ulDurationLeft, pElement))
  929. {
  930.     break;
  931. }
  932.     }
  933.     if(m_pDependent)
  934.     {
  935. adjustDependentDuration(m_pDependent);
  936. m_pDependent->setDelay(m_pSourceElement->m_ulDelay + m_pSourceElement->m_ulDuration);
  937.     }
  938.     //[SMIL 1.0 comliance] Helps fix PR 14420 and 23025:
  939.     if (m_pParser && m_pParser->m_pTimelineElementManager)
  940.     {
  941.         m_pParser->m_pTimelineElementManager->notify(m_pID);
  942.     }
  943. }
  944. void
  945. CSmil1TimelineSeq::setMaxDuration(UINT32 ulMaxDuration)
  946. {
  947.     HX_ASSERT(m_pChildren);
  948.     m_bMaxDurationSet = TRUE;
  949.     m_pSourceElement->m_ulMaxDuration = ulMaxDuration;
  950.     if (m_pChildren)
  951.     {
  952. CSmil1TimelineElement* pElement = (CSmil1TimelineElement*)m_pChildren->GetHead();
  953. pElement->setMaxDuration(ulMaxDuration);
  954.     }
  955. }
  956. void 
  957. CSmil1TimelineSeq::adjustDependentDuration(CSmil1TimelineElement* pDependent)
  958. {
  959.     if(m_bDurationSet || m_bMaxDurationSet)
  960.     {
  961. UINT32     ulDurationLeft = m_bDurationSet?m_pSourceElement->m_ulDuration:
  962.     m_pSourceElement->m_ulMaxDuration;
  963. BOOL     bAdjusted = FALSE;
  964. RepeatTag   repeatTag = RepeatUnknown;
  965. CHXSimpleList::Iterator i = m_pChildren->Begin();
  966. for(; i != m_pChildren->End(); ++i)
  967. {
  968.     CSmil1TimelineElement* pElement = (CSmil1TimelineElement*)(*i);
  969.     UINT32 ulChildDuration = pElement->getDuration();
  970.     if (pElement == pDependent)
  971.     {
  972. bAdjusted = TRUE;
  973.     }
  974.     if (bAdjusted)
  975.     {
  976. if (!setElementDuration(ulDurationLeft, pElement))
  977. {
  978.     break;
  979. }
  980.     }
  981.     else
  982.     {
  983. if(ulDurationLeft >= ulChildDuration)
  984. {
  985.     ulDurationLeft -= ulChildDuration;
  986. }
  987. else
  988. {
  989.     ulDurationLeft = 0;
  990. }     
  991.     }
  992. }
  993. if (!bAdjusted && m_pParent)
  994. {
  995.     m_pParent->adjustDependentDuration(pDependent);
  996. }
  997.     }
  998. }
  999. BOOL
  1000. CSmil1TimelineSeq::setElementDuration(UINT32& ulDurationLeft, CSmil1TimelineElement* pElement)
  1001. {
  1002.     BOOL bContinue = TRUE;
  1003.     UINT32 ulChildDuration = pElement->getDuration();
  1004.     RepeatTag   repeatTag = pElement->m_pSourceElement->m_pNode->m_repeatTag;
  1005.     if (repeatTag == RepeatIndefiniteOnMe)
  1006.     {
  1007. pElement->setMaxDuration(ulDurationLeft);
  1008. ulDurationLeft = 0;
  1009. goto cleanup;
  1010.     }
  1011.     else if (repeatTag == RepeatIndefiniteOnGroup)
  1012.     {
  1013. pElement->setMaxDuration(ulDurationLeft);
  1014. bContinue = FALSE;
  1015. goto cleanup;
  1016.     }
  1017.     // no more duration left, take care of the duration of the rest of 
  1018.     // the elements
  1019.     if (0 == ulDurationLeft)
  1020.     {
  1021. pElement->setDuration(ulDurationLeft, TRUE);
  1022.     }
  1023.     // if this is the last child, then enforce the duration whatever
  1024.     // left
  1025.     else if (pElement == m_pChildren->GetTail())
  1026.     {
  1027. pElement->setDuration(ulDurationLeft, TRUE);
  1028. bContinue = FALSE;
  1029.     }
  1030.     // unknown duration, so we apply max. duration here
  1031.     else if (ulChildDuration == (UINT32)-1)
  1032.     {
  1033. pElement->setMaxDuration(ulDurationLeft);
  1034. bContinue = FALSE;
  1035.     }
  1036.     else
  1037.     {
  1038. if(ulDurationLeft >= ulChildDuration)
  1039. {
  1040.     ulDurationLeft -= ulChildDuration;
  1041. }
  1042. else
  1043. {
  1044.     pElement->setDuration(ulDurationLeft, TRUE);
  1045.     ulDurationLeft = 0;
  1046. }
  1047.     }
  1048. cleanup:
  1049.     return bContinue;
  1050. }
  1051. /*
  1052.  * CSmil1TimelineAnchor methods
  1053.  */
  1054. CSmil1TimelineAnchor::CSmil1TimelineAnchor(CSmil1Element* pSourceElement,
  1055.    CSmil1Parser* pParser):
  1056.     CSmil1TimelineElement(pSourceElement, pParser)
  1057.     , m_nDurationAdded(0)
  1058. {
  1059. }
  1060. CSmil1TimelineAnchor::~CSmil1TimelineAnchor()
  1061. {
  1062. }
  1063. void
  1064. CSmil1TimelineAnchor::elementResolved(CSmil1TimelineElement* pEventElement)
  1065. {
  1066. //XXXEH: shouldn't we be making sure the pEventElement's id
  1067. // matches the m_[XXX]EventSourceID?  Otherwise, a begin event on one id
  1068. // and an end event on another may cause problems...
  1069.     //First, let's see if we have a begin event to resolve:
  1070.     if(m_pSourceElement->m_nBeginEventSourceTag == SMILEventSourceBegin)
  1071.     {
  1072. if(pEventElement->m_bDelaySet)
  1073. {
  1074.     //[SMIL 1.0 Compliance] Helps fix 14420:
  1075.     if (m_bNonEventDelaySet)
  1076.     {
  1077. //Add non-event delay to begin event delay:
  1078. m_pSourceElement->m_ulDelay += 
  1079.     pEventElement->m_pSourceElement->m_ulDelay;
  1080.     }
  1081.     else
  1082.     {
  1083. //Just set delay to event delay:
  1084. m_pSourceElement->m_ulDelay = 
  1085.     pEventElement->m_pSourceElement->m_ulDelay;
  1086.     }
  1087.     m_bNonEventDelaySet = m_bDelaySet = TRUE;
  1088.     if(m_pChildren)
  1089.     {
  1090. CHXSimpleList::Iterator i = m_pChildren->Begin();
  1091. for(; i != m_pChildren->End(); ++i)
  1092. {
  1093.     CSmil1TimelineElement* pElement =
  1094.     (CSmil1TimelineElement*)(*i);
  1095.     pElement->setDelay(m_pSourceElement->m_ulDelay);
  1096. }
  1097.     }
  1098. }
  1099.     }
  1100.     else if(m_pSourceElement->m_nBeginEventSourceTag == SMILEventSourceEnd)
  1101.     {
  1102. if(pEventElement->m_bDurationSet)
  1103. {
  1104.     //[SMIL 1.0 Compliance] Helps fix 14420:
  1105.     if (m_bNonEventDelaySet)
  1106.     {
  1107. //Add non-event delay to begin event delay:
  1108. m_pSourceElement->m_ulDelay += 
  1109.     pEventElement->m_pSourceElement->m_ulDuration +
  1110.     pEventElement->m_pSourceElement->m_ulDelay;
  1111.     }
  1112.     else
  1113.     {
  1114. //Just set delay to event delay:
  1115. m_pSourceElement->m_ulDelay = 
  1116.     pEventElement->m_pSourceElement->m_ulDuration +
  1117.     pEventElement->m_pSourceElement->m_ulDelay;
  1118.     }
  1119.     m_bNonEventDelaySet = m_bDelaySet = TRUE;
  1120.     if(m_pChildren)
  1121.     {
  1122. CHXSimpleList::Iterator i = m_pChildren->Begin();
  1123. for(; i != m_pChildren->End(); ++i)
  1124. {
  1125.     CSmil1TimelineElement* pElement =
  1126.     (CSmil1TimelineElement*)(*i);
  1127.     pElement->setDelay(m_pSourceElement->m_ulDelay);
  1128. }
  1129.     }
  1130. }
  1131.     }
  1132.     else if(m_pSourceElement->m_nBeginEventSourceTag == SMILEventSourceClock)
  1133.     {
  1134. //We want event *BEGIN* plus clock therefor check for m_bDelaySet not
  1135. // m_bDurationSet; after all, it's the eventElement's m_ulDelay
  1136. // that's used, below:
  1137. if(pEventElement->m_bDelaySet)
  1138. {
  1139.     if (m_bNonEventDelaySet)
  1140.     {
  1141. //Add non-event delay to begin event delay + clock val:
  1142. m_pSourceElement->m_ulDelay += 
  1143.     pEventElement->m_pSourceElement->m_ulDelay +
  1144.     m_pSourceElement->m_ulBeginEventClockValue;
  1145.     }
  1146.     else
  1147.     {
  1148. //Just set delay to event delay:
  1149. m_pSourceElement->m_ulDelay = 
  1150.     pEventElement->m_pSourceElement->m_ulDelay +
  1151.     m_pSourceElement->m_ulBeginEventClockValue;
  1152.     }
  1153.     m_bNonEventDelaySet = m_bDelaySet = TRUE;
  1154.     if(m_pChildren)
  1155.     {
  1156. CHXSimpleList::Iterator i = m_pChildren->Begin();
  1157. for(; i != m_pChildren->End(); ++i)
  1158. {
  1159.     CSmil1TimelineElement* pElement =
  1160.     (CSmil1TimelineElement*)(*i);
  1161.     pElement->setDelay(m_pSourceElement->m_ulDelay);
  1162. }
  1163.     }
  1164. }
  1165.     }
  1166.     
  1167. //XXXEH: shouldn't we be making sure the pEventElement's id
  1168. // matches the m_[XXX]EventSourceID, otherwise a begin event on one id
  1169. // and an end event on another will cause problems.
  1170. #if defined(XXXEH_UNTESTED_AND_NOT_EXAMINED_WELL)
  1171.     if(m_pSourceElement->m_nEndEventSourceTag == SMILEventSourceBegin)
  1172.     {
  1173. if(pEventElement->m_bDelaySet)
  1174. {
  1175.     durationResolved(pEventElement->m_pSourceElement->m_ulDelay);
  1176. }
  1177.     }
  1178.     else if(m_pSourceElement->m_nEndEventSourceTag == SMILEventSourceEnd)
  1179.     {
  1180. if(pEventElement->m_bDurationSet)
  1181. {
  1182.     durationResolved(pEventElement->getDuration());
  1183. }
  1184.     }
  1185.     else if(m_pSourceElement->m_nEndEventSourceTag == SMILEventSourceClock)
  1186.     {
  1187. if(pEventElement->m_bDelaySet)
  1188. {
  1189.     durationResolved(pEventElement->m_pSourceElement->m_ulDelay +
  1190.     m_pSourceElement->m_ulEndEventClockValue);
  1191. }
  1192.     }
  1193. #endif // defined(XXXEH_UNTESTED_AND_NOT_EXAMINED_WELL).
  1194. }
  1195. void
  1196. CSmil1TimelineAnchor::durationResolved(UINT32 ulDuration)
  1197. {
  1198.     if(!m_bDurationSet)
  1199.     {
  1200. m_bDurationSet = TRUE;
  1201. m_pSourceElement->m_ulDuration = ulDuration;
  1202.     }
  1203. }