smldoc.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:673k
- /* ***** BEGIN LICENSE BLOCK *****
- * Source last modified: $Id: smldoc.cpp,v 1.10.4.8 2004/07/13 22:46:02 ehodge Exp $
- *
- * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
- *
- * The contents of this file, and the files included with this file,
- * are subject to the current version of the RealNetworks Public
- * Source License (the "RPSL") available at
- * http://www.helixcommunity.org/content/rpsl unless you have licensed
- * the file under the current version of the RealNetworks Community
- * Source License (the "RCSL") available at
- * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
- * will apply. You may also obtain the license terms directly from
- * RealNetworks. You may not use this file except in compliance with
- * the RPSL or, if you have a valid RCSL with RealNetworks applicable
- * to this file, the RCSL. Please see the applicable RPSL or RCSL for
- * the rights, obligations and limitations governing use of the
- * contents of the file.
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL") in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your version of
- * this file only under the terms of the GPL, and not to allow others
- * to use your version of this file under the terms of either the RPSL
- * or RCSL, indicate your decision by deleting the provisions above
- * and replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient may
- * use your version of this file under the terms of any one of the
- * RPSL, the RCSL or the GPL.
- *
- * This file is part of the Helix DNA Technology. RealNetworks is the
- * developer of the Original Code and owns the copyrights in the
- * portions it created.
- *
- * This file, and the files included with this file, is distributed
- * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
- * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
- * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
- * ENJOYMENT OR NON-INFRINGEMENT.
- *
- * Technology Compatibility Kit Test Suite(s) Location:
- * http://www.helixcommunity.org/content/tck
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
- // system
- #include <time.h>
- #include <math.h>
- #include <ctype.h> /* for isspace() */
- #if defined(_UNIX) && (!(defined(_BEOS))) && defined(USE_XWINDOWS)
- #include <X11/Xlib.h>
- #include <X11/Xutil.h>
- #endif
- // include
- #include "hxtypes.h"
- #include "hxwintyp.h"
- #include "hxcom.h"
- #include "smiltype.h"
- #include "hxcomm.h"
- #include "ihxpckts.h"
- #include "hxprefs.h"
- #include "hxplugn.h"
- #include "hxcore.h"
- #include "hxwin.h"
- #include "hxsite2.h"
- #include "hxrendr.h"
- #include "hxgroup.h"
- #include "hxevent.h"
- #include "hxvsurf.h"
- #include "hxhyper.h"
- #include "hxxml.h"
- #include "hxvport.h"
- #include "hxfiles.h"
- #include "hxausvc.h"
- #include "hxclsnk.h"
- #if !defined(XXXEH_NEED_TO_ADD_51_PRCNT_OPAQUE_SITE_ON_TOP_TO_DISABLE)
- #include "hxvctrl.h"
- #endif
- #include "hxmmrkr.h"
- #include "hxinter.h"
- #include "hxupgrd.h"
- #include "hxsm2sm.h"
- #include "hxerror.h"
- // pncont
- #include "hxslist.h"
- #include "chxpckts.h"
- #include "hxstring.h"
- #include "hxmap.h"
- #include "hxordval.h"
- #include "hxstack.h"
- #include "rtsputil.h"
- // pnmisc
- #include "hxurl.h"
- #include "hxstrutl.h"
- #include "hxwinver.h"
- #include "hxtick.h"
- #include "dllpath.h"
- // rnxmllib
- #include "hxxmlprs.h"
- // coreres
- #include "smilres.h"
- // pxcomlib
- #include "buffutil.h"
- // rmasmil
- #include "smlelem.h"
- #include "smlparse.h"
- #include "smlprstime.h"
- #include "smlerror.h"
- #include "smlutil.h"
- // smlrendr
- #include "smlrendr.h"
- #include "smlrtype.h"
- #include "animattr.h"
- #include "animsand.h"
- #include "evnthook.h"
- #include "siteuser.h"
- #include "sitewatc.h"
- #include "layout.h"
- #include "passivsw.h"
- #include "layevent.h"
- #include "smcallbk.h"
- #include "xdata.h"
- #include "smldoc.h"
- #if defined(_WINDOWS)
- #include "hxalloc.h"
- #define IDC_HANDCURSOR 102
- #elif defined (_MACINTOSH)
- #include "hxmm.h"
- #include "cresload.h"
- extern FSSpec g_DLLFSpec;
- #endif
- #if defined(_UNIX) && (!(defined(_BEOS))) && defined(USE_XWINDOWS)
- #include <X11/Xlib.h>
- #include <X11/Xutil.h>
- #include <X11/cursorfont.h>
- /* USE_SHM doesn't work yet */
- #ifdef USE_SHM
- #undef USE_SHM
- #endif /* USE_SHM */
- #endif
- // pndebug
- #include "errdbg.h"
- #include "debugout.h"
- #include "smlrmlog.h"
- #include "hxheap.h"
- #ifdef _DEBUG
- #undef HX_THIS_FILE
- static const char HX_THIS_FILE[] = __FILE__;
- #endif
- #ifdef _WINDOWS
- extern HINSTANCE g_hInstance;
- #endif
- // /This got removed, accidentally, by huge optimization HEAD check-in on
- // 11/7/2001, causing show="new" and target="[someLPP]" (launching of LPP)
- // to stop working. Putting this back in fixes PR 69905:
- #define XXXEH_USE_OPENWINDOW_METHOD
- #define HANDLE_DISCRETE_MEDIA_IN_TrackDurationSet 1
- // /XXXEH- talk to core devs; we need them to be able to
- // deal with an added track that all of a sudden has its
- // duration changed to zero; this seems to work fine for
- // tracks that have a zero delay, but subsequent ones
- // hang the system when their durations are set to zero:
- #define XXXEH_WAITING_FOR_PLAYER_CORE_FIX_FOR_RESETTING_DUR_TO_ZERO
- #if defined(XXXEH_WAITING_FOR_PLAYER_CORE_FIX_FOR_RESETTING_DUR_TO_ZERO)
- #define ZERO_DUR 1 /* 1 millisecond to trick core. */
- #else
- #define ZERO_DUR 0
- #endif
- // /For case where destinationLevel < 10 on a new player and we need to set
- // the shared-by-all-players volume to accomodate this, we need to limit it
- // for now so source player's volume doesn't cut out:
- #define XXXEH_MIN_DEST_AUDIOPLAYER_VOL 10
- // /Clamp track soundLevel at some arbitrary, high value; MEH chose 1000% (10x)
- // for max-allowed animation of soundLevel; use 1000 until someone complains
- // and then ask them what would be better:
- #define MAX_ALLOWED_SOUNDLEVEL 1000.0
- // /#define XXXEH_DEBUG_HANDLESOURCE_AND_TRACKDURATIONSET
- // /#define XXXEH_DEBUGOUT_TRACKSTOPPAUSERESUME
- // /#define XXXEH_DEBUGOUT_RESOLVEGROUPDUR
- /*
- * CSmilDocumentRenderer methods
- */
- CSmilDocumentRenderer::CSmilDocumentRenderer(
- CSmilRenderer* pParent, IUnknown* pContext):
- m_pParent(pParent),
- m_pSmilParser(0),
- m_ulParseResult(HXR_OK),
- m_lRefCount(0),
- m_pRegionMap(0),
- m_pRootLayout(NULL),
- m_pViewportList(NULL),
- m_pRegPointMap(NULL),
- #if defined(HELIX_FEATURE_SMIL2_TRANSITIONS)
- m_pTransitionMap(0),
- #endif /* #if defined(HELIX_FEATURE_SMIL2_TRANSITIONS) */
- m_pSiteInfoByRendererMap(0),
- m_pSiteWatcherMap(0),
- m_pGroupInfoMap(0),
- m_pGroupMap(0),
- m_pDeferredSourceMap(0),
- m_pDeferrededRemoveTrackMap(NULL),
- m_bInTrackDurationSetCall(FALSE),
- m_bEventSinkWasSetup(FALSE),
- m_pPausedAndDisabledIDMap(NULL),
- m_pPausedAndDisabledBrightnessMap(NULL),
- m_pPrefetchTrackElementMap(0),
- m_pSiteInfoList(0),
- m_uCurrentGroupIndex(-1),
- m_pPlayToAssocList(0),
- m_pZOrderList(0),
- m_pSiteMgr(0),
- m_pScheduler(0),
- m_pEventList(0),
- m_pFragment(0),
- m_ulCurrentTime(0),
- m_ulEventListPosition(0),
- m_bFirstTimeSync(FALSE),
- m_bSettingFragment(FALSE),
- m_bFragFoundAndResolved(FALSE),
- m_ulFragmentTimeOffset(0),
- m_bInHyperlink(FALSE),
- m_pStatusMessage(0),
- m_bStatusMessageSet(FALSE),
- m_bMetadataPassedOffAlready(FALSE),
- m_pPersistentLayoutStream(NULL),
- m_bIsRootLayoutSetup(FALSE),
- m_ulNoLayoutRendererCount(0),
- m_pErrorMessages(NULL),
- m_bDestPlaystateIsPause(FALSE),
- #ifdef _WINDOWS
- m_hPreHyperlinkCursor(0),
- m_hHyperlinkCursor(0),
- m_bNeedToSetHyperlinkCursor(FALSE),
- #endif
- #ifdef _MACINTOSH
- m_hHyperlinkCursor(0),
- m_bResetCursor(FALSE),
- #endif
- #if defined(_UNIX) && (!(defined(_BEOS))) && defined(USE_XWINDOWS)
- m_hHyperlinkCursor(0),
- m_hCurrentCursor(0),
- m_pDisplay(0),
- m_Window(0),
- m_pPixmapDisplay(NULL),
- m_pVisualInfo(NULL),
- #endif
- m_bSiteLayoutComplete(FALSE),
- m_nFragmentTracks(0),
- m_dResizeXScale(1.0),
- m_dResizeYScale(1.0),
- m_pActiveTransitions(NULL),
- m_pActiveAnimations(NULL),
- m_pRegionMapIterator(NULL),
- m_pAnimationMap(NULL),
- m_pDelayedRendererCloseList(NULL),
- m_bSMILPresentationHasEnded(FALSE),
- m_pSMILDefaultNamespaceStr(NULL),
- m_pViewPortManager(NULL)
- #ifdef XXXMEH_DO_VIEWPORT_TLC
- ,m_pViewPortSiteMap(NULL)
- ,m_bSMILViewportClose(FALSE)
- #endif
- , m_pPlayerResumeStack(NULL)
- #if defined(BE_SITE_SUPPLIER_20010205)
- , m_pIndependentPlayer(NULL)
- , m_pChildSiteInfoMap(NULL)
- #endif /* BE_SITE_SUPPLIER_20010205 */
- , m_ulGroupIndex(0)
- , m_ulTrackIndex(0)
- , m_uGroupIndexWithin(0)
- , m_bSitesDetached(FALSE)
- , m_ulPersistentComponentID(0)
- , m_uPersistentGroupID(0)
- , m_uPersistentTrackID(0)
- , m_pPersistentProperties(NULL)
- , m_pPersistentParentRenderer(NULL)
- , m_pExternalMediaMarkerList(NULL)
- , m_bLayoutElementPresent(FALSE)
- , m_bEmptyLayout(FALSE)
- , m_bDoNotZoom(FALSE)
- , m_AnimationIterator(NULL)
- , m_pAnimSiteRedrawMap(NULL)
- , m_pAnimRegionRecomputeMap(NULL)
- , m_bAnimateRootLayout(FALSE)
- , m_pAnimTopLayoutMap(NULL)
- , m_usAnimBaseGroupIndex(0)
- , m_ulAnimDuration(0)
- , m_ulCurGroupDuration(0)
- , m_pSoundLevelMutex(NULL)
- , m_bCloseCalled(FALSE)
- , m_bRootLayoutSiteDetached(FALSE)
- , m_pHandlePendingSchedulingCallback(NULL)
- , m_pHyperlinkCallback(NULL)
- , m_pMediaID2RendererMap(NULL)
- , m_pMediaID2RendererSiteMap(NULL)
- , m_pMediaID2RendererSiteWatcherMap(NULL)
- , m_pEventSinkList(NULL)
- , m_ulPktnum(0)
- , m_usOldXPos(0)
- , m_usOldYPos(0)
- {
- m_pContext = pContext;
- HX_ASSERT(m_pContext);
- if(m_pContext)
- {
- m_pContext->AddRef();
-
- HX_VERIFY(HXR_OK == m_pContext->
- QueryInterface(IID_IHXSiteManager,(void**)&m_pSiteMgr));
-
- HX_VERIFY(HXR_OK == m_pContext->
- QueryInterface(IID_IHXScheduler, (void**)&m_pScheduler));
-
- if (HXR_OK != m_pContext->QueryInterface(IID_IHXStatusMessage,
- (void**)&m_pStatusMessage))
- {
- // not an error, just a feature waiting to happen...
- m_pStatusMessage = NULL;
- }
- #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT)
- // QI for IHXViewPortManager
- m_pContext->QueryInterface(IID_IHXViewPortManager,
- (void**) &m_pViewPortManager);
- if (m_pViewPortManager)
- {
- // Add ourselves as a view port sink
- IHXViewPortSink* pSink = NULL;
- QueryInterface(IID_IHXViewPortSink, (void**) &pSink);
- if (pSink)
- {
- m_pViewPortManager->AddViewPortSink(pSink);
- }
- HX_RELEASE(pSink);
- }
- #endif /* #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT) */
- // Add ourselves as a media marker sink
- // TRUE adds us, FALSE removes us
- addRemoveMediaMarkerSink(TRUE);
- // Add ourselves as an error sink
- addRemoveErrorSink(TRUE);
- // QI for IHXErrorMessages - ok if not implemented
- m_pContext->QueryInterface(IID_IHXErrorMessages,
- (void**) &m_pErrorMessages);
- }
- #ifdef _WINDOWS
- m_hHyperlinkCursor = LoadCursor(g_hInstance,
- MAKEINTRESOURCE(IDC_HANDCURSOR));
- #endif
- #ifdef _MACINTOSH
- const short HAND_CURSOR = 1313;
- m_pResourceLoader = CResourceLoader::CreateInstance(g_DLLFSpec);
- m_hHyperlinkCursor = (CursHandle)m_pResourceLoader->LoadResource('CURS', HAND_CURSOR);
- #endif
-
- #ifdef _DEBUG
- BOOL bShowDependencies = FALSE;
- ::getBooleanPreference(m_pContext,
- "showdependencies",
- bShowDependencies);
- if(bShowDependencies)
- {
- // mark file boundary
- #ifdef _WINDOWS
- const char* pszDepFile = "\smildep.txt";
- #else
- const char* pszDepFile = "smildep.txt";
- #endif
- FILE* fp = fopen(pszDepFile, "a");
- if(fp)
- {
- fprintf(fp, "===========================n");
- fclose(fp);
- }
- }
- #endif
- }
- CSmilDocumentRenderer::~CSmilDocumentRenderer()
- {
- HX_RELEASE(m_pSiteMgr);
- HX_DELETE(m_pRootLayout);
- #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT)
- closeViewports();
- removeViewports();
- HX_DELETE(m_pViewportList);
- HX_RELEASE(m_pViewPortManager);
- #ifdef XXXMEH_DO_VIEWPORT_TLC
- clearViewportMap();
- #endif
- #endif /* #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT) */
- HX_DELETE(m_pRegPointMap);
- HX_RELEASE(m_pPersistentLayoutStream);
- HX_RELEASE(m_pErrorMessages);
- #if defined(HELIX_FEATURE_SMIL2_ANIMATION)
- removeActiveAnimations();
- #endif /* #if defined(HELIX_FEATURE_SMIL2_ANIMATION) */
- HX_DELETE(m_pActiveAnimations);
- HX_DELETE(m_pAnimationMap);
- HX_DELETE(m_pAnimSiteRedrawMap);
- HX_DELETE(m_pAnimRegionRecomputeMap);
- HX_DELETE(m_pAnimTopLayoutMap);
- deleteExternalMediaMarkerList();
- HX_RELEASE(m_pSMILDefaultNamespaceStr);
- if (m_pPrefetchTrackElementMap)
- {
- CHXMapLongToObj::Iterator i;
- for (i = m_pPrefetchTrackElementMap->Begin();
- i != m_pPrefetchTrackElementMap->End(); ++i)
- {
- CHXString* pId = (CHXString*)(*i);
- HX_DELETE(pId);
- }
- HX_DELETE(m_pPrefetchTrackElementMap);
- }
- if (m_pIndependentPlayer)
- {
- HX_DELETE(m_pIndependentPlayer);
- }
- if (m_pChildSiteInfoMap)
- {
- HX_ASSERT(m_pChildSiteInfoMap->IsEmpty()); // /Should be empty!...
- // ...but in case it's not empty, go ahead and delete its nodes:
- CHXMapLongToObj::Iterator i = m_pChildSiteInfoMap->Begin();
- for(; i != m_pChildSiteInfoMap->End(); ++i)
- {
- SMILChildSiteInfo* pChildSiteInfo = (SMILChildSiteInfo*)(*i);
- delete pChildSiteInfo;
- }
- HX_DELETE(m_pChildSiteInfoMap);
- }
- #if defined(_UNIX) && (!(defined(_BEOS))) && defined(USE_XWINDOWS)
- CHXMapPtrToPtr::Iterator i = m_siteToXDataMap.Begin();
- for(; i != m_siteToXDataMap.End(); ++i)
- {
- XData* xData = (XData*)(*i);
- delete xData;
- }
- if (m_pVisualInfo)
- {
- XFree(m_pVisualInfo);
- m_pVisualInfo = NULL;
- }
- if (m_pDisplay && m_hHyperlinkCursor)
- {
- XFreeCursor(m_pDisplay, m_hHyperlinkCursor);
- m_hHyperlinkCursor = 0;
- }
- #endif
- #if defined(_MACINTOSH)
- if (m_hHyperlinkCursor)
- {
- m_pResourceLoader->UnloadResource((Handle)m_hHyperlinkCursor);
- m_hHyperlinkCursor = NULL;
-
- HX_RELEASE(m_pResourceLoader);
- }
- if (m_bResetCursor)
- {
- ::InitCursor();
- }
- #endif
- HX_RELEASE(m_pSoundLevelMutex);
- clearRendererMap();
- HX_DELETE(m_pMediaID2RendererMap);
- clearRendererSiteMap();
- HX_DELETE(m_pMediaID2RendererSiteMap);
- clearRendererSiteWatcherMap();
- HX_DELETE(m_pMediaID2RendererSiteWatcherMap);
- destroyAllRegions();
- CleanUpSiteInfoContainers();
- HX_DELETE(m_pSiteWatcherMap);
- }
- /*
- * IUnknown methods
- */
- STDMETHODIMP
- CSmilDocumentRenderer::QueryInterface(REFIID riid, void** ppvObj)
- {
- if(IsEqualIID(riid, IID_IUnknown))
- {
- AddRef();
- *ppvObj = this;
- return HXR_OK;
- }
- else if(IsEqualIID(riid, IID_IHXSiteUser))
- {
- HX_ASSERT(0 && "Huh?! CSmilDocumentRenderer doesn't implement IHXSiteUser");
- AddRef();
- *ppvObj = (IHXSiteUser*)this;
- return HXR_OK;
- }
- else if(IsEqualIID(riid, IID_IHXRendererAdviseSink))
- {
- AddRef();
- *ppvObj = (IHXRendererAdviseSink*)this;
- return HXR_OK;
- }
- else if(IsEqualIID(riid, IID_IHXGroupSink))
- {
- AddRef();
- *ppvObj = (IHXGroupSink*)this;
- return HXR_OK;
- }
- else if(IsEqualIID(riid, IID_IHXClientAdviseSink))
- {
- AddRef();
- *ppvObj = (IHXClientAdviseSink*)this;
- return HXR_OK;
- }
- else if (IsEqualIID(riid, IID_IHXPrefetchSink))
- {
- AddRef();
- *ppvObj = (IHXPrefetchSink*)this;
- return HXR_OK;
- }
- else if (IsEqualIID(riid, IID_IHXTrackSink))
- {
- AddRef();
- *ppvObj = (IHXTrackSink*)this;
- return HXR_OK;
- }
- #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT)
- else if (IsEqualIID(riid, IID_IHXViewPortSink))
- {
- AddRef();
- *ppvObj = (IHXViewPortSink*) this;
- return HXR_OK;
- }
- #ifdef XXXMEH_DO_VIEWPORT_TLC
- else if (IsEqualIID(riid, IID_IHXViewPortSupplier))
- {
- AddRef();
- *ppvObj = (IHXViewPortSupplier*) this;
- return HXR_OK;
- }
- #endif
- #endif /* #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT) */
- #if defined(BE_SITE_SUPPLIER_20010205)
- else if (IsEqualIID(riid, IID_IHXSiteSupplier))
- {
- AddRef();
- *ppvObj = (IHXSiteSupplier*) this;
- return HXR_OK;
- }
- #endif /* BE_SITE_SUPPLIER_20010205 */
- else if (IsEqualIID(riid, IID_IHXMediaMarkerSink))
- {
- AddRef();
- *ppvObj = (IHXMediaMarkerSink*) this;
- return HXR_OK;
- }
- else if (IsEqualIID(riid, IID_IHXEventSink))
- {
- AddRef();
- *ppvObj = (IHXEventSink*) this;
- return HXR_OK;
- }
- else if (IsEqualIID(riid, IID_IHXErrorSink))
- {
- AddRef();
- *ppvObj = (IHXErrorSink*) this;
- return HXR_OK;
- }
- *ppvObj = NULL;
- return HXR_NOINTERFACE;
- }
- STDMETHODIMP_(ULONG32)
- CSmilDocumentRenderer::AddRef()
- {
- return InterlockedIncrement(&m_lRefCount);
- }
- STDMETHODIMP_(ULONG32)
- CSmilDocumentRenderer::Release()
- {
- if(InterlockedDecrement(&m_lRefCount) > 0)
- {
- return m_lRefCount;
- }
- delete this;
- return 0;
- }
- HX_RESULT
- CSmilDocumentRenderer::close(CSmilRenderer* pParent)
- {
- MLOG_LEAKCHECK("CSmilDocumentRenderer::close() t=%lun", HX_GET_BETTERTICKCOUNT());
- if (m_pHandlePendingSchedulingCallback &&
- m_pHandlePendingSchedulingCallback->m_bIsCallbackPending)
- {
- m_pHandlePendingSchedulingCallback->m_bIsCallbackPending = FALSE;
- m_pScheduler->Remove(m_pHandlePendingSchedulingCallback->m_PendingHandle);
- m_pHandlePendingSchedulingCallback->m_PendingHandle = 0;
- }
- HX_RELEASE(m_pHandlePendingSchedulingCallback);
- if (m_pHyperlinkCallback &&
- m_pHyperlinkCallback->IsCallbackPending())
- {
- m_pHyperlinkCallback->SetCallbackPending(FALSE);
- m_pScheduler->Remove(m_pHyperlinkCallback->GetCallbackHandle());
- m_pHyperlinkCallback->SetCallbackHandle(0);
- }
- HX_RELEASE(m_pHyperlinkCallback);
- if (m_pDelayedRendererCloseList)
- {
- CHXSimpleList::Iterator i = m_pDelayedRendererCloseList->Begin();
- for (; i != m_pDelayedRendererCloseList->End(); ++i)
- {
- SMILDelayedRendererClose* pClose= (SMILDelayedRendererClose*)(*i);
- //HX_ASSERT(FALSE); ??
- actualRendererClosed(pClose->m_pRenderer, pClose->m_pInfo);
- HX_RELEASE(pClose->m_pRenderer);
- HX_RELEASE(pClose->m_pInfo);
- HX_DELETE(pClose);
- }
- }
- HX_DELETE(m_pDelayedRendererCloseList);
- if (m_pRootLayout && m_pRootLayout->m_pSiteUser)
- {
- IUnknown* pThisUnk = NULL;
- m_pRootLayout->m_pSiteUser->QueryInterface(IID_IUnknown, (void**) &pThisUnk);
- if (pThisUnk)
- {
- pParent->HandleRemoveLayoutSiteGroup(pThisUnk);
- }
- HX_RELEASE(pThisUnk);
- }
- m_pParent = NULL;
- if(m_pEventList)
- {
- CHXSimpleList::Iterator i = m_pEventList->Begin();
- for(; i != m_pEventList->End(); ++i)
- {
- CSmilLayoutEvent* pEvent = (CSmilLayoutEvent*)(*i);
- delete pEvent;
- }
- }
- HX_DELETE(m_pEventList);
- removeAllPlayToAssoc();
- deleteExternalMediaMarkerList();
- // HX_DELETE(m_pRootLayout);
- #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT)
- closeViewports();
- removeViewports();
- HX_DELETE(m_pViewportList);
- #ifdef XXXMEH_DO_VIEWPORT_TLC
- clearViewportMap();
- #endif
- // Remove ourselves as a view port sink
- if (m_pViewPortManager)
- {
- IHXViewPortSink* pSink = NULL;
- QueryInterface(IID_IHXViewPortSink, (void**) &pSink);
- if (pSink)
- {
- m_pViewPortManager->RemoveViewPortSink(pSink);
- }
- HX_RELEASE(pSink);
- }
- HX_RELEASE(m_pViewPortManager);
- #endif /* #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT) */
- HX_DELETE(m_pRegPointMap);
- HX_RELEASE(m_pSMILDefaultNamespaceStr);
- #if defined(HELIX_FEATURE_SMIL2_ANIMATION)
- removeActiveAnimations();
- #endif /* #if defined(HELIX_FEATURE_SMIL2_ANIMATION) */
- HX_DELETE(m_pActiveAnimations);
- HX_DELETE(m_pAnimSiteRedrawMap);
- HX_DELETE(m_pAnimRegionRecomputeMap);
- HX_DELETE(m_pAnimTopLayoutMap);
- // Remove ourselves as a media marker sink
- // TRUE adds us, FALSE removes us
- addRemoveMediaMarkerSink(FALSE);
- // Are we setup as an event sink?
- if (m_bEventSinkWasSetup)
- {
- // Remove ourselves as an event sink,
- // TRUE adds us, FALSE removes us
- addRemoveEventSink(FALSE);
- }
- // Remove any renderer event sinks we have setup
- removeAllEventSinks();
- HX_DELETE(m_pEventSinkList);
- // Remove ourselve as an error sink
- addRemoveErrorSink(FALSE);
- HX_RELEASE(m_pErrorMessages);
- if (m_bRootLayoutSiteDetached)
- {
- destroyAllRegions();
- }
-
- #if defined(HELIX_FEATURE_SMIL2_TRANSITIONS)
- if(m_pTransitionMap)
- {
- CHXMapStringToOb::Iterator i = m_pTransitionMap->Begin();
- for(; i != m_pTransitionMap->End(); ++i)
- {
- CSmilTransitionInfo* pTrans = (CSmilTransitionInfo*)(*i);
- delete pTrans;
- }
- }
- HX_DELETE(m_pTransitionMap);
- #endif /* #if defined(HELIX_FEATURE_SMIL2_TRANSITIONS) */
- if (m_pActiveTransitions)
- {
- CHXSimpleList::Iterator i = m_pActiveTransitions->Begin();
- for (;i != m_pActiveTransitions->End(); ++i)
- {
- SMILTransitionState* pState = (SMILTransitionState*)*i;
- HX_DELETE(pState);
- }
- }
- HX_DELETE(m_pActiveTransitions);
- if(m_pGroupInfoMap)
- {
- CHXMapLongToObj::Iterator i = m_pGroupInfoMap->Begin();
- for(; i != m_pGroupInfoMap->End(); ++i)
- {
- SMILGroupInfo* pGroupInfo = (SMILGroupInfo*)(*i);
- delete pGroupInfo;
- }
- }
- HX_DELETE(m_pGroupInfoMap);
- if(m_pDeferredSourceMap)
- {
- CHXMapStringToOb::Iterator i = m_pDeferredSourceMap->Begin();
- for(; i != m_pDeferredSourceMap->End(); ++i)
- {
- SMILDeferredSourceInfo* pInfo = (SMILDeferredSourceInfo*)(*i);
- delete pInfo;
- }
- }
- HX_DELETE(m_pDeferredSourceMap);
- if(m_pDeferrededRemoveTrackMap)
- {
- CHXMapStringToOb::Iterator i = m_pDeferrededRemoveTrackMap->Begin();
- for(; i != m_pDeferrededRemoveTrackMap->End(); ++i)
- {
- CHXString* pID = (CHXString*)(*i);
- delete pID;
- }
- }
- HX_DELETE(m_pDeferrededRemoveTrackMap);
- if (m_pPausedAndDisabledIDMap)
- {
- CHXMapStringToOb::Iterator i = m_pPausedAndDisabledIDMap->Begin();
- for(; i != m_pPausedAndDisabledIDMap->End(); ++i)
- {
- CHXString* pID = (CHXString*)(*i);
- delete pID;
- }
- }
- HX_DELETE(m_pPausedAndDisabledIDMap);
-
- if (m_pPausedAndDisabledBrightnessMap)
- {
- CHXMapStringToOb::Iterator i =
- m_pPausedAndDisabledBrightnessMap->Begin();
- for (; i != m_pPausedAndDisabledBrightnessMap->End(); ++i)
- {
- float* pf = (float*)(*i);
- delete pf;
- }
- }
- HX_DELETE(m_pPausedAndDisabledBrightnessMap);
- if(m_pStatusMessage)
- {
- m_pStatusMessage->SetStatus(NULL);
- }
- HX_RELEASE(m_pStatusMessage);
- if (m_pPlayerResumeStack)
- {
- CSmilPlayerResumePos* pResumePos =
- (CSmilPlayerResumePos*)m_pPlayerResumeStack->Pop();
- while (pResumePos)
- {
- delete pResumePos;
- pResumePos = (CSmilPlayerResumePos*)m_pPlayerResumeStack->Pop();
- }
- }
- HX_DELETE(m_pPlayerResumeStack);
- if (m_bRootLayoutSiteDetached)
- {
- CleanUpSiteInfoContainers();
- HX_DELETE(m_pSiteWatcherMap);
- }
- HX_DELETE(m_pSmilParser);
- HX_VECTOR_DELETE(m_pFragment);
- HX_RELEASE(m_pScheduler);
- HX_RELEASE(m_pContext);
- clearRendererMap();
- HX_DELETE(m_pMediaID2RendererMap);
- clearRendererSiteMap();
- HX_DELETE(m_pMediaID2RendererSiteMap);
- clearRendererSiteWatcherMap();
- HX_DELETE(m_pMediaID2RendererSiteWatcherMap);
- #ifdef _MACINTOSH
- if (m_bResetCursor)
- {
- m_bResetCursor = FALSE;
- ::InitCursor();
- }
- #endif
- // Set the flag indicating that close has been called
- m_bCloseCalled = TRUE;
- // Release the sound level mutex
- HX_RELEASE(m_pSoundLevelMutex);
- return HXR_OK;
- }
- HX_RESULT
- CSmilDocumentRenderer::onHeader(IHXValues* pHeader)
- {
- m_bSMILPresentationHasEnded = FALSE;
- m_pRegionMap = new CHXMapStringToOb;
- m_pSiteInfoByRendererMap = new CHXMapPtrToPtr;
- m_pSmilParser = new CSmilParser(m_pContext);
- m_pSmilParser->init();
-
- if (m_pPersistentParentRenderer &&
- HXR_OK == m_pPersistentParentRenderer->GetElementProperties(m_uPersistentGroupID,
- m_uPersistentTrackID,
- m_pPersistentProperties))
- {
- m_pSmilParser->InitPersistent(m_ulPersistentComponentID, m_pPersistentProperties);
- }
- // Create a root-layout object
- HX_DELETE(m_pRootLayout);
- m_pRootLayout = new CSmilBasicRootLayout();
- // The SMIL default namespace is stored in the
- // "MimeType" property of the stream header
- if (pHeader)
- {
- HX_RELEASE(m_pSMILDefaultNamespaceStr);
- if (m_pParent && !m_pParent->isStreamProxiedByOtherRenderer())
- {
- pHeader->GetPropertyCString("MimeType", m_pSMILDefaultNamespaceStr);
- }
- else // /Use value passed in via IHXSmilToSmilRendererCommunicator
- {
- HX_ASSERT(m_pParent);
- if (m_pParent && m_pParent->m_pVersionNamespaceFromProxyRenderer)
- {
- m_pSMILDefaultNamespaceStr =
- m_pParent->m_pVersionNamespaceFromProxyRenderer;
- m_pSMILDefaultNamespaceStr->AddRef();
- }
- }
- }
- // Get the group we are starting on
- m_usAnimBaseGroupIndex = getCurrentGroup();
- return HXR_OK;
- }
- HX_RESULT
- CSmilDocumentRenderer::getErrorInfo(REF(UINT32) ulLineNumber,
- REF(UINT32) ulColumnNumber,
- REF(IHXBuffer*) pErrorText)
- {
- ulLineNumber = m_pSmilParser->m_ulErrorLineNumber;
- ulColumnNumber = m_pSmilParser->m_ulErrorColumnNumber;
- pErrorText = m_pSmilParser->m_pErrorText;
- if(pErrorText)
- {
- pErrorText->AddRef();
- }
- return HXR_OK;
- }
- HX_RESULT CSmilDocumentRenderer::getErrorInterface(REF(IHXErrorMessages*) rpErrMsgs)
- {
- HX_RESULT retVal = HXR_OK;
- if (m_pErrorMessages)
- {
- HX_RELEASE(rpErrMsgs);
- rpErrMsgs = m_pErrorMessages;
- rpErrMsgs->AddRef();
- }
- else
- {
- retVal = HXR_FAIL;
- }
- return retVal;
- }
- HX_RESULT
- CSmilDocumentRenderer::onPacket(IHXBuffer* pBuffer, BOOL bIsLast)
- {
- HX_RESULT rc = HXR_OK;
- BOOL bDumpToFile = FALSE;
- ::getBooleanPreference(m_pContext,
- "NonObviousKeyName",
- bDumpToFile);
- BOOL bShowPacketBoundaries = FALSE;
- ::getBooleanPreference(m_pContext,
- "NonObviousKeyNameOption1",
- bShowPacketBoundaries);
- if (bDumpToFile)
- {
- #ifdef _WINDOWS
- const char* pszFile = "c:\smildump.txt";
- #else
- const char* pszFile = "smildump.txt";
- #endif
- FILE* pFoo = fopen(pszFile, m_ulPktnum > 0L ? "a" : "w");
- if (pFoo)
- {
- char* pBuf = (char*) pBuffer->GetBuffer();
- if(pBuf && strlen(pBuf) > 0)
- {
- if (bShowPacketBoundaries)
- {
- fprintf(pFoo, "[[[packet # %lu]]]:{{{", m_ulPktnum);
- }
- fwrite(pBuf, 1, pBuffer->GetSize(), pFoo);
- if (bShowPacketBoundaries)
- {
- fprintf(pFoo, "}}}n");
- }
- }
- else
- {
- if (bShowPacketBoundaries)
- {
- fprintf(pFoo, "n[[[Packet %lu empty in onPacket()]]]n",
- m_ulPktnum);
- }
- }
- }
- fclose(pFoo);
- if (bIsLast)
- m_ulPktnum = 0L;
- else
- m_ulPktnum++;
- }
- rc = m_pSmilParser->parse(pBuffer, bIsLast);
- return rc;
- }
- HX_RESULT CSmilDocumentRenderer::setDocument(const char* pFragment)
- {
- BOOL bDisableValidation = FALSE;
- ::getBooleanPreference(m_pContext,
- "DisableSMILValidation",
- bDisableValidation);
- HX_RESULT rc = HXR_OK;
- if (!bDisableValidation)
- {
- #if defined(HELIX_FEATURE_SMIL2_VALIDATION)
- rc = m_pSmilParser->validateAgainstDTD();
- #endif /* #if defined(HELIX_FEATURE_SMIL2_VALIDATION) */
- }
- if (SUCCEEDED(rc))
- {
- rc = m_pSmilParser->createElements();
- if(HXR_OK == rc)
- {
- rc = m_pSmilParser->setAllElementHandlers(this);
- rc = handleElements();
- if (SUCCEEDED(rc))
- {
- rc = postParseSetup();
- }
- // The player may need to know about the URLs
- // we will hurl in advance. Therefore, we will
- // throw all the potential URLs we may throw
- // to the IHXHyperNavigateHint interface.
- SendHyperlinkHints();
- // Handle any references to external media marker files
- m_pSmilParser->handleAllXMMFReferences();
- BOOL bContainsSource = m_pSmilParser->presentationContainsASource();
- BOOL bContainsInitiallyScheduledTrack =
- m_pSmilParser->presentationContainsInitiallyScheduledTrack();
- ULONG32 ulDurIfNoInitialTracksScheduled =
- m_pSmilParser->presentationDurIfNoInitialTracksScheduled();
- // If we have a source in the tree but no source has
- // been scheduled, then we'll go ahead and create a group
- // XXXMEH - temporary fix. The core does not call DoneChangeLayout
- // on the TLC if there is no source scheduled. The real fix for
- // this should be done in the core/TLC but may be involved.
- // This fix should do in the meantime.
- if (!bContainsSource || !bContainsInitiallyScheduledTrack)
- {
- setupDummySource();
- }
- IHXPlayer* pPlayer = m_pParent->getPlayer();
- IHXGroupManager* pMgr = 0;
- if(HXR_OK == pPlayer->QueryInterface(IID_IHXGroupManager, (void**)&pMgr))
- {
- if(pFragment)
- {
- m_pFragment = new_string(pFragment);
- m_bSettingFragment = TRUE;
- m_nFragmentTracks = 0;
- UINT16 uFragmentGroup =
- m_pSmilParser->getFragmentGroup(m_pFragment);
- pMgr->SetCurrentGroup(uFragmentGroup);
- }
- else if (bContainsInitiallyScheduledTrack)
- {
- if (m_pParent->m_bUseNestedMeta && m_uCurrentGroupIndex == -1)
- {
- pMgr->GetCurrentGroup((UINT16&)m_uCurrentGroupIndex);
- }
- else
- {
- pMgr->SetCurrentGroup(0);
- }
- }
- // /No sources were scheduled to play, so we have to manually
- // keep the presentation open for others like animate elements
- // (which can animate regions and thus no sources are needed
- // for a SMIL presentation to be (arguably) interesting. Also,
- // a track (source) could begin on an event during playback:
- else if (ulDurIfNoInitialTracksScheduled>0 &&
- SMILTIME_INVALID != ulDurIfNoInitialTracksScheduled)
- {
- HX_ASSERT(m_pPersistentLayoutStream);
- if (m_pPersistentLayoutStream)
- {
- IHXValues* pStreamProps = NULL;
- if(HXR_OK == m_pPersistentLayoutStream->GetProperties(pStreamProps))
- {
- pStreamProps->SetPropertyULONG32("duration",
- ulDurIfNoInitialTracksScheduled);
- m_pPersistentLayoutStream->SetProperties(pStreamProps);
- HX_RELEASE(pStreamProps);
- }
- }
- // XXXMEH - since there are no sources, the only sites will
- // be region sites, so unless they have an explicit
- // showBackground="whenActive", then we need to show them here
- showAllSites(m_pRootLayout, TRUE);
- }
- pMgr->Release();
- }
- }
- }
- return rc;
- }
- HX_RESULT CSmilDocumentRenderer::setupDummySource()
- {
- HX_RESULT retVal = HXR_FAIL;
- // Our dummy source is a <brush>, so if <brush> is
- // not supported, then we fail.
- #if defined(HELIX_FEATURE_SMIL2_BRUSH)
- if (m_pParent)
- {
- // Get the player
- IHXPlayer* pPlayer = m_pParent->getPlayer();
- if (pPlayer)
- {
- // Get the group manager
- IHXGroupManager* pMgr = NULL;
- pPlayer->QueryInterface(IID_IHXGroupManager, (void**) &pMgr);
- if (pMgr)
- {
- // Get the current group
- UINT16 usGroup = 0;
- if (m_pParent->m_bUseNestedMeta && m_uCurrentGroupIndex == -1)
- {
- pMgr->GetCurrentGroup(usGroup);
- }
- // Get an IHXCommonClassFactory
- IHXCommonClassFactory* pFactory = m_pParent->getFactory();
- if (pFactory)
- {
- // Create an IHXValues for the track properties
- IHXValues* pValues = NULL;
- pFactory->CreateInstance(CLSID_IHXValues, (void**) &pValues);
- if (pValues)
- {
- // Create an IHXValues for the 822 headers
- IHXValues* pReqHeaders = NULL;
- pFactory->CreateInstance(CLSID_IHXValues, (void**) &pReqHeaders);
- if (pReqHeaders)
- {
- // Create the base of our src string
- CHXString cSrc("data:text/brush;base64,");
- // Now we need to create our brush string
- CHXString cBrushText("<brush color="black"/>");
- // Allocate an output string big enough to hold the
- // base-64-encoded string
- char* pStr64 = new char [cBrushText.GetLength() << 1];
- if (pStr64)
- {
- // Encode to base-64
- INT32 lEncodedLen = BinTo64((const BYTE*)(const char*) cBrushText,
- cBrushText.GetLength(),
- pStr64);
- // Create a string out of this encoded data
- CHXString cEncodedBrushText((const char*) pStr64, lEncodedLen);
- // Append this string to our src string
- cSrc += cEncodedBrushText;
- }
- HX_VECTOR_DELETE(pStr64);
- // Assign the "url" property
- setProperty(pValues, "url", (const char*) cSrc);
- // Assign the "id" property
- setProperty(pValues, "id", "dummy_brush_07241965");
- // Assign the delay property
- pValues->SetPropertyULONG32("delay", 0);
- // Assign the duration property to 1ms
- pValues->SetPropertyULONG32("duration", 1);
-
- //Set the PersistentComponentID.
- pValues->SetPropertyULONG32("PersistentComponentID", m_ulPersistentComponentID);
- //Tell the core this we don't want any
- //TrackAdded callbacks because we don't
- //have any groups.
- pValues->SetPropertyULONG32("NoGroupsPresent", 1);
- // Add the "NullBrush" property to the request headers
- setProperty(pReqHeaders, "NullBrush", "1");
- // Get the current group
- IHXGroup* pGroup = NULL;
- pMgr->GetGroup(usGroup, pGroup);
- if (pGroup)
- {
- // Get the IHXGroup2 interface
- IHXGroup2* pGroup2 = NULL;
- pGroup->QueryInterface(IID_IHXGroup2, (void**) &pGroup2);
- if (pGroup2)
- {
- // Add the track
- pGroup2->AddTrack2(pValues, pReqHeaders);
- }
- HX_RELEASE(pGroup2);
- }
- HX_RELEASE(pGroup);
- }
- HX_RELEASE(pReqHeaders);
- }
- HX_RELEASE(pValues);
- }
- }
- HX_RELEASE(pMgr);
- }
- }
- #endif /* #if defined(HELIX_FEATURE_SMIL2_BRUSH) */
- return retVal;
- }
- HX_RESULT
- CSmilDocumentRenderer::handleElements()
- {
- HX_RESULT rc = HXR_OK;
- if(m_pSmilParser)
- {
- //if(m_ulParseResult != HXR_STREAM_DONE)
- //{
- while(HXR_OK == rc)
- {
- rc = m_pSmilParser->handleNextElement(this);
- }
- m_ulParseResult = rc;
- //}
- }
- return HXR_OK;
- }
- HX_RESULT CSmilDocumentRenderer::postParseSetup()
- {
- HX_RESULT retVal = HXR_OK;
- // There are several things we cannot setup until
- // we have received all of the CSmilElement's handleElement()
- // methods up front.
- //
- // The first is that we want to set the SiteNeverBlts property
- // of the site, but in order to do that, we need to know all
- // the sources and all the animate elements.
- if (m_pRegionMap)
- {
- // Run through the map
- POSITION pos = m_pRegionMap->GetStartPosition();
- while (pos)
- {
- const char* pszKey = NULL;
- void* pVal = NULL;
- m_pRegionMap->GetNextAssoc(pos, pszKey, pVal);
- if (pVal)
- {
- // Get the region pointer
- CSmilBasicRegion* pRegion = (CSmilBasicRegion*) pVal;
- // Check if this region's site should
- // have its SiteNeverBlts property set to "1".
- // It should if:
- // a) the backgroundColor is transparent
- // b) backgroundColor is never animated
- // c) backgroundColor is never overridden in a source
- if (isTransparent(pRegion->m_ulBackgroundColor) &&
- !isAttributeAnimated((const char*) pRegion->m_region,
- kAttrNameBackgroundColor) &&
- !isRegionBackgroundColorOverridden(pRegion))
- {
- setSiteProperty(pRegion->m_pSite, "SiteNeverBlts", "1");
- }
- }
- }
- }
- return retVal;
- }
- HX_RESULT
- CSmilDocumentRenderer::parseDimension(const char* pDimensionString,
- REF(UINT32) ulValue,
- REF(BOOL) bIsPercent)
- {
- HX_RESULT rc = HXR_OK;
- if(!pDimensionString || strlen(pDimensionString) == 0)
- {
- ulValue = 0L;
- //[SMIL 1.0 compliance] Helps fix PR 16542. The caller of this
- // function should look at this return value to determine whether
- // or not the string was empty (and thus 0 is returned in ulValue) or
- // whether "0" or "0%" IS the string (and thus 0 is returned in
- // ulValue along with HXR_OK):
- rc = HXR_FAIL;
- }
- else
- {
- char* pEndPtr = 0;
- ulValue = (UINT32)strtod(pDimensionString, &pEndPtr);
- if(pEndPtr && strcmp(pEndPtr, "%") == 0)
- {
- bIsPercent = TRUE;
- }
- else
- {
- bIsPercent = FALSE;
- }
- }
- return rc;
- }
- HX_RESULT CSmilDocumentRenderer::computeBoxDimension(CSmilBasicBox* pBox,
- BoxDimension eDim)
- {
- HX_RESULT retVal = HXR_OK;
- if (pBox)
- {
- // Clear the flag that says whether or
- // not to compute our dimension based on
- // our children
- BOOL bPostResolve = FALSE;
- // Have we already resolved our dimension?
- if (!pBox->isResolved(eDim))
- {
- // We have NOT resolved our dimension yet,
- // so we need to attempt to resolve it
- HX_RESULT rv = pBox->computeDimension(eDim);
- if (FAILED(rv))
- {
- // We could not resolve our dimension
- // so we will have to try and resolve it
- // from our children.
- bPostResolve = TRUE;
- }
- }
- if (pBox->m_pChildList)
- {
- // Now we run through our children, computing
- // their dimensions
- LISTPOSITION pos = pBox->m_pChildList->GetHeadPosition();
- while (pos && SUCCEEDED(retVal))
- {
- CSmilBasicBox* pListBox = (CSmilBasicBox*) pBox->m_pChildList->GetNext(pos);
- if (pListBox)
- {
- retVal = computeBoxDimension(pListBox, eDim);
- }
- }
- if (SUCCEEDED(retVal) && bPostResolve)
- {
- retVal = pBox->resolveFromChildren(eDim);
- }
- }
- }
- return retVal;
- }
- void CSmilDocumentRenderer::clearResolvedFlags(CSmilBasicBox* pBox)
- {
- if (pBox)
- {
- // Clear the flags for this box
- pBox->m_bWidthResolved = FALSE;
- pBox->m_bHeightResolved = FALSE;
- // Recurse through the children
- if (pBox->m_pChildList)
- {
- LISTPOSITION pos = pBox->m_pChildList->GetHeadPosition();
- while (pos)
- {
- CSmilBasicBox* pListBox =
- (CSmilBasicBox*) pBox->m_pChildList->GetNext(pos);
- clearResolvedFlags(pListBox);
- }
- }
- }
- }
- void CSmilDocumentRenderer::resetSites(CSmilBasicBox* pBox, BOOL bOptimizeRedraws)
- {
- if (pBox)
- {
- IHXSite* pSite = pBox->m_pSite;
- BOOL bIsRegion = FALSE;
- if (pBox->m_pParent)
- {
- // This box has a parent, so it has to be a region
- bIsRegion = TRUE;
- }
- if (pSite)
- {
- // Get the current position of the site
- HXxPoint cPos = {0, 0};
- pSite->GetPosition(cPos);
- // Set the new position of the site
- HXxPoint cNewPos = {pBox->m_Rect.left, pBox->m_Rect.top};
- #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT)
- #if defined(XXXMEH_DO_VIEWPORT_TLC) && defined(_WINDOWS)
- if (pBox->m_pParent && !pBox->m_pParent->m_pParent)
- {
- // This has to be a region, so cast
- CSmilBasicRegion* pReg = (CSmilBasicRegion*) pBox;
- if (!pReg->m_bUnderRootLayout)
- {
- cNewPos.x += GetSystemMetrics(SM_CXFIXEDFRAME);
- cNewPos.y += GetSystemMetrics(SM_CYFIXEDFRAME) + GetSystemMetrics(SM_CYCAPTION);
- }
- }
- #endif
- #endif /* #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT) */
- // If the new position is different from
- // the old position, then reset the position
- if (cPos.x != cNewPos.x ||
- cPos.y != cNewPos.y)
- {
- if (bIsRegion)
- {
- CSmilBasicRegion* pReg = (CSmilBasicRegion*) pBox;
- MLOG_LAYOUT(m_pErrorMessages,
- "CSmilDocumentRenderer::resetSites() region=%s site->SetPosition(%ld,%ld)n",
- (const char*) pReg->m_region, cNewPos.x, cNewPos.y);
- }
- pSite->SetPosition(cNewPos);
- // Optimize out any site redraws if necessary
- if (bOptimizeRedraws)
- {
- // If we are calling SetPosition() on this
- // site, then the site code will automatically
- // force a redraw on this site. Therefore, if
- // we were planning on doing a ForceRedraw() on
- // this site as a result of some animation, then
- // it's no longer necessary
- removePendingAnimationRedraw(pSite);
- }
- }
- // Get the current size of the site
- HXxSize cSize = {0, 0};
- pSite->GetSize(cSize);
- // Set the new size of the site
- HXxSize cNewSize = {HXxRECT_WIDTH(pBox->m_Rect),
- HXxRECT_HEIGHT(pBox->m_Rect)};
- // If this is different from the size
- // of the rect, then resize
- if (cSize.cx != cNewSize.cx ||
- cSize.cy != cNewSize.cy)
- {
- if (bIsRegion)
- {
- CSmilBasicRegion* pReg = (CSmilBasicRegion*) pBox;
- MLOG_LAYOUT(m_pErrorMessages,
- "CSmilDocumentRenderer::resetSites() region=%s site->SetSize(%ld,%ld)n",
- (const char*) pReg->m_region, cNewSize.cx, cNewSize.cy);
- }
- pSite->SetSize(cNewSize);
- // Optimize out any site redraws if necessary
- if (bOptimizeRedraws)
- {
- // If we are calling SetSize() on this
- // site, then the site code will automatically
- // force a redraw on this site. Therefore, if
- // we were planning on doing a ForceRedraw() on
- // this site as a result of some animation, then
- // it's no longer necessary
- removePendingAnimationRedraw(pSite);
- }
- // If this is a region, then we need to
- // resize any renderers which are currently
- // playing as well.
- if (bIsRegion)
- {
- CSmilBasicRegion* pRegion = (CSmilBasicRegion*) pBox;
- resetRendererSites(pRegion);
- }
- }
- }
- // Recurse through the children
- if (pBox->m_pChildList)
- {
- LISTPOSITION pos = pBox->m_pChildList->GetHeadPosition();
- while (pos)
- {
- CSmilBasicBox* pListBox =
- (CSmilBasicBox*) pBox->m_pChildList->GetNext(pos);
- resetSites(pListBox, bOptimizeRedraws);
- }
- }
- }
- }
- void CSmilDocumentRenderer::resizeTopLevelBox(CSmilBasicBox* pBox,
- HXxSize cOrigSize,
- HXxSize cSize)
- {
- // A box is only top-level if it has no parent box
- if (pBox && !pBox->m_pParent)
- {
- // Only resize if the current size is different
- if (cSize.cx != HXxRECT_WIDTH(pBox->m_Rect) ||
- cSize.cy != HXxRECT_HEIGHT(pBox->m_Rect))
- {
- MLOG_LAYOUT(m_pErrorMessages,
- "CSmilDocumentRenderer::resizeTopLevelBox(0x%08x,(%ld,%ld),(%ld,%ld))n",
- pBox, cOrigSize.cx, cOrigSize.cy, cSize.cx, cSize.cy);
- // Clear the resolved flags
- clearResolvedFlags(pBox);
- // Normally, we have to resolve a top-level box's
- // dimensions just like anything else, but top-level
- // boxes can be explicitly resized by the user by
- // resizing the window. Therefore, we explicitly
- // set the rectangle for this top-level box
- pBox->m_Rect.left = 0;
- pBox->m_Rect.top = 0;
- if (pBox->m_eResizeBehavior == ResizePercentOnly ||
- (pBox->m_eResizeBehavior == ResizeZoom && m_bDoNotZoom))
- {
- // If we are NOT zooming, then we simply use
- // the new size. Also, this could be called in
- // the case where we are using the media size
- // to figure out the root-layout size. In that
- // case, we don't zoom either.
- pBox->m_Rect.right = cSize.cx;
- pBox->m_Rect.bottom = cSize.cy;
- }
- else
- {
- // If we are zooming, then we re-calculate
- // using the original top-level size and then
- // scale the whole thing.
- pBox->m_Rect.right = cOrigSize.cx;
- pBox->m_Rect.bottom = cOrigSize.cy;
- }
- // We force resolution of the top-level site
- pBox->m_bWidthResolved = TRUE;
- pBox->m_bHeightResolved = TRUE;
- // Compute left and right of the region rects
- computeBoxDimension(pBox, BoxDimensionWidth);
- // Compute top and bottom of the region rects
- computeBoxDimension(pBox, BoxDimensionHeight);
- // If we have zoom resize behavior, then we need to
- // compute and set the zoom scale factors and then
- // scale the rects
- if (pBox->m_eResizeBehavior == ResizeZoom && !m_bDoNotZoom)
- {
- // Compute the x scale factor
- double dScaleX = 1.0;
- if (cOrigSize.cx > 0)
- {
- dScaleX = ((double) cSize.cx) / ((double) cOrigSize.cx);
- }
- // Compute the y scale factor
- double dScaleY = 1.0;
- if (cOrigSize.cy > 0)
- {
- dScaleY = ((double) cSize.cy) / ((double) cOrigSize.cy);
- }
- // Set all the scale factors
- zoomRect(pBox, dScaleX, dScaleY);
- }
- // Turn on site composition if it's not already on
- // We don't want to turn it off if it's already on
- BOOL bInCompositionMode = isSiteCompositionModeON();
- if (!bInCompositionMode)
- {
- turnSiteCompositionModeON();
- }
- // Lock the composition if necessary
- BOOL bIsLocked = isSiteCompositionLocked();
- if (!bIsLocked)
- {
- lockSiteComposition();
- }
- // Now run through and adjust the size of the sites
- resetSites(pBox, FALSE);
- // Unlock the composition if necessary
- if (!bIsLocked)
- {
- unlockSiteComposition();
- }
- // If we're supposed to turn composition mode off,
- // then do it now. Otherwise, if we were already
- // in composition mode, then blt the site composition
- if (!bInCompositionMode)
- {
- turnSiteCompositionModeOFF();
- }
- }
- }
- }
- void CSmilDocumentRenderer::zoomRect(CSmilBasicBox* pBox,
- double dScaleX,
- double dScaleY)
- {
- if (pBox)
- {
- // Set the zoom scale factors for this box
- pBox->m_dZoomScaleFactorX = dScaleX;
- pBox->m_dZoomScaleFactorY = dScaleY;
- // Save off the unscaled rect
- pBox->m_RectNoZoom = pBox->m_Rect;
- // Apply these scale factors to the rect (with rounding)
- // Make sure we don't round the left/right and top/bottom
- // independently - this can result in spurious width/height
- // changes, even when the actual floating point scaled width
- // and height doesn't change.
- double dWidth = (double) HXxRECT_WIDTH(pBox->m_Rect);
- double dHeight = (double) HXxRECT_HEIGHT(pBox->m_Rect);
- pBox->m_Rect.left = (INT32) floor((((double) pBox->m_Rect.left) * dScaleX) + 0.5);
- pBox->m_Rect.top = (INT32) floor((((double) pBox->m_Rect.top) * dScaleY) + 0.5);
- INT32 lScaledWidth = (INT32) floor(dWidth * dScaleX + 0.5);
- INT32 lScaledHeight = (INT32) floor(dHeight * dScaleY + 0.5);
- pBox->m_Rect.right = pBox->m_Rect.left + lScaledWidth;
- pBox->m_Rect.bottom = pBox->m_Rect.top + lScaledHeight;
- // Run through any renderer site children and update
- // the scale factors of their site watchers
- if (pBox->m_pChildRendererSiteList &&
- m_pSiteWatcherMap)
- {
- LISTPOSITION pos = pBox->m_pChildRendererSiteList->GetHeadPosition();
- while (pos)
- {
- IHXSite* pRndSite = (IHXSite*) pBox->m_pChildRendererSiteList->GetNext(pos);
- if (pRndSite)
- {
- // Look up the site watcher in the site watcher map
- void* pVoid = NULL;
- if (m_pSiteWatcherMap->Lookup((void*) pRndSite, pVoid) && pVoid)
- {
- CSmilSiteWatcher* pWatcher = (CSmilSiteWatcher*) pVoid;
- pWatcher->SetZoomScaleFactors(dScaleX, dScaleY);
- }
- }
- }
- }
- // Is this a region? If it has a parent, then it
- // must be a region
- if (pBox->m_pParent)
- {
- // XXXMEH - these are holdover members which currently
- // need to be set, but should be taken out soon
- CSmilBasicRegion* pRegion = (CSmilBasicRegion*) pBox;
- pRegion->m_rect = pRegion->m_Rect;
- pRegion->m_originalRect = pRegion->m_Rect;
- }
- // Recurse through the children
- if (pBox->m_pChildList)
- {
- LISTPOSITION pos = pBox->m_pChildList->GetHeadPosition();
- while (pos)
- {
- CSmilBasicBox* pListBox =
- (CSmilBasicBox*) pBox->m_pChildList->GetNext(pos);
- zoomRect(pListBox, dScaleX, dScaleY);
- }
- }
- }
- }
- void CSmilDocumentRenderer::recomputeBoxLayout(CSmilBasicBox* pBox, BOOL bOptimizeRedraws)
- {
- if (pBox)
- {
- // Clear the resolved flags
- clearResolvedFlags(pBox);
- // Compute left and right of the region rects
- computeBoxDimension(pBox, BoxDimensionWidth);
- // Compute top and bottom of the region rects
- computeBoxDimension(pBox, BoxDimensionHeight);
- // We may currently be zoomed. If so, then
- // adjust for the zoom
- if (pBox->m_eResizeBehavior == ResizeZoom && !m_bDoNotZoom &&
- (pBox->m_dZoomScaleFactorX != 1.0 ||
- pBox->m_dZoomScaleFactorY != 1.0))
- {
- // Set all the scale factors
- zoomRect(pBox, pBox->m_dZoomScaleFactorX, pBox->m_dZoomScaleFactorY);
- }
- // Now run through and adjust the size of the sites
- resetSites(pBox, bOptimizeRedraws);
- }
- }
- HX_RESULT
- CSmilDocumentRenderer::handleRegion(CSmilRegion* pElement)
- {
- HX_RESULT retVal = HXR_OK;
- if (pElement)
- {
- // Create the CSmilBasicRegion element
- CSmilBasicRegion* pRegion = new CSmilBasicRegion(pElement);
- if (pRegion)
- {
- // Set the parent child relationships
- retVal = setRegionParentChild(pRegion);
- if (SUCCEEDED(retVal))
- {
- // Add this region to the map - m_pRegionMap is
- // the "owner" of the CSmilBasicRegion, so when it
- // goes away, all of the CSmilBasicRegion's go away.
- if (m_pRegionMap)
- {
- m_pRegionMap->SetAt((const char*) pElement->m_pNode->m_id,
- (void*) pRegion);
- }
- }
- }
- else
- {
- retVal = HXR_OUTOFMEMORY;
- }
- }
- else
- {
- retVal = HXR_FAIL;
- }
- return retVal;
- }
- HX_RESULT
- CSmilDocumentRenderer::handleRegPoint(CSmilRegPoint* pElement)
- {
- HX_RESULT retVal = HXR_OK;
- if (pElement && pElement->m_pNode)
- {
- // Does the map already exist
- if (!m_pRegPointMap)
- {
- // Create the map
- m_pRegPointMap = new CHXMapStringToOb();
- }
- if (m_pRegPointMap)
- {
- // Add this regPoint to the map
- m_pRegPointMap->SetAt((const char*) pElement->m_pNode->m_id,
- (void*) pElement);
- }
- else
- {
- retVal = HXR_OUTOFMEMORY;
- }
- }
- else
- {
- retVal = HXR_FAIL;
- }
- return retVal;
- }
- #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT)
- HX_RESULT
- CSmilDocumentRenderer::handleViewport(CSmilViewport* pElement)
- {
- HX_RESULT retVal = HXR_FAIL;
- if (pElement)
- {
- // Does the viewport list exist yet?
- if (!m_pViewportList)
- {
- // Create the list
- m_pViewportList = new CHXSimpleList();
- }
- if (m_pViewportList)
- {
- // Create a viewport object
- CSmilBasicViewport* pPort = new CSmilBasicViewport(pElement);
- if (pPort)
- {
- // Add it to the list
- m_pViewportList->AddTail((void*) pPort);
- // Clear the return value
- retVal = HXR_OK;
- }
- }
- }
- return retVal;
- }
- #endif /* #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT) */
- #if defined(HELIX_FEATURE_SMIL2_TRANSITIONS)
- HX_RESULT CSmilDocumentRenderer::handleTransition(CSmilTransition* pTrans)
- {
- HX_RESULT retVal = HXR_FAIL;
- if (pTrans)
- {
- // Create the transition map if necessary
- if (!m_pTransitionMap)
- {
- m_pTransitionMap = new CHXMapStringToOb();
- }
- if (m_pTransitionMap)
- {
- // Create a transition info object
- CSmilTransitionInfo* pInfo = new CSmilTransitionInfo(pTrans, m_pContext);
- if (pInfo)
- {
- // Put this info object in the map
- m_pTransitionMap->SetAt((const char*) pTrans->m_pNode->m_id,
- (void*) pInfo);
- // Clear the return value
- retVal = HXR_OK;
- }
- }
- }
- return retVal;
- }
- #endif /* #if defined(HELIX_FEATURE_SMIL2_TRANSITIONS) */
- #if defined(HELIX_FEATURE_SMIL2_ANIMATION)
- HX_RESULT CSmilDocumentRenderer::handleAnimate(CSmilAnimateElement* pAnimate)
- {
- MLOG_ANIM(m_pErrorMessages,"CSmilDocumentRenderer::handleAnimate() id=%s tel=%s t=%lun",
- (const char*) pAnimate->m_pNode->m_id,
- (const char*) *pAnimate->m_pTargetElementID,
- pAnimate->m_ulDelay);
- HX_RESULT retVal = HXR_OK;
- if (pAnimate)
- {
- // XXXMEH - try here to schedule other animations and
- // elements that may be using this animate element as
- // a sync-arc. This should get us through interop, but this
- // needs to be re-examined later.
- m_pSmilParser->durationResolved(pAnimate->m_pNode->m_id,
- pAnimate->m_ulActiveDuration);
- // Add this to the animation map
- if (!m_pAnimationMap)
- {
- m_pAnimationMap = new CHXMapStringToOb();
- }
- if (m_pAnimationMap)
- {
- m_pAnimationMap->SetAt(pAnimate->m_pNode->m_id, (void*) pAnimate);
- }
- // Update the duration contributed to
- // only by animations
- UINT32 ulAnimEnd = pAnimate->m_ulDelay + pAnimate->m_ulActiveDuration;
- if (ulAnimEnd > m_ulAnimDuration)
- {
- m_ulAnimDuration = ulAnimEnd;
- }
- // See if we've already scheduled an event for
- // this animate element
- CSmilAnimateEvent* pAnimEvent = getAnimateEvent(pAnimate);
- if (pAnimEvent)
- {
- // We HAVE already scheduled an event
- // for this animate element. This is most likely
- // an interactive animation which can begin
- // several times. We should adjust the time for
- // this event instead of adding a new event.
- //
- // Remove the event from the queue
- removeEvent(pAnimEvent);
- // Update the event time
- pAnimEvent->m_ulEventTime = pAnimate->m_ulDelay;
- // Re-insert into the queue with the new time
- insertEvent(pAnimEvent);
- }
- else
- {
- // We have NOT already scheduled an event
- // for this animate element
- //
- // Schedule the begin animation event
- UINT16 usGroupIndexShifted = m_usAnimBaseGroupIndex + pAnimate->m_pNode->m_nGroup;
- CSmilAnimateEvent* pEvent = new CSmilAnimateEvent(usGroupIndexShifted,
- pAnimate->m_ulDelay,
- FALSE,
- pAnimate,
- this,
- m_pSmilParser);
- if (pEvent)
- {
- // Put the event only the timeline
- insertEvent(pEvent);
- }
- }
- }
- else
- {
- retVal = HXR_FAIL;
- }
- return retVal;
- }
- #endif /* #if defined(HELIX_FEATURE_SMIL2_ANIMATION) */
- HX_RESULT CSmilDocumentRenderer::handleRemoveTimeUpdate(CSmilElement* pElement,
- UINT32 ulRemoveTime)
- {
- MLOG_EVENT(m_pErrorMessages,
- "handleRemoveTimeUpdate(0x%08x,%lu)ntmediaID=%snttick=%lun",
- pElement, ulRemoveTime,
- (const char*) pElement->m_pNode->m_id,
- HX_GET_BETTERTICKCOUNT());
- HX_RESULT retVal = HXR_OK;
- if (pElement && pElement->m_pNode &&
- m_pEventList && m_pEventList->GetCount() > 0)
- {
- // Search through the event queue to find
- // the hide event for this element.
- CHXSimpleList cTmp;
- const char* pszID = (const char*) pElement->m_pNode->m_id;
- LISTPOSITION pos = m_pEventList->GetHeadPosition();
- while (pos)
- {
- BOOL bRemoved = FALSE;
- CSmilLayoutEvent* pListEvent = (CSmilLayoutEvent*) m_pEventList->GetAt(pos);
- if (pListEvent && pListEvent->m_type == CSmilLayoutEvent::eHideSite)
- {
- CSmilShowSiteEvent* pListHide = (CSmilShowSiteEvent*) pListEvent;
- if (!strcmp(pszID, pListHide->getMediaID()) &&
- pListHide->m_ulEventTime != ulRemoveTime)
- {
- MLOG_EVENT(m_pErrorMessages,
- "tRemoving event from list (%s,%lu,%u,%lu,%lu,%s,%s) tick=%lun",
- pListHide->getEventTypeName(),
- pListHide->m_ulEventTime,
- pListHide->m_uGroupIndex,
- pListHide->m_bOnlyHideSite,
- pListHide->m_bIgnorEvent,
- pListHide->getMediaID(),
- pListHide->getRegionID(),
- HX_GET_BETTERTICKCOUNT());
- // Remove the event from the list
- pos = m_pEventList->RemoveAt(pos);
- // Set the flag
- bRemoved = TRUE;
- // Save onto the temporary list
- cTmp.AddTail((void*) pListHide);
- }
- }
- if (!bRemoved)
- {
- m_pEventList->GetNext(pos);
- }
- }
- // Did we remove any events?
- if (cTmp.GetCount() > 0)
- {
- // Loop through the removed events
- pos = cTmp.GetHeadPosition();
- while (pos)
- {
- CSmilShowSiteEvent* pHideEvent = (CSmilShowSiteEvent*) cTmp.GetNext(pos);
- if (pHideEvent)
- {
- // Set the new event time
- pHideEvent->m_ulEventTime = ulRemoveTime;
- // Get the this event's group duration
- UINT32 ulGroupDur = 0;
- if (getGroupDuration(pHideEvent->m_uGroupIndex, ulGroupDur))
- {
- // Does this media have fill="remove"?
- FillType eFill = getMediaFillBehavior((const char*) pHideEvent->getMediaID());
- // We got the group duration.
- // Is our new hide time scheduled for the
- // group duration?
- if (pHideEvent->m_ulEventTime == ulGroupDur &&
- eFill != FillRemove)
- {
- // Yes, it is, so set the flag that
- // says to ignore the hide
- pHideEvent->m_bIgnorEvent = TRUE;
- }
- else
- {
- // No, the hide is NOT scheduled for the group
- // duration, so clear the flag that
- // says to ignore the hide
- pHideEvent->m_bIgnorEvent = FALSE;
- }
- }
- // Re-insert into the event queue
- MLOG_EVENT(m_pErrorMessages,
- "tInserting event into list (%s,%lu,%u,%lu,%lu,%s,%s) tick=%lun",
- pHideEvent->getEventTypeName(),
- pHideEvent->m_ulEventTime,
- pHideEvent->m_uGroupIndex,
- pHideEvent->m_bOnlyHideSite,
- pHideEvent->m_bIgnorEvent,
- pHideEvent->getMediaID(),
- pHideEvent->getRegionID(),
- HX_GET_BETTERTICKCOUNT());
- insertEvent(pHideEvent);
- }
- }
- }
- }
- else
- {
- retVal = HXR_FAIL;
- }
- return retVal;
- }
- HX_RESULT CSmilDocumentRenderer::handleExternalMediaMarkerFile(CSmilElement* pElement,
- const char* pszID,
- const char* pszExternalFileName,
- const char* pszRelativeSource)
- {
- HX_RESULT retVal = HXR_OK;
- if (pElement && pszID && pszExternalFileName && pszRelativeSource)
- {
- // First convert the URL of the source
- CHXString cSrc;
- convertURL((const char*) m_pParent->getURLRoot(),
- (const char*) m_pParent->getURLPrefix(),
- (const char*) pszRelativeSource,
- cSrc);
- // Now generate a new root and prefix
- CHXString cNewPrefix;
- CHXString cNewRoot;
- char* pszNewFrag = NULL;
- CHXURL::GeneratePrefixRootFragment((const char*) cSrc,
- cNewPrefix,
- cNewRoot,
- pszNewFrag);
- HX_VECTOR_DELETE(pszNewFrag);
- // Now make the external media marker file name
- // relative to the source
- CHXString cExtFile;
- convertURL((const char*) cNewRoot,
- (const char*) cNewPrefix,
- pszExternalFileName,
- cExtFile);
- // Now check to see if we have already done a TrackAdded for
- // this external media marker file name
- CExternalMediaMarkerInfo* pInfo = getExternalMediaMarkerInfo(cExtFile);
- if (!pInfo)
- {
- // This file is not already present
- // Create a ExternalMediaMarkerInfo struct
- pInfo = new CExternalMediaMarkerInfo();
- if (pInfo)
- {
- // Create the list
- pInfo->m_pIDList = new CHXSimpleList();
- if (pInfo->m_pIDList)
- {
- // Add the id
- char* pID = new char [strlen(pszID) + 1];
- if (pID)
- {
- // Copy the string
- strcpy(pID, pszID); /* Flawfinder: ignore */
- // Add this id to the list
- pInfo->m_pIDList->AddTail((void*) pID);
- // Create the string
- pInfo->m_pszAddTrackURL = new char [cExtFile.GetLength() + 1];
- if (pInfo->m_pszAddTrackURL)
- {
- // Copy the string
- strcpy(pInfo->m_pszAddTrackURL, (const char*) cExtFile); /* Flawfinder: ignore */
- // Add this info to the list
- if (!m_pExternalMediaMarkerList)
- {
- m_pExternalMediaMarkerList = new CHXSimpleList();
- }
- if (m_pExternalMediaMarkerList)
- {
- m_pExternalMediaMarkerList->AddTail((void*) pInfo);
- }
- // Create an IHXValues
- IHXCommonClassFactory* pFact = m_pParent->getFactory();
- IHXValues* pValues = NULL;
- retVal = pFact->CreateInstance(CLSID_IHXValues, (void**) &pValues);
- if (SUCCEEDED(retVal))
- {
- // Set the persistent component ID
- pValues->SetPropertyULONG32("PersistentComponentID", m_ulPersistentComponentID);
- // Set the URL
- setProperty(pValues, "url", cExtFile);
- // Set a flag saying this is an external media marker
- setProperty(pValues, "ExternalMarkerFile", "1");
- // We don't really have an id for this, but we
- // will create one from the pointer of the info struct
- char szTmpID[48]; /* Flawfinder: ignore */
- sprintf(szTmpID, "xmmf_0x%08x", pInfo); /* Flawfinder: ignore */
- setProperty(pValues, "id", (const char*) szTmpID);
- setProperty(pValues, "repeatid", (const char*) szTmpID);
- // XXXMEH - are there any other properties we need to set?
- IHXGroup* pGroup = NULL;
- if (m_pGroupMap &&
- m_pGroupMap->Lookup(pElement->m_pNode->m_nGroup, (void*&) pGroup) &&
- pGroup)
- {
- // Add this external file as a track
- pGroup->AddTrack(pValues);
- }
- else
- {
- retVal = HXR_FAIL;
- }
- }
- HX_RELEASE(pValues);
- }
- else
- {
- retVal = HXR_FAIL;
- }
- }
- else
- {
- retVal = HXR_FAIL;
- }
- }
- else
- {
- retVal = HXR_FAIL;
- }
- }
- else
- {
- retVal = HXR_FAIL;
- }
- if (FAILED(retVal))
- {
- HX_DELETE(pInfo);
- }
- }
- else
- {
- // We already have done an AddTrack for this file,
- // so we simply need to add this id to the list,
- // if it is not already present.
- if (!isIDMappedToExternalMediaMarkerFile(pInfo, pszID))
- {
- // Add the id
- char* pID = new char [strlen(pszID) + 1];
- if (pID)
- {
- // Copy the string
- strcpy(pID, pszID); /* Flawfinder: ignore */
- // Add this id to the list
- pInfo->m_pIDList->AddTail((void*) pID);
- }
- }
- }
- }
- else
- {
- retVal = HXR_FAIL;
- }
- return retVal;
- }
- HX_RESULT
- CSmilDocumentRenderer::handleRootLayout(CSmilRootLayout* pElement)
- {
- HX_RESULT retVal = HXR_OK;
- if (pElement)
- {
- // Set the parser root-layout into the object
- m_pRootLayout->SetParserRootLayout(pElement);
- }
- else
- {
- retVal = HXR_FAIL;
- }
- return retVal;
- }
- HX_RESULT
- CSmilDocumentRenderer::handleAddGroup(CSmilAddGroup* pElement)
- {
- HX_RESULT rc = HXR_OK;
- if(!m_pGroupMap)
- {
- m_pGroupMap = new CHXMapLongToObj;
- }
- IHXPlayer* pPlayer = m_pParent->getPlayer();
- IHXGroupManager* pMgr = 0;
- if(HXR_OK == pPlayer->QueryInterface(IID_IHXGroupManager, (void**)&pMgr))
- {
- IHXGroup* pGroup = NULL;
- IHXGroup2* pGroup2 = NULL;
- IHXPrefetch* pPrefetch = NULL;
- if (m_pParent->m_bUseNestedMeta && 0 == m_ulGroupIndex)
- {
- rc = pMgr->GetCurrentGroup(m_uGroupIndexWithin);
- rc = pMgr->GetGroup(m_uGroupIndexWithin, pGroup);
- }
- else
- {
- rc = pMgr->CreateGroup(pGroup);
- }
- if (HXR_OK == rc)
- // release pGroup when m_pGroupMap is destructed
- {
- CHXHeader* pGroupValues = new CHXHeader;
- pGroupValues->AddRef();
- if(pElement->m_ulDuration != (UINT32)-1)
- {
- pGroupValues->SetPropertyULONG32("duration", pElement->m_ulDuration);
- }
- pGroupValues->SetPropertyULONG32("total_tracks", pElement->m_nTotalTracks);
- pGroupValues->SetPropertyULONG32("initial_tracks", pElement->m_nInitTracks);
-
- pGroupValues->SetPropertyULONG32("PersistentComponentID", m_ulPersistentComponentID);
- // copy all the node values to group values
- IHXValues* pValues = pElement->m_pValues;
- if(pValues)
- {
- IHXBuffer* pBuf = NULL;
- const char* pName = NULL;
- HX_RESULT res =
- pValues->GetFirstPropertyCString(pName, pBuf);
- while(HXR_OK == res)
- {
- pGroupValues->SetPropertyCString(pName, pBuf);
- HX_RELEASE(pBuf);
- res = pValues->GetNextPropertyCString(pName, pBuf);
- }
- }
-
- pGroup->SetGroupProperties(pGroupValues);
- if (HXR_OK == pGroup->QueryInterface(IID_IHXGroup2, (void**)&pGroup2))
- {
- pGroup2->SetPersistentComponentProperties(m_ulPersistentComponentID,
- pGroupValues);
- }
- HX_RELEASE(pGroupValues);
- if (m_pParent->m_bUseNestedMeta && 0 == m_ulGroupIndex)
- {
- GroupAdded(m_uGroupIndexWithin, pGroup);
- }
- else
- {
- pMgr->AddGroup(pGroup);
- }
-
- m_ulTrackIndex = 0;
- m_ulGroupIndex++;
- (*m_pGroupMap)[pElement->m_nGroup] = pGroup;
- if (HXR_OK == pGroup->QueryInterface(IID_IHXPrefetch, (void**)&pPrefetch))
- {
- // Add ourselves as a prefetch sink
- pPrefetch->AddPrefetchSink(this);
- // Add ourselves as a track sink
- IHXTrackSink* pSink = NULL;
- QueryInterface(IID_IHXTrackSink, (void**) &pSink);
- if (pSink)
- {
- // XXXMEH - where is the right place to remove
- // ourselves as a track sink?
- pGroup2->AddTrackSink(pSink);
- }
- HX_RELEASE(pSink);
- }
- HX_RELEASE(pPrefetch);
- HX_RELEASE(pGroup2);
- }
- }
- HX_RELEASE(pMgr);
- return rc;
- }
- HX_RESULT
- CSmilDocumentRenderer::GetCurGroupDuration(REF(UINT32) ulCurGrpDur)
- {
- HX_RESULT pnrslt = HXR_OK;
- ulCurGrpDur = m_ulCurGroupDuration;
- return pnrslt;
- }
- // /This is needed for fixing PR 56686 (and others) where the presentation
- // duration is not high enough to account for time-container-extended
- // duration. E.g.,
- // <body><par><img dur="1s"/><excl dur="20s"></excl></par></body>
- // should play for 20s even though the excl is empty, but the core didn't
- // used to have any way of knowing about this since only media durations
- // are made know to the core (via addTrack()). The below method bumps up
- // the presentation duration if a higher-than-m_ulCurGroupDuration value
- // is declared by the outer time container (body child):
- // /Also, made it so we *always* set this duration, even if we decide it
- // is lower (see below):
- HX_RESULT
- CSmilDocumentRenderer::resolveGroupDurToOuterTimeContainerDur(
- UINT32 ulGroupIndex, UINT32 ulGroupTimeContainerDuration)
- {
- #if defined(_DEBUG) && defined(XXXEH_DEBUGOUT_RESOLVEGROUPDUR)
- {
- FILE* f1 = ::fopen("c:\smil2AddDuration.txt", "a+");
- ::fprintf(f1, "CSmilDocumentRenderer::resolveGroupDurToOuterTimeContainerDur"
- "(group=%lu, groupTimeContainerDur=%lu), m_ulCurGroupDuration=%lu%sn",
- ulGroupIndex, ulGroupTimeContainerDuration, m_ulCurGroupDuration,
- m_pGroupInfoMap!=NULL?"":", (skipped: m_pGroupInfoMap is NULL)");
- ::fclose(f1);
- }
- #endif
- HX_RESULT pnrslt = HXR_OK;
- SMILGroupInfo* pGroupInfo = NULL;
- if (m_pGroupInfoMap && // /Check for NULL fixes PR 65874.
- m_pGroupInfoMap->Lookup(ulGroupIndex, (void*&)pGroupInfo))
- {
- // /Changed '>' to '>=' to fix "PR55117-related_andPR6XXX5...": re-
- // force core to adjust presentation duration after all media has
- // been added:
- // /For PR59584+, we *always* set this duration, even if we decide it
- // is lower, because we may reset the last track's duration to something
- // less and the core will then adjust without accounting for the frozen
- // period that that track may need, e.g., if last-in-seq is a par w/discrete
- // image in it, the core will first think it's 5sec long, but we reset its
- // duration to be .001sec and freeze it for the remainder of its par
- // parent (that has an explicit dur or end): removed if():
- #if defined(XXXEH_ONLY_SET_IF_SAME_OR_HIGHER_20011024)
- if (ulGroupTimeContainerDuration >=
- // /Changing this from pGroupInfo->m_ulDuration to
- // m_ulCurGroupDuration fixes PR 56686:
- m_ulCurGroupDuration // /was: pGroupInfo->m_ulDuration)
- // /Helps fix PR 62688; group duration is now resolved to
- // non-indefinite time, so let's update group duration:
- || (WAY_IN_THE_FUTURE <= m_ulCurGroupDuration &&
- WAY_IN_THE_FUTURE > ulGroupTimeContainerDuration) )
- #endif
- {
- if (ulGroupTimeContainerDuration > WAY_IN_THE_FUTURE)
- {
- ulGroupTimeContainerDuration = WAY_IN_THE_FUTURE;
- }
- // duration is the end of group
- pGroupInfo->m_ulDuration = ulGroupTimeContainerDuration;
- pGroupInfo->m_bDurationSet = TRUE;
- ignoreLastHideEvent(ulGroupIndex, pGroupInfo);
- // /Update the "persistent layout stream" duration
- if (m_pPersistentLayoutStream)
- {
- IHXValues* pStreamProps = NULL;
- m_pPersistentLayoutStream->GetProperties(pStreamProps);
- if (pStreamProps)
- {
- pStreamProps->SetPropertyULONG32("duration",
- ulGroupTimeContainerDuration);
- m_pPersistentLayoutStream->SetProperties(pStreamProps);
- // /The following if()-block fixes PR 108178: the core will
- // ignore the layoutstream duration property if we've
- // ever given the group a duration property even if it was
- // the flag-it-as-unresolved WAY_IN_THE_FUTURE value.
- // So, we need to reset the group duration property if
- // it's been set to some other value:
- IHXPlayer* pPlayer = m_pParent->getPlayer();
- IHXGroupManager* pMgr = 0;
- if (HXR_OK == pPlayer->QueryInterface(IID_IHXGroupManager,
- (void**)&pMgr))
- {
- IHXGroup* pGroup = NULL;
- IHXGroup2* pGroup2 = NULL;
- if (HXR_OK == pMgr->GetGroup(ulGroupIndex, pGroup) &&
- HXR_OK == pGroup->QueryInterface(IID_IHXGroup2,
- (void**)&pGroup2))
- {
- IHXValues* pGroupProperties = NULL;
- pGroup2->GetPersistentComponentProperties(
- m_ulPersistentComponentID, pGroupProperties);
- if(pGroupProperties)
- {
- UINT32 ulPrevGroupDur = 0;
- if (HXR_OK ==
- pGroupProperties->GetPropertyULONG32("duration",
- ulPrevGroupDur) && ulPrevGroupDur !=
- ulGroupTimeContainerDuration)
- {
- pGroupProperties->SetPropertyULONG32("duration",
- ulGroupTimeContainerDuration);
- }
- }
- HX_RELEASE(pGroupProperties);
- }
- HX_RELEASE(pGroup2);
- HX_RELEASE(pGroup);
- }
- HX_RELEASE(pMgr);
- }
- HX_RELEASE(pStreamProps);
- }
- PersistentDurationSet(pGroupInfo->m_ulDuration,
- m_pSmilParser->m_ulPersistentComponentDelay,
- // /XXXEH- TODO: check w/Henry if this is OK:
- FALSE);
- }
- }
- else
- {
- pnrslt = HXR_UNEXPECTED;
- }
- return pnrslt;
- }
- void
- CSmilDocumentRenderer::setProperty(IHXValues* pValues,
- const char* pName, const char* pValue)
- {
- IHXBuffer* pBuf = 0;
- IHXCommonClassFactory* pFactory = m_pParent->getFactory();
- if(HXR_OK == pFactory->CreateInstance(CLSID_IHXBuffer,
- (void**)&pBuf))
- {
- pBuf->Set((BYTE*)pValue, strlen(pValue)+1);
- pValues->SetPropertyCString(pName, pBuf);
- pBuf->Release();
- }
- }
- HX_RESULT CSmilDocumentRenderer::convertURL(const char* pszBaseRoot, const char* pszBasePrefix,
- const char* pURL, CHXString& newURL)
- {
- HX_RESULT retVal = HXR_OK;
- CHXURL urlObj(pURL);
- IHXValues* pHeader = urlObj.GetProperties();
- if (pHeader)
- {
- IHXBuffer* pBuffer = NULL;
- HX_RESULT rc = pHeader->GetPropertyBuffer(PROPERTY_SCHEME, pBuffer);
- if (SUCCEEDED(rc))
- {
- // fully qualified URL
- newURL = pURL;
- }
- else
- {
- // relative URL
- // if it starts with '/', make it relative to the root of
- // the URL prefix
- if(*pURL == '/')
- {
- newURL = pszBaseRoot;
- newURL += pURL;
- }
- else if (strnicmp(pURL, URL_COMMAND, sizeof(URL_COMMAND) - 1) == 0)
- {
- newURL = pURL;
- }
- else
- {
- newURL = pszBasePrefix;
- newURL += pURL;
- }
- }
- HX_RELEASE(pBuffer);
- HX_RELEASE(pHeader);
- }
- else
- {
- retVal = HXR_FAIL;
- }
- return retVal;
- }
- HX_RESULT CSmilDocumentRenderer::handleSource(CSmilSource* pElement)
- {
- MLOG_SRC(m_pErrorMessages,"handleSource() id=%s del=%lu dur=%lu m_ulCurrentTime=%lun",
- (const char*) pElement->m_pNode->m_id,
- pElement->m_ulDelay,
- pElement->m_ulDuration,
- m_ulCurrentTime);
- HX_RESULT rc = HXR_OK;
- CHXString urlString;
- convertURL((const char*) m_pParent->getURLRoot(),
- (const char*) m_pParent->getURLPrefix(),
- (const char*) pElement->m_src,
- urlString);
- BOOL bIsPrefetchElement = (pElement->m_pNode &&
- SMILPrefetch == pElement->m_pNode->m_tag);
- BOOL bDurationPropSet = FALSE;
- double fDur = -1;
- #if defined(_DEBUG) && defined(XXXEH_DEBUG_HANDLESOURCE_AND_TRACKDURATIONSET)
- {FILE* f1 = ::fopen("c:\smil2AddDuration.txt", "a+");
- ::fprintf(f1, "handleSource(media id=%s, duration=%lu, delay=%lu%s, maxDuration=%lu, clipBegin=%lu)n",
- (const char*)pElement->m_pNode->m_id, pElement->m_ulDuration,pElement->m_ulDelay,
- WAY_IN_THE_FUTURE==pElement->m_ulDelay?"(UNRESOLVED)":"", pElement->m_ulMaxDuration, pElement->m_ulClipBegin);::fclose(f1);}
- #endif
- IHXGroup* pGroup = 0;
- HX_ASSERT(WAY_IN_THE_FUTURE > pElement->m_ulDelay);
- // /For PR 59584: don't add a track whose begin is indefinite:
- if (WAY_IN_THE_FUTURE <= pElement->m_ulDelay)
- {
- goto cleanup;
- }
- if(m_pGroupMap && pElement->m_pNode &&
- m_pGroupMap->Lookup(pElement->m_pNode->m_nGroup, (void*&)pGroup))
- {
- IHXCommonClassFactory* pFactory = m_pParent->getFactory();
- IHXValues* pValues = 0;
- if(HXR_OK == pFactory->CreateInstance(CLSID_IHXValues,
- (void**)&pValues))
- {
- pValues->SetPropertyULONG32("PersistentComponentID", m_ulPersistentComponentID);
- setProperty(pValues, "url", urlString);
- setProperty(pValues, "id", pElement->m_pNode->m_id);
- setProperty(pValues, "repeatid", pElement->m_pNode->m_repeatid);
- if (!bIsPrefetchElement)
- {
- setProperty(pValues, "playto", pElement->m_region);
- if(pElement->m_region.GetLength() > 0)
- {
- // save original region name in track values
- setProperty(pValues, "region", pElement->m_region);
- }
- // Set the fill string. We should get it from pElement->m_eActualFill,
- // since this is the value which takes fillDefault into account.
-
- // XXX HP set "fill" as ULONG32 is much efficient than string!!
- // no convertion needed
- CHXString cFill;
- CSmilParser::getFillString(pElement->m_eActualFill, cFill);
- setProperty(pValues, "fill", cFill);
- pValues->SetPropertyULONG32("fill", pElement->m_eActualFill);
- CHXString cErase;
- CSmilParser::getEraseString(pElement->m_eErase, cErase);
- setProperty(pValues, "erase", cErase);
- if (pElement->m_beginTransition.GetLength() > 0)
- {
- setProperty(pValues, "beginTransition", pElement->m_beginTransition);
- }
- if (pElement->m_endTransition.GetLength() > 0)
- {
- setProperty(pValues, "endTransition", pElement->m_endTransition);
- }
- }
- setProperty(pValues, "track-hint",
- pElement->m_pNode->m_trackHint);
- pValues->SetPropertyULONG32("lexicalNum", pElement->m_pNode->m_ulTagStartLine);
- // Check the rn:accessErrorBehavior property of this element
- AccessErrorBehavior eErr =
- m_pSmilParser->getAccessErrorBehavior(pElement->m_pNode);
- if (eErr == AccessErrorBehaviorContinue)
- {
- // Set the property
- setProperty(pValues, "accessErrorBehavior", "continue");
- // Since we have rn:accessErrorBehavior="continue" behavior,
- // then we need to provide an alternative URL. We want a
- // broken window to show up. Since the GIF renderer has this
- // ability, then we will simply provide a corrupt inline GIF.
- setProperty(pValues, "altURL",
- "data:image/gif,any_non_gif_junk");
- }
- else
- {
- // Set the property
- setProperty(pValues, "accessErrorBehavior", "stop");
- }
- UINT32 ulDelay = 0;
- if(pElement->m_ulDelay != (UINT32)-1)
- {
- pValues->SetPropertyULONG32("delay", pElement->m_ulDelay);
- ulDelay = pElement->m_ulDelay;
- }
- ULONG32 ulDurationUsedInProperties = (UINT32)-1;
- if(pElement->m_ulDuration != (UINT32)-1 &&
- // /We don't want to use explicitly-set duration if
- // min=".." was set; we'll await being told of the
- // intrinsic duration of the media and THEN decide what
- // our duration should be:
- (0 == pElement->m_ulMinActiveDur &&
- !pElement->m_bUseMediaDurForMinDur) &&
- // /We also don't want to declare a dur yet if
- // max="media" in case the authored dur is greater than
- // the intrinsic duration:
- (!pElement->m_bUseMediaDurForMaxDur))
- {
- if (WAY_IN_THE_FUTURE == pElement->m_ulDuration)
- {
- HX_ASSERT(pElement->m_ulDuration > ulDelay);
- fDur = double(float(pElement->m_ulDuration - ulDelay));
- // /Don't multiply by partialPlayFactor if duration
- // is indefinite.
- }
- else
- {
- HX_ASSERT(!pElement->m_bDurationIncludesDelayBeyondSyncbase);
- fDur = double(float(pElement->m_ulDuration));
- fDur *= pElement->m_pNode->m_fPartialPlayFactor;
- }
- pValues->SetPropertyULONG32("duration", ULONG32(float(fDur)) );
- bDurationPropSet = TRUE;
- ulDurationUsedInProperties = ULONG32(float(fDur));
- }
- // Save the value of pElement->m_ulDuration that
- // we set in the AddTrack IHXValues
- pElement->m_ulDurationInAddTrack = pElement->m_ulDuration;
- if(pElement->m_ulMaxDuration != (UINT32)-1)
- {
- // /"Fixes" PR 47476 by not setting maxduration if duration
- // prop is already set (to a same-or-lower value) for repeats.
- // Otherwise, the core ignores the duration and uses the
- // maxduration as the duration passed in through subsequent
- // RepeatedTrackDurationSet() callback:
- if (!bDurationPropSet ||
- pElement->m_pNode->m_repeatTag == RepeatUnknown ||
- ulDurationUsedInProperties > pElement->m_ulMaxDuration)
- {
- ULONG32 ulMaxDuration = pElement->m_ulMaxDuration;
- if (ulDelay>0 && pElement->m_ulMaxDuration >= WAY_IN_THE_FUTURE)
- {
- // /This fixes PR 81821: indef presentation duration was
- // displaying as 22:22:22:27.2 instead of nothing shown.
- // NOTE: we'll never get here if ulDelay >= WAY_IN...:
- ulMaxDuration = WAY_IN_THE_FUTURE - ulDelay;
- }
- pValues->SetPropertyULONG32("maxduration", ulMaxDuration);
- }
- }
- if(pElement->m_ulClipBegin != (UINT32)-1)
- {
- pValues->SetPropertyULONG32("start", pElement->m_ulClipBegin);
- }
- if(pElement->m_ulClipEnd != (UINT32)-1)
- {
- pValues->SetPropertyULONG32("end", pElement->m_ulClipEnd);
- }
- if (pElement->m_pNode->m_repeatTag !=
- RepeatUnknown)
- {
- pValues->SetPropertyULONG32("repeatTag", pElement->m_pNode->m_repeatTag);
- }
- // Set the soundLevel property of the track.
- //
- // We need to check to see if this element is playing to a <region>.
- // If it is, then we will use the soundLevel attribute of that <region>.
- UINT32 ulSoundLevel = 100;
- BOOL bNeedToHandleSndLevelDueToLinkRgnTarget = FALSE;
- if (pElement->m_region.GetLength() > 0)
- {
- CSmilBasicRegion* pRegion = getRegionByID(pElement->m_region);
- if (pRegion)
- {
- // /For PR 66650: if either source or destination level
- // of the link was not 100%, then we need to adjust one
- // up or down:
- if (100 != pElement->m_ulLinkTargetDestnLevel_pct ||
- 100 != pElement->m_ulLinkTargetSourceLevel_pct)
- {
- bNeedToHandleSndLevelDueToLinkRgnTarget = TRUE;
- ulSoundLevel = pElement->m_ulLinkTargetDestnLevel_pct;
- }
- else
- {
- ulSoundLevel = UINT32(pRegion->m_dSoundLevel + 0.5);
- }
- }
- }
- #if defined(HELIX_FEATURE_SMIL2_ANIMATION)
- // Also we need to check if an animation starts right at
- // the beginning of this track. If so, then we need to
- // go ahead and set the soundLevel to be the first value
- // of the animation
- if (isAttributeAnimated(pElement->m_region, kAttrNameSoundLevel))
- {
- // We ARE animating the soundLevel of this region, so loop
- // through all the animation elements which are animating
- // this region's soundLevel. If there are multiple animations
- // going on at the same time, then we cannot attempt to
- // try and calculate these - we have to just estimate. We
- // will take the min soundLevel.
- BOOL bFound = FALSE;
- UINT32 ulMinLevel = 0xFFFFFFFF;
- CSmilAnimateElement* pAnim = getFirstAnimationElement(pElement->m_region,
- kAttrNameSoundLevel);
- while (pAnim)
- {
- // Does this animation start at the same time this
- // element starts?
- if (pAnim->m_ulDelay == pElement->m_ulDelay)
- {
- // It DOES start at the same time, so get the first
- // value of the animation
- if (pAnim->m_ppValue &&
- pAnim->m_ulNumValues >= 1 &&
- pAnim->m_ppValue[0])
- {
- // We did find at least one matching
- // animation, so set the flag
- bFound = TRUE;
- // Get the first value
- UINT32 ulTmp = (UINT32) (pAnim->m_ppValue[0]->GetValueDouble() + 0.5);
- // If it's less than the min, update the min
- if (ulTmp < ulMinLevel)
- {
- ulMinLevel = ulTmp;
- }
-
- }
- }
- // Get the next animation
- pAnim = getNextAnimationElement(pElement->m_region,
- kAttrNameSoundLevel);
- }
- // If we found a matching animation, then set
- // the soundLevel
- if (bFound)
- {
- ulSoundLevel = ulMinLevel;
- }
- }
- #endif /* #if defined(HELIX_FEATURE_SMIL2_ANIMATION) */
- // /For PR 66650: if this element was created for a link-targetted
- // region, then we may need to adjust soundLevel of currently-
- // playing audio tracks:
- if (bNeedToHandleSndLevelDueToLinkRgnTarget)
- {
- // /Adjust all tracks' soundLevels (both source & dest)
- // regardless of value, but skip setting dest's soundLevel if
- // calculated level is 100:
- if (100 != ulSoundLevel)
- {
- pValues->SetPropertyULONG32("soundLevel", ulSoundLevel);
- }
- // /then set all source tracks' soundLevels:
- AdjustSoundLevelsOfAllCurrentTracks(
- pElement->m_pNode->m_nGroup,
- pElement->m_ulLinkTargetSourceLevel_pct,
- pElement);
- }
- else
- {
- pValues->SetPropertyULONG32("soundLevel", ulSoundLevel);
- }
- if (pElement->m_bIndefiniteDuration ||
- pElement->m_bIndefiniteEnd)
- {
- // /Adding this check fixes PR 73961:
- if (WAY_IN_THE_FUTURE != pElement->m_ulDuration)
- {
- pValues->SetPropertyULONG32("indefiniteduration", TRUE);
- }
- }
- if (bIsPrefetchElement)
- {
- pValues->SetPropertyULONG32("PrefetchType",
- pElement->m_typeOfPrefetchAmount);
- pValues->SetPropertyULONG32("PrefetchValue",
- pElement->m_ulPrefetchAmount);
- HX_ASSERT(pElement->m_typeOfPrefetchAmount <
- PrefetchMaxAllowedPlus1);
- }
- if (pElement->m_title.GetLength() > 0)
- {
- setProperty(pValues, "title",
- (const char*)pElement->m_title);
- }
- if (pElement->m_author.GetLength() > 0)
- {
- setProperty(pValues, "author",
- (const char*)pElement->m_author);
- }
- if (pElement->m_copyright.GetLength() > 0)
- {
- setProperty(pValues, "copyright",
- (const char*)pElement->m_copyright);
- }
- if (pElement->m_abstract.GetLength() > 0)
- {
- setProperty(pValues, "abstract",
- (const char*)pElement->m_abstract);
- }
- // add arbitrary name-value pairs to track
- if(pElement->m_pNode->m_pValues)
- {
- IHXValues* pSrcValues = pElement->m_pNode->m_pValues;
- const char* pName = 0;
- IHXBuffer* pValue = 0;
- HX_RESULT rCode = pSrcValues->GetFirstPropertyCString(
- pName, pValue);
- while(HXR_OK == rCode)
- {
- // skip the values we already have or have overridden...
- if((strcasecmp(pName, "url") != 0) &&
- (strcasecmp(pName, "id") != 0) &&
- (strcasecmp(pName, "playto") != 0) &&
- (strcasecmp(pName, "fill") != 0) &&
- (strcasecmp(pName, "title") !=0) &&
- (strcasecmp(pName, "author") !=0) &&
- (strcasecmp(pName, "copyright") !=0) &&
- (strcasecmp(pName, "abstract") !=0) )
- {
- setProperty(pValues, pName,
- (const char*)pValue->GetBuffer());
- }
- HX_RELEASE(pValue);
- rCode = pSrcValues->GetNextPropertyCString(
- pName, pValue);
- }
- HX_RELEASE(pValue);
- }
- {
- // determine whether this source has been initialized yet...
- BOOL bHandled = FALSE;
- SMILPlayToAssoc* pPlayToAssoc = NULL;
- if(m_pPlayToAssocList &&
- // /Helps fix PR 50660 (par version) and PR 62408:
- // don't repeat one that's merely restarting:
- !pElement->IsRestartingAndNotRepeating())
- {
- CHXSimpleList::Iterator i =m_pPlayToAssocList->Begin();
- for(;i!=m_pPlayToAssocList->End();++i)
- {
- SMILPlayToAssoc* pThisAssoc = (SMILPlayToAssoc*)(*i);
- if (pThisAssoc->m_repeatid == pElement->m_pNode->m_repeatid)
- {
- IHXGroup2* pGroup2 = NULL;
- IHXTrack* pHXTrack = NULL;
- if (HXR_OK == pGroup->QueryInterface(IID_IHXGroup2, (void**)&pGroup2))
- {
- if (HXR_OK == pGroup2->GetIHXTrack(pThisAssoc->m_uTrackIndex, pHXTrack) &&
- pHXTrack)
- {
- if (!bDurationPropSet &&
- pThisAssoc->m_ulDuration !=
- (UINT32)-1 &&
- 1.0 != pElement->m_pNode->
- m_fPartialPlayFactor)
- {
- double fDur = double(float(
- pThisAssoc->m_ulDuration));
- fDur *= pElement->m_pNode->
- m_fPartialPlayFactor;
- pElement->m_ulDuration =
- ULONG32(float(fDur));
- pValues->SetPropertyULONG32(
- "duration",
- pElement->m_ulDuration);
- }
- bHandled = TRUE;
- pHXTrack->AddRepeat(pValues);
- }
- HX_RELEASE(pHXTrack);
- }
- HX_RELEASE(pGroup2);
- if (bHandled)
- {
- break;
- }
- }
- }
- }
-
- if (!bHandled)
- {
- SMILNode* pSyncNode = m_pSmilParser->getSyncAncestor(
- pElement->m_pNode);
- if (bIsPrefetchElement)
- {
- IHXPrefetch* pPrefetch = NULL;
- if (HXR_OK == pGroup->QueryInterface(IID_IHXPrefetch,
- (void**)&pPrefetch))
- {
- // Add the rn:handledBy attribute to the
- // prefetch IHXValues
- const char* pszHandledByStr =
- m_pSmilParser->getEnumAttrString(SMIL2AttrRNHandledBy,
- pElement->m_eHandledBy);
- if (pszHandledByStr)
- {
- addStringProperty(pValues,
- m_pContext,
- "handledBy",
- pszHandledByStr);
- }
- if (HXR_OK == pPrefetch->AddPrefetchTrack(pValues))
- {
- UINT32 ulTrackIndex = 0;
- // /Don't cast a UINT16& to a UINT32& here otherwise Big-endian
- // machines will not receive the right 2 bytes:
- rc = pValues->GetPropertyULONG32("TrackIndex", ulTrackIndex);
- pElement->m_pNode->m_nPrefetchTrackNum = (UINT16)ulTrackIndex;
- HX_ASSERT(HXR_OK == rc);
- if (!m_pPrefetchTrackElementMap)
- {
- m_pPrefetchTrackElementMap = new CHXMapLongToObj;
- }
- CHXString* pId = new CHXString;
- *pId = pElement->m_pNode->m_id;
- (*m_pPrefetchTrackElementMap)[pElement->m_pNode->m_nPrefetchTrackNum] = pId;
- }
- }
- HX_RELEASE(pPrefetch);
- // /Fixes PR 57135: prefetch element needs to be added
- // to the timeline (i.e., to its parent) so its parent
- // duration can resolve:
- if ((UINT32)-1 != pElement->m_ulDuration)
- {
- HX_ASSERT(pElement->m_ulDuration == pElement->getPureDuration());
- m_pSmilParser->durationResolved(
- (const char*)pElement->m_pNode->m_id,
- pElement->m_ulDuration);
- }
- }
- else
- {
- // Is the soundLevel animated?
- if (isAttributeAnimated(pElement->m_region, kAttrNameSoundLevel)
- // /This will be true if there exists an a or
- // area element that messes with the audio
- // level and has sourcePlaystate="play":
- || m_pSmilParser->allTracksNeedReflushHint()
- // /Or, is the flag set that tells us that
- // this audio track might end on an event
- // (including restarting on the fly):
- || pElement->m_bAudioDeviceReflushHintNeeded)
- {
- // /Track may be ended early (on-the-fly) OR
- // The soundLevel on this track WILL be
- // animated - therefore, we need to add
- // the following hint.
- // // XXXMEH
- // OutputDebugString("setting audioDeviceReflushHint track property to 1.n");
- pValues->SetPropertyULONG32("audioDeviceReflushHint", 1);
- }
- // If mediaRepeat or any <param> elements
- // are specified, then we need to add them to request parameters
- IHXValues* pReqVal = NULL;
- IHXCommonClassFactory* pFactory = m_pParent->getFactory();
- if (pFactory)
- {
- if (pElement->m_MediaRepeat.GetLength() > 0 ||
- hasParamChildren(pElement, TRUE))
- {
- pFactory->CreateInstance(CLSID_IHXValues, (void**) &pReqVal);
- if (pReqVal)
- {
- if (pElement->m_MediaRepeat.GetLength() > 0)
- {
- addStringProperty(pReqVal, m_pContext,
- "mediaRepeat",
- pElement->m_MediaRepeat);
- }
- if (hasParamChildren(pElement, TRUE))
- {
- addParamProperties(pElement,
- pReqVal,
- m_pContext,
- TRUE);
- }
- }
- }
- }
- // /XXXEH- revisit this when we can handle groups of
- // lock-sync'd-to-each-other tracks that are
- // sync-independent of parallel tracks:
- BOOL bSyncbaseIsSyncIndependent = FALSE;
- if (pSyncNode && pSyncNode->m_pElement &&
- SmilSyncBehaviorIndependent ==
- pSyncNode->m_pElement->m_syncBehavior)
- {
- bSyncbaseIsSyncIndependent = TRUE;
- }
- if (SmilSyncBehaviorIndependent !=
- pElement->m_syncBehavior &&
- !bSyncbaseIsSyncIndependent)
- {
- // Now add the track - if there are any request
- // parameters, then use AddTrack2
- if (pReqVal)
- {
- // QI for IHXGroup2
- IHXGroup2* pGroup2 = NULL;
- pGroup->QueryInterface(IID_IHXGroup2,
- (void**) &pGroup2);
- if (pGroup2)
- {
- rc = pGroup2->AddTrack2(pValues, pReqVal);
- }
- HX_RELEASE(pGroup2);
- }
- else
- {
- rc = pGroup->AddTrack(pValues);
- }
- m_ulTrackIndex++;
- }
- // /track's syncBehavior="independent", so create a
- // new child player for it:
- else if (m_pParent)
- {
- IHXClientEngine* pClientEngine =
- m_pParent->getClientEngine();
- if (pClientEngine)
- {
- IHXPlayer* pTopLevelPlayer =
- m_pParent->getPlayer();
- IHXPlayer* pChildPlayer = NULL;
- if (HXR_OK == pClientEngine->CreatePlayer(
- pChildPlayer) && pChildPlayer)
- {
- IHXPlayerNavigator* pPlayerNavRoot=NULL;
- IHXPlayerNavigator* pPlayerNavKid=NULL;
- HX_RESULT pnrslt =
- pTopLevelPlayer->QueryInterface(
- IID_IHXPlayerNavigator,
- (void**)&pPlayerNavRoot);
- if (HXR_OK == pnrslt)
- {
- HX_RESULT pnradd = pPlayerNavRoot->
- AddChildPlayer(pChildPlayer);
- UINT16 ulNumKids = pPlayerNavRoot->
- GetNumChildPlayer();
- pnrslt =
- pChildPlayer->QueryInterface(
- IID_IHXPlayerNavigator,
- (void**)&pPlayerNavKid);
- if (HXR_OK == pnrslt)
- {
- HX_RESULT pnrspp =pPlayerNavKid->
- SetParentPlayer(
- pTopLevelPlayer);
- }
- #if defined(BE_SITE_SUPPLIER_20010205)
- m_XXXEH_HACK_regionId =
- pElement->m_region;
- m_pIndependentPlayer = pChildPlayer;
- const char* pPlayTo = (const char*)
- pElement->m_region;
- UINT32 ulLexicalNum = 0;
- pValues->GetPropertyULONG32(
- "lexicalNum", ulLexicalNum);
- setPlayToAssoc(0, 9999+ulLexicalNum,
- pElement->m_pNode->m_id,
- pElement->m_pNode->m_repeatid,
- (const char*)
- pElement->m_region,
- (const char*)
- pElement->m_region,
- NULL /*pBeginTransition*/,
- NULL /*pEndTransition*/,
- ulLexicalNum);
- // /We implement IHXSiteSupplier, so
- // we'll say we're the context and
- // then we'll get called with
- // SitesNeeded by this player, and we
- // can hook it up then:
- pChildPlayer->SetClientContext(
- (IHXSiteSupplier*)this);
- #else
- pChildPlayer->SetClientContext(
- m_pContext);
- #endif /* BE_SITE_SUPPLIER_20010205 */
- HX_RESULT openrslt = HXR_FAIL;
- // /Need IHXPlayer2 for OpenRequest():
- IHXPlayer2* pPlayer2_Child = NULL;
- // /XXXEH- hack for now; set begin,
- // end, clip-begin, and clip-end as
- // URL-encoded parameters:
- char chDelimiter = '?';
- CHXString extraURLparams = "";
- if ((UINT32)-1 !=
- pElement->m_ulDelay &&
- 0 != pElement->m_ulDelay)
- {
- extraURLparams.Format(
- "%cdelay=%.3f", chDelimiter,
- (float)pElement->m_ulDelay /
- 1000.0 );
- urlString += extraURLparams;
- extraURLparams = "";
- chDelimiter = '&';
- }
- if (-1 != fDur)
- {
- extraURLparams.Format(
- "%cduration=%.3f",
- chDelimiter,