smldoc.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:673k
- pPort->m_pSiteUser == pSiteUser)
- {
- pRet = pPort;
- break;
- }
- }
- }
- return pRet;
- }
- CSmilBasicViewport* CSmilDocumentRenderer::getViewportBySite(IHXSite* pSite)
- {
- CSmilBasicViewport* pRet = NULL;
- if(m_pViewportList)
- {
- LISTPOSITION pos = m_pViewportList->GetHeadPosition();
- while (pos)
- {
- CSmilBasicViewport* pPort =
- (CSmilBasicViewport*) m_pViewportList->GetNext(pos);
- if (pPort &&
- pPort->m_pSite == pSite)
- {
- pRet = pPort;
- break;
- }
- }
- }
- return pRet;
- }
- CSmilBasicViewport* CSmilDocumentRenderer::getViewportByDescendant(CSmilBasicRegion* pRegion)
- {
- CSmilBasicViewport* pRet = NULL;
- if (pRegion && !pRegion->m_bUnderRootLayout)
- {
- CSmilBasicBox* pTop = getTopLevelBox(pRegion);
- if (pTop)
- {
- pRet = (CSmilBasicViewport*) pTop;
- }
- }
- return pRet;
- }
- #endif /* #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT) */
- CSmilBasicBox* CSmilDocumentRenderer::getTopLevelBox(CSmilBasicRegion* pRegion)
- {
- CSmilBasicBox* pRet = NULL;
- if (pRegion && pRegion->m_pParent)
- {
- pRet = pRegion->m_pParent;
- while (pRet->m_pParent)
- {
- pRet = pRet->m_pParent;
- }
- }
- return pRet;
- }
- CSmilRegPoint* CSmilDocumentRenderer::getRegPoint(const char* pszID)
- {
- CSmilRegPoint* pRet = NULL;
- if(m_pRegPointMap)
- {
- void* pVoid = NULL;
- if (m_pRegPointMap->Lookup(pszID, pVoid))
- {
- pRet = (CSmilRegPoint*) pVoid;
- }
- }
- return pRet;
- }
- CSmilSource* CSmilDocumentRenderer::getSource(const char* pszID)
- {
- CSmilSource* pRet = NULL;
- if (m_pSmilParser)
- {
- CSmilElement* pElement = m_pSmilParser->findElement(pszID);
- if (pElement && pElement->m_pNode &&
- (pElement->m_pNode->m_tag == SMILRef ||
- pElement->m_pNode->m_tag == SMILText ||
- pElement->m_pNode->m_tag == SMILImg ||
- pElement->m_pNode->m_tag == SMILAudio ||
- pElement->m_pNode->m_tag == SMILVideo ||
- pElement->m_pNode->m_tag == SMILAnimation ||
- pElement->m_pNode->m_tag == SMILTextstream ||
- pElement->m_pNode->m_tag == SMILBrush ||
- pElement->m_pNode->m_tag == SMILPrefetch))
- {
- pRet = (CSmilSource*) pElement;
- }
- }
- return pRet;
- }
- void CSmilDocumentRenderer::setTopLevelSiteSize()
- {
- if (m_pRootLayout->IsWidthSet() &&
- m_pRootLayout->IsHeightSet())
- {
- // Set the members
- m_topSiteSize.cx = (INT32) m_pRootLayout->GetWidth();
- m_topSiteSize.cy = (INT32) m_pRootLayout->GetHeight();
- m_topSiteOriginalSize.cx = m_topSiteSize.cx;
- m_topSiteOriginalSize.cy = m_topSiteSize.cy;
- // Set the site's size
- if(m_topSiteSize.cx > 0 && m_topSiteSize.cy > 0 &&
- m_pRootLayout && m_pRootLayout->m_pSite)
- {
- // Get the site's current size
- HXxSize cSize = {0, 0};
- m_pRootLayout->m_pSite->GetSize(cSize);
- // If the size we want to set and the current
- // size are different, then call SetSize()
- if (cSize.cx != m_topSiteSize.cx ||
- cSize.cy != m_topSiteSize.cy)
- {
- m_pRootLayout->m_pSite->SetSize(m_topSiteSize);
- }
- }
- }
- }
- HX_RESULT CSmilDocumentRenderer::setRegionParentChild(CSmilBasicRegion* pRegion)
- {
- HX_RESULT retVal = HXR_OK;
- if (pRegion &&
- pRegion->m_pSmilRegion &&
- pRegion->m_pSmilRegion->m_pNode &&
- pRegion->m_pSmilRegion->m_pNode->m_pParent)
- {
- SMILNodeTag eParentTag = pRegion->m_pSmilRegion->m_pNode->m_pParent->m_tag;
- CHXString cParentID = pRegion->m_pSmilRegion->m_pNode->m_pParent->m_id;
- if (eParentTag == SMILBasicLayout)
- {
- // Does the root layout exist?
- if (!m_pRootLayout)
- {
- // Create a root layout
- m_pRootLayout = new CSmilBasicRootLayout();
- }
- if (m_pRootLayout)
- {
- // Set our own parent member
- pRegion->m_pParent = m_pRootLayout;
- // Add a child to the root-layout
- retVal = m_pRootLayout->addChild(pRegion);
- }
- else
- {
- retVal = HXR_OUTOFMEMORY;
- }
- }
- else if (eParentTag == SMILRegion)
- {
- CSmilBasicRegion* pParent = getRegionByID(cParentID);
- if (pParent)
- {
- // Set our own parent member
- pRegion->m_pParent = pParent;
- // Add ourselves as a child of our parent
- retVal = pParent->addChild(pRegion);
- if (SUCCEEDED(retVal))
- {
- // Copy our parent's flag which says
- // whether or not we are descended from
- // the root-layout
- pRegion->m_bUnderRootLayout = pParent->m_bUnderRootLayout;
- }
- }
- else
- {
- retVal = HXR_FAIL;
- }
- }
- #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT)
- else if (eParentTag == SMILViewport)
- {
- CSmilBasicViewport* pPort = getViewport(cParentID);
- if (pPort)
- {
- // Set our own parent member
- pRegion->m_pParent = pPort;
- // Add ourselves as a child of our parent
- pPort->addChild(pRegion);
- // Clear the flag that says we are a descendant
- // of the root layout
- pRegion->m_bUnderRootLayout = FALSE;
- }
- else
- {
- retVal = HXR_FAIL;
- }
- }
- #endif /* #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT) */
- }
- return retVal;
- }
- HX_RESULT CSmilDocumentRenderer::createRegionSites(CHXSimpleList* pChildList)
- {
- HX_RESULT retVal = HXR_OK;
- // Don't do anything if we don't have any children
- if (pChildList)
- {
- // Loop through the children
- LISTPOSITION pos = pChildList->GetHeadPosition();
- while (pos && SUCCEEDED(retVal))
- {
- // Get the child region
- CSmilBasicRegion* pRegion = (CSmilBasicRegion*) pChildList->GetNext(pos);
- if (pRegion)
- {
- // Setup the site for this region
- retVal = createRegionSite(pRegion);
- if (SUCCEEDED(retVal))
- {
- // We have successfully processed this region,
- // so now process its children
- retVal = createRegionSites(pRegion->m_pChildList);
- }
- }
- }
- }
- return retVal;
- }
- HX_RESULT CSmilDocumentRenderer::createRegionSite(CSmilBasicRegion* pRegion)
- {
- HX_RESULT retVal = HXR_OK;
- if (pRegion &&
- pRegion->m_pParent &&
- pRegion->m_pParent->m_pSite)
- {
- // Make sure we don't already have a site
- HX_RELEASE(pRegion->m_pSite);
- // Create the site from its parent site - this
- // could either be a top-level site (root-layout
- // or viewport) or another region's site
- retVal = pRegion->m_pParent->m_pSite->CreateChild(pRegion->m_pSite);
- if (SUCCEEDED(retVal))
- {
- // Set the position of the site
- HXxPoint cPos = {pRegion->m_Rect.left, pRegion->m_Rect.top};
- #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT)
- #if defined(XXXMEH_DO_VIEWPORT_TLC) && defined(_WINDOWS)
- if (pRegion->m_pParent &&
- !pRegion->m_pParent->m_pParent &&
- !pRegion->m_bUnderRootLayout)
- {
- cPos.x += GetSystemMetrics(SM_CXFIXEDFRAME);
- cPos.y += GetSystemMetrics(SM_CYFIXEDFRAME) + GetSystemMetrics(SM_CYCAPTION);
- }
- #endif
- #endif /* #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT) */
- MLOG_LAYOUT(m_pErrorMessages,
- "createRegionSite() region=%s SetSize(%ld,%ld)n",
- (const char*) pRegion->m_region, cPos.x, cPos.y);
- retVal = pRegion->m_pSite->SetPosition(cPos);
- if (SUCCEEDED(retVal))
- {
- // Set the size of the site
- HXxSize cSize = {HXxRECT_WIDTH(pRegion->m_Rect),
- HXxRECT_HEIGHT(pRegion->m_Rect)};
- MLOG_LAYOUT(m_pErrorMessages,
- "createRegionSite() region=%s SetSize(%ld,%ld)n",
- (const char*) pRegion->m_region, cSize.cx, cSize.cy);
- retVal = pRegion->m_pSite->SetSize(cSize);
- if (SUCCEEDED(retVal))
- {
- // Since region's have a backgroundColor, then
- // we have to create a site user which will
- // draw this background color.
- HX_RELEASE(pRegion->m_pSiteUser);
- pRegion->m_pSiteUser = new CSmilSiteUser((CSmilSiteUserResponse*) this,
- pRegion->m_ulBackgroundColor,
- m_pContext, FALSE, pRegion->m_region);
- if (pRegion->m_pSiteUser)
- {
- // AddRef the site user
- pRegion->m_pSiteUser->AddRef();
- // Attach this site user to the site
- retVal = pRegion->m_pSite->AttachUser(pRegion->m_pSiteUser);
- if (SUCCEEDED(retVal))
- {
- // If this region has a showBackground="always", then
- // make it visible. Otherwise, hide it - the show event
- // for the media playing in the region will make it
- // visible later
- if (pRegion->m_eShowBackground == ShowBackgroundAlways)
- {
- showSite(pRegion->m_pSite, TRUE);
- }
- else if (pRegion->m_eShowBackground == ShowBackgroundWhenActive)
- {
- showSite(pRegion->m_pSite, FALSE);
- }
- }
- }
- else
- {
- retVal = HXR_OUTOFMEMORY;
- }
- }
- }
- }
- }
- else
- {
- retVal = HXR_FAIL;
- }
- return retVal;
- }
- void CSmilDocumentRenderer::destroyRegionSites(CHXSimpleList* pChildList)
- {
- // Do we have any children?
- if (pChildList)
- {
- // Loop through the children
- LISTPOSITION pos = pChildList->GetHeadPosition();
- while (pos)
- {
- // Get the region
- CSmilBasicRegion* pRegion = (CSmilBasicRegion*) pChildList->GetNext(pos);
- if (pRegion)
- {
- // We have to process our children first
- destroyRegionSites(pRegion->m_pChildList);
- // Do we have a site to destroy?
- if (pRegion->m_pParent &&
- pRegion->m_pParent->m_pSite &&
- pRegion->m_pSite)
- {
- // Detach the site user - our ref on it will
- // get released when the CSmilBasicRegion is
- // destructed
- pRegion->m_pSite->DetachUser();
- // Destroy the parent-child relationship
- pRegion->m_pParent->m_pSite->DestroyChild(pRegion->m_pSite);
- }
- }
- }
- }
- }
- CSmilBasicRegion* CSmilDocumentRenderer::getRegionByName(const char* pszName)
- {
- CSmilBasicRegion* pRet = NULL;
- if (pszName && m_pRegionMap)
- {
- while (m_pRegionMapIterator)
- {
- const char* pszKey = NULL;
- void* pVoid = NULL;
- m_pRegionMap->GetNextAssoc(m_pRegionMapIterator, pszKey, pVoid);
- if (pVoid)
- {
- CSmilBasicRegion* pRegion = (CSmilBasicRegion*) pVoid;
- if (pRegion->m_pSmilRegion &&
- pRegion->m_pSmilRegion->m_RegionName.GetLength() > 0 &&
- strlen(pszName) > 0 &&
- pRegion->m_pSmilRegion->m_RegionName == pszName)
- {
- pRet = pRegion;
- break;
- }
- }
- }
- }
- return pRet;
- }
- STDMETHODIMP CSmilDocumentRenderer::SitePositionChanged(IHXSite* pSite, HXxPoint* pPoint)
- {
- HX_RESULT retVal = HXR_OK;
- return retVal;
- }
- STDMETHODIMP CSmilDocumentRenderer::SiteSizeChanged(IHXSite* pSite, HXxSize* pSize)
- {
- HX_RESULT retVal = HXR_OK;
- if (pSite && pSize)
- {
- if (m_pRootLayout &&
- m_pRootLayout->m_pSite &&
- pSite == m_pRootLayout->m_pSite)
- {
- // check for resize of top level site, we must have
- // a "site" and not already be resizing!
- if (!m_pRootLayout->m_bSiteChangingSize)
- {
- if (pSize->cx != HXxRECT_WIDTH(m_pRootLayout->m_Rect) ||
- pSize->cy != HXxRECT_HEIGHT(m_pRootLayout->m_Rect))
- {
- MLOG_LAYOUT(m_pErrorMessages,
- "SiteSizeChanged(%ld,%ld) root-layout m_ulCurrentTime=%lu t=%lun",
- pSize->cx, pSize->cy, m_ulCurrentTime, HX_GET_BETTERTICKCOUNT());
- m_pRootLayout->m_bSiteChangingSize = TRUE;
- resizeTopLevelBox(m_pRootLayout, m_pRootLayout->m_OriginalSize, *pSize);
- forceFullRedraw(m_pRootLayout->m_pSite);
- m_pRootLayout->m_bSiteChangingSize = FALSE;
- }
- }
- }
- #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT)
- else
- {
- CSmilBasicViewport* pPort = getViewportBySite(pSite);
- if (pPort)
- {
- // check for resize of top level site, we must have
- // a "site" and not already be resizing!
- if (!pPort->m_bSiteChangingSize)
- {
- if (pSize->cx != HXxRECT_WIDTH(pPort->m_Rect) ||
- pSize->cy != HXxRECT_HEIGHT(pPort->m_Rect))
- {
- pPort->m_bSiteChangingSize = TRUE;
- resizeTopLevelBox(pPort, pPort->m_OriginalSize, *pSize);
- forceFullRedraw(pPort->m_pSite);
- pPort->m_bSiteChangingSize = FALSE;
- }
- }
- }
- }
- #endif /* #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT) */
- }
- else
- {
- retVal = HXR_FAIL;
- }
- return retVal;
- }
- STDMETHODIMP CSmilDocumentRenderer::BeginDone(UINT16 uGroupIndex, UINT16 uTrackIndex)
- {
- HX_RESULT retVal = HXR_OK;
- return retVal;
- }
- STDMETHODIMP CSmilDocumentRenderer::SeekDone(UINT16 uGroupIndex, UINT16 uTrackIndex,
- UINT32 ulSeekTime)
- {
- HX_RESULT retVal = HXR_OK;
- return retVal;
- }
- STDMETHODIMP CSmilDocumentRenderer::PauseDone(UINT16 uGroupIndex, UINT16 uTrackIndex)
- {
- HX_RESULT retVal = HXR_OK;
- return retVal;
- }
- STDMETHODIMP CSmilDocumentRenderer::StopDone(UINT16 uGroupIndex, UINT16 uTrackIndex)
- {
- HX_RESULT retVal = HXR_OK;
- return retVal;
- }
- STDMETHODIMP CSmilDocumentRenderer::OnSoundLevelAnimation(UINT16 uGroupIndex,
- UINT16 uTrackIndex,
- UINT32 ulSoundLevelAnimationTime)
- {
- // XXXMEH
- // char szDbgStr[256];
- // sprintf(szDbgStr, "enter OnSoundLevelAnimation(%u,%u,%lu) m_ulCurrentTime=%lu tick=%lu threadID=%lun",
- // uGroupIndex, uTrackIndex, ulSoundLevelAnimationTime,
- // m_ulCurrentTime, HX_GET_BETTERTICKCOUNT(), GetCurrentThreadId());
- // OutputDebugString(szDbgStr);
- HX_RESULT retVal = HXR_OK;
- #if defined(HELIX_FEATURE_SMIL2_ANIMATION)
- // Get the playto assocation
- SMILPlayToAssoc* pPlayTo = getPlayToAssoc(uGroupIndex, uTrackIndex);
- if (pPlayTo)
- {
- // If there is another animation getting added right
- // now, then we need to hold up until it is added
- if (m_pSoundLevelMutex) m_pSoundLevelMutex->Lock();
- // Find the animation element which is animating
- // the soundLevel of this region
- // XXXMEH - TODO - replace this with a more efficient method
- // of finding the correct animation sandwich
- CSmilAnimateInfo* pInfo = NULL;
- if (m_pActiveAnimations)
- {
- LISTPOSITION pos = m_pActiveAnimations->GetHeadPosition();
- while (pos)
- {
- CSmilAnimateInfo* pListInfo =
- (CSmilAnimateInfo*) m_pActiveAnimations->GetNext(pos);
- if (pListInfo &&
- pListInfo->m_pSandwich)
- {
- CHXString cRegionID(pListInfo->m_pSandwich->GetTargetElementID());
- if (cRegionID == pPlayTo->m_playTo &&
- pListInfo->m_pSandwich->GetAttributeName() == kAttrNameSoundLevel)
- {
- pInfo = pListInfo;
- break;
- }
- }
- }
- }
- // Now compute the value of the animation at
- // the time we were given
- if (pInfo && pInfo->m_pSandwich && pInfo->m_pUnder)
- {
- // We want to cap the time at the duration of
- // the current group - we don't want to send
- // a timesync that is greater than the duration.
- UINT32 ulAnimTime = ulSoundLevelAnimationTime;
- if (ulAnimTime > m_ulCurGroupDuration &&
- m_ulCurGroupDuration > 0)
- {
- ulAnimTime = m_ulCurGroupDuration;
- }
- // Compute the value of the animation at the time
- CAttr cRet = pInfo->m_pSandwich->GetValue(ulAnimTime,
- pInfo->m_pUnder,
- pInfo->m_pDepend);
- // Get the sound level and clamp it at 0 on the bottom end.
- double dVal = cRet.GetValueDouble();
- if (dVal < 0.0) dVal = 0.0;
- // XXXMEH - what should we clamp it to at the top end?
- // I'll choose 10x as the limit for now, which would be 1000%.
- if (dVal > MAX_ALLOWED_SOUNDLEVEL) dVal = MAX_ALLOWED_SOUNDLEVEL;
- // Get this value as a UINT16
- UINT16 usLevel = (UINT16) (dVal + 0.5);
- // Set the soundLevel for the track
- IHXTrack* pTrack = NULL;
- HX_RESULT rv = getTrack(uGroupIndex, uTrackIndex, pTrack);
- if (SUCCEEDED(rv))
- {
- MLOG_ANIM(m_pErrorMessages,"OnSoundLevelAnimation(%u,%u,%lu) m_ulCurrentTime=%lu "
- "tick=%lu I call SetSoundLevel(%u)n",
- uGroupIndex, uTrackIndex, ulSoundLevelAnimationTime,
- m_ulCurrentTime, HX_GET_BETTERTICKCOUNT(), usLevel);
- pTrack->SetSoundLevel(usLevel);
- }
- HX_RELEASE(pTrack);
- // Adjust the sandwich
- pInfo->m_pSandwich->AdjustLayers(ulAnimTime);
- // Are there no more layers left in this animation?
- if (pInfo->m_pSandwich->GetNumLayers() == 0)
- {
- // This animation is done, so finish call
- // IHXTrack::EndSoundLevelAnimation
- finishSoundLevelAnimation(pInfo);
- // Remove the animation from the active
- // animation list
- removeAnimation(pInfo);
- // Now we can delete the info object
- HX_DELETE(pInfo);
- }
- }
- // Now we can release the mutex, since we
- // are done messing with the animations.
- if (m_pSoundLevelMutex) m_pSoundLevelMutex->Unlock();
- }
- else
- {
- retVal = HXR_FAIL;
- }
- #endif /* #if defined(HELIX_FEATURE_SMIL2_ANIMATION) */
- // XXXMEH
- // sprintf(szDbgStr, "exit OnSoundLevelAnimation(%u,%u,%lu) m_ulCurrentTime=%lu tick=%lu threadID=%lun",
- // uGroupIndex, uTrackIndex, ulSoundLevelAnimationTime,
- // m_ulCurrentTime, HX_GET_BETTERTICKCOUNT(), GetCurrentThreadId());
- // OutputDebugString(szDbgStr);
- return retVal;
- }
- #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT)
- STDMETHODIMP CSmilDocumentRenderer::ViewPortOpened(const char* pszViewPort)
- {
- HX_RESULT retVal = HXR_FAIL;
- if (pszViewPort)
- {
- CSmilBasicViewport* pPort = getViewport(pszViewPort);
- if (pPort)
- {
- // Set the open flag
- pPort->m_bOpen = TRUE;
- // Clear the return value
- retVal = HXR_OK;
- // /Raise the "open" event:
- HX_RESULT rc = m_pSmilParser->tryToResolveBeginEndEvents(
- "topLayoutOpenEvent", pszViewPort, m_ulCurrentTime);
- if SUCCEEDED(rc)
- {
- handleElements();
- }
- }
- }
- return retVal;
- }
- STDMETHODIMP CSmilDocumentRenderer::ViewPortClosed(const char* pszViewPort)
- {
- HX_RESULT retVal = HXR_FAIL;
- if (pszViewPort)
- {
- CSmilBasicViewport* pPort = getViewport(pszViewPort);
- if (pPort)
- {
- // Clear the open flag
- pPort->m_bOpen = FALSE;
- // Clear the return value
- retVal = HXR_OK;
- // /Raise the "close" event:
- HX_RESULT rc = m_pSmilParser->tryToResolveBeginEndEvents(
- "topLayoutCloseEvent", pszViewPort, m_ulCurrentTime);
- if SUCCEEDED(rc)
- {
- handleElements();
- }
- }
- }
- return retVal;
- }
- STDMETHODIMP CSmilDocumentRenderer::ViewPortShown(const char* pszViewPort)
- {
- HX_RESULT retVal = HXR_OK;
- return retVal;
- }
- STDMETHODIMP CSmilDocumentRenderer::ViewPortHidden(const char* pszViewPort)
- {
- HX_RESULT retVal = HXR_OK;
- return retVal;
- }
- STDMETHODIMP CSmilDocumentRenderer::ViewPortFocusSet(const char* pszViewPort)
- {
- HX_RESULT retVal = HXR_OK;
- return retVal;
- }
- STDMETHODIMP CSmilDocumentRenderer::ViewPortZOrderSet(const char* pszViewPort, UINT32 ulZOrder)
- {
- HX_RESULT retVal = HXR_OK;
- return retVal;
- }
- #ifdef XXXMEH_DO_VIEWPORT_TLC
- STDMETHODIMP CSmilDocumentRenderer::OnViewPortOpen(IHXValues* pValues, IHXSiteUser* pSiteUser)
- {
- HX_RESULT retVal = HXR_OK;
- if (pValues && m_pContext)
- {
- // Get the common class factory interface
- IHXCommonClassFactory* pFactory = NULL;
- retVal = m_pContext->QueryInterface(IID_IHXCommonClassFactory,
- (void**) &pFactory);
- if (SUCCEEDED(retVal))
- {
- // Create an IHXSiteWindowed
- IHXSiteWindowed* pSiteWindowed = NULL;
- retVal = pFactory->CreateInstance(CLSID_IHXSiteWindowed,
- (void**) &pSiteWindowed);
- if (SUCCEEDED(retVal))
- {
- // Call Create() on the site
- UINT32 ulStyle = 0;
- #if defined(_WINDOWS)
- ulStyle = WS_CAPTION | WS_SIZEBOX | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
- #endif
- retVal = pSiteWindowed->Create(NULL, ulStyle);
- if (SUCCEEDED(retVal))
- {
- // Get the IHXSite interface
- IHXSite* pSite = NULL;
- retVal = pSiteWindowed->QueryInterface(IID_IHXSite,
- (void**) &pSite);
- if (SUCCEEDED(retVal))
- {
- // Get the "playto" property
- IHXBuffer* pPlayToStr = NULL;
- retVal = pValues->GetPropertyCString("playto", pPlayToStr);
- if (SUCCEEDED(retVal))
- {
- // Get the string
- const char* pszPlayTo = (const char*) pPlayToStr->GetBuffer();
- // Get the IHXValues interface from the site
- IHXValues* pSiteValues = NULL;
- pSite->QueryInterface(IID_IHXValues, (void**) &pSiteValues);
- if (pSiteValues)
- {
- // Set the "name" property in the site properties
- pSiteValues->SetPropertyCString("name", pPlayToStr);
- // Get the viewport
- CSmilBasicViewport* pPort = getViewport(pszPlayTo);
- if (pPort && pPort->m_pSiteUser)
- {
- // QI for IHXSiteUser
- IHXSiteUser* pSiteUser = NULL;
- retVal = pPort->m_pSiteUser->QueryInterface(IID_IHXSiteUser,
- (void**) &pSiteUser);
- if (SUCCEEDED(retVal))
- {
- // Add the viewport site to the map
- if (!m_pViewPortSiteMap)
- {
- m_pViewPortSiteMap = new CHXMapStringToOb();
- }
- if (m_pViewPortSiteMap)
- {
- // AddRef the site before going in the map
- pSite->AddRef();
- // Put it into the map
- m_pViewPortSiteMap->SetAt(pszPlayTo, pSite);
- }
- // Attach the viewport's site user to the site
- retVal = pSite->AttachUser(pSiteUser);
- }
- HX_RELEASE(pSiteUser);
- }
- else
- {
- retVal = HXR_FAIL;
- }
- }
- HX_RELEASE(pSiteValues);
- }
- HX_RELEASE(pPlayToStr);
- }
- HX_RELEASE(pSite);
- }
- }
- HX_RELEASE(pSiteWindowed);
- }
- HX_RELEASE(pFactory);
- }
- else
- {
- retVal = HXR_FAIL;
- }
- return retVal;
- }
- STDMETHODIMP CSmilDocumentRenderer::OnViewPortClose(const char* pszViewPort)
- {
- HX_RESULT retVal = HXR_FAIL;
- if (pszViewPort && m_pViewPortSiteMap)
- {
- void* pObj = NULL;
- if (m_pViewPortSiteMap->Lookup(pszViewPort, pObj))
- {
- // Get the site
- IHXSite* pSite = (IHXSite*) pObj;
- // Remove it from the map
- m_pViewPortSiteMap->RemoveKey(pszViewPort);
- // Detach the user
- pSite->DetachUser();
- // Since we called IHXSiteWindowed::Create(), then
- // we need to call IHXSiteWindowed::Destroy() as well.
- IHXSiteWindowed* pSiteWindowed = NULL;
- pSite->QueryInterface(IID_IHXSiteWindowed, (void**) &pSiteWindowed);
- if (pSiteWindowed)
- {
- pSiteWindowed->Destroy();
- }
- HX_RELEASE(pSiteWindowed);
- // Release the map's ref on the site
- HX_RELEASE(pSite);
- // Clear the return value
- retVal = HXR_OK;
- }
- }
- return retVal;
- }
- STDMETHODIMP CSmilDocumentRenderer::OnViewPortShow(const char* pszViewPort)
- {
- HX_RESULT retVal = HXR_FAIL;
- if (pszViewPort && m_pViewPortSiteMap)
- {
- void* pObj = NULL;
- if (m_pViewPortSiteMap->Lookup(pszViewPort, pObj) && pObj)
- {
- // Get the site
- IHXSite* pSite = (IHXSite*) pObj;
- // Do a show on the site
- showSite(pSite, TRUE);
- // Clear the return value
- retVal = HXR_OK;
- }
- }
- return retVal;
- }
- STDMETHODIMP CSmilDocumentRenderer::OnViewPortHide(const char* pszViewPort)
- {
- HX_RESULT retVal = HXR_FAIL;
- if (pszViewPort && m_pViewPortSiteMap)
- {
- void* pObj = NULL;
- if (m_pViewPortSiteMap->Lookup(pszViewPort, pObj) && pObj)
- {
- // Get the site
- IHXSite* pSite = (IHXSite*) pObj;
- // Do a hide on the site
- showSite(pSite, FALSE);
- // Clear the return value
- retVal = HXR_OK;
- }
- }
- return retVal;
- }
- STDMETHODIMP CSmilDocumentRenderer::OnViewPortFocus(const char* pszViewPort)
- {
- HX_RESULT retVal = HXR_OK;
- return retVal;
- }
- STDMETHODIMP CSmilDocumentRenderer::OnViewPortZOrder(const char* pszViewPort, UINT32 ulZOrder)
- {
- HX_RESULT retVal = HXR_OK;
- return retVal;
- }
- #endif // #ifdef XXXMEH_DO_VIEWPORT_TLC
- #endif /* #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT) */
- BOOL
- CSmilDocumentRenderer::draw(HXxEvent* pEvent, IHXSite* pSite,
- UINT32 ulBgColor)
- {
- if(pEvent &&
- pEvent->event == HX_SURFACE_UPDATE &&
- pEvent->result == HXR_OK)
- {
- // Set up color
- UINT32 ulColor = ulBgColor;
- // Set up bitmap info header
- HXBitmapInfoHeader cHeader;
- cHeader.biSize = 40;
- cHeader.biWidth = 1;
- cHeader.biHeight = 1;
- cHeader.biPlanes = 1;
- cHeader.biBitCount = 32;
- cHeader.biCompression = (ulBgColor & 0xFF000000 ? HX_ARGB : HX_RGB);
- cHeader.biSizeImage = 0;
- cHeader.biXPelsPerMeter = 0;
- cHeader.biYPelsPerMeter = 0;
- cHeader.biClrUsed = 0;
- cHeader.biClrImportant = 0;
- cHeader.rcolor = 0;
- cHeader.gcolor = 0;
- cHeader.bcolor = 0;
- // Set up src rect
- HXxRect cSrcRect = {0, 0, 1, 1};
- // Set up dst rect
- HXxSize cSize = {0, 0};
- pSite->GetSize(cSize);
- HXxRect cDstRect = {0, 0, cSize.cx, cSize.cy};
- // Do the blt
- IHXVideoSurface* pSurf = (IHXVideoSurface*) pEvent->param1;
- if(pSurf)
- {
- pSurf->AddRef();
- pEvent->result = pSurf->Blt((BYTE*) &ulColor,
- &cHeader,
- cDstRect,
- cSrcRect);
- pSurf->Release();
- }
- }
- return TRUE;
- }
- /*
- * IHXRendererAdviseSink methods
- */
- STDMETHODIMP
- CSmilDocumentRenderer::TrackDurationSet(UINT32 ulGroupIndex,
- UINT32 ulTrackIndex,
- UINT32 ulDuration,
- UINT32 ulDelay,
- BOOL bLiveSource)
- {
- MLOG_SRC(m_pErrorMessages,"TrackDurationSet(%lu,%lu,%lu,%lu,%lu) m_ulCurrentTime=%lun",
- ulGroupIndex,
- ulTrackIndex,
- ulDuration,
- ulDelay,
- bLiveSource,
- m_ulCurrentTime);
- HX_RESULT retVal = HXR_OK;
- // /This is needed for fixing PR 66391, so we don't remove a track while
- // core is still setting it up:
- m_bInTrackDurationSetCall = TRUE;
- SMILPlayToAssoc* pPlayToAssoc = getPlayToAssoc((UINT16)ulGroupIndex,
- (UINT16)ulTrackIndex);
- #if defined(_DEBUG) && defined(XXXEH_DEBUG_HANDLESOURCE_AND_TRACKDURATIONSET)
- if (!pPlayToAssoc)
- {
- {FILE* f1 = ::fopen("c:\smil2AddDuration.txt", "a+"); ::fprintf(f1, "TrackDurationSet(media id=%s, duration=%lu, delay=%lun",
- "---####--NULL playToAssoc--####----", ulDuration, ulDelay);::fclose(f1);}
- }
- #endif
- // /XXXEH- talk to Core dudes about this:
- #define TRACKDURSET_INDEFDURATION_FUDGE_FACTOR 1000 /*milliseconds*/
- // /Work-around for Mac PR 81141: core is not giving us the duration we
- // requested (namely WAY_IN_THE_FUTURE) on the Mac; it's returning
- // 1981341952 instead of 1981342000 (i.e., is 48 millisecs too small,
- // probably due to rounding error). Let's adjust if so:
- if (ulDuration > WAY_IN_THE_FUTURE)
- {
- if (ulDuration - WAY_IN_THE_FUTURE < TRACKDURSET_INDEFDURATION_FUDGE_FACTOR)
- {
- ulDuration = WAY_IN_THE_FUTURE;
- }
- }
- else // /ulDuration < WAY_IN_THE_FUTURE
- {
- if (WAY_IN_THE_FUTURE - ulDuration < TRACKDURSET_INDEFDURATION_FUDGE_FACTOR)
- {
- ulDuration = WAY_IN_THE_FUTURE;
- }
- }
- if(pPlayToAssoc)
- {
- ULONG32 ulDurToUseForGroup = ulDuration;
- CSmilElement* pThisElement =
- m_pSmilParser->findElement(pPlayToAssoc->m_id);
- #if defined(_DEBUG) && defined(XXXEH_DEBUG_HANDLESOURCE_AND_TRACKDURATIONSET)
- {FILE* f1 = ::fopen("c:\smil2AddDuration.txt", "a+"); ::fprintf(f1, "TrackDurationSet(media id=%s, duration=%lu, delay=%lun",
- (const char*)pPlayToAssoc->m_id, ulDuration, ulDelay);::fclose(f1);}
- #endif
- if (!pPlayToAssoc->m_bDurationResolved)
- {
- BOOL bAlreadyHandledAsDiscreteMedia = FALSE;
-
- if (!pPlayToAssoc->m_bIsPersistentSource)
- {
- #if defined(HANDLE_DISCRETE_MEDIA_IN_TrackDurationSet)
- // /First, let's see if this is discrete media that needs to have
- // its duration reset to 0:
- BOOL bIsDiscreteImageMedia = FALSE;
- BOOL bIsDiscreteTextMedia = FALSE;
- IHXBuffer* pIntrinsicDurType = NULL;
- IHXStreamSource* pStreamSource = NULL;
- UINT32 ulStreamHeaderDuration = 0;
- const char* pszStreamMimeType = NULL;
- HX_RESULT pnrIntrDurTypeRet = HXR_FAIL;
- HX_RESULT pnrStrmHdrDurationRet = HXR_FAIL;
- IHXGroup* pGroup = NULL;
- // /Adjust for min
- if (pThisElement)
- {
- if ((UINT32)-1 != pThisElement->m_ulMinActiveDur)
- {
- if (ulDurToUseForGroup < pThisElement->m_ulMinActiveDur)
- {
- ulDurToUseForGroup = pThisElement->m_ulMinActiveDur;
- }
- }
- if ((UINT32)-1 != pThisElement->m_ulMaxActiveDur)
- {
- if (ulDurToUseForGroup > pThisElement->m_ulMaxActiveDur)
- {
- ulDurToUseForGroup = pThisElement->m_ulMaxActiveDur;
- }
- }
- }
- // /If it's not live and it has no authored dur (explicitly-
- // set dur, end, min) then see if it's "discrete media" and,
- // if so, set its duration to 0:
- if(!bLiveSource && pThisElement &&
- (UINT32)-1 == pThisElement->m_ulAuthoredDur &&
- // /Fixes PR 54282: if end is a sync-arc, m_ulAuthoredDur
- // is not ever set to (end-begin) so we would erroneously
- // treat this (img or text) as discrete media even though
- // it *does* have an explicit end. (Used to work 5/11!?)
- !pThisElement->m_bHasExplicitEnd &&
- 0 == pThisElement->m_ulMinActiveDur &&
- m_pGroupMap &&
- m_pGroupMap->Lookup((UINT16)ulGroupIndex,(void*&)pGroup))
- {
- IHXTrack* pTrack = NULL;
- IHXGroup2* pGroup2 = NULL;
- HX_RESULT pGrp2Rslt = pGroup->QueryInterface(IID_IHXGroup2,
- (void**)&pGroup2);
- // /This AddRef()s pTrack so be sure to release it when done:
- if (HXR_OK==pGrp2Rslt && HXR_OK==pGroup2->GetIHXTrack(
- (UINT16)ulTrackIndex, pTrack))
- {
- if (HXR_OK == pTrack->GetSource(pStreamSource) &&
- pStreamSource)
- {
- UINT16 uNumStreams = pStreamSource->GetStreamCount();
- IHXStream* pStream = NULL;
- IHXValues* pStreamHeader = NULL;
- // /Use stream #0:
- IUnknown* pUnk = NULL;
- if (uNumStreams >= 1)
- {
- pStreamSource->GetStream(0, pUnk);
- HX_ASSERT(pUnk);
- if (HXR_OK == pUnk->QueryInterface(IID_IHXStream,
- (void**)&pStream) )
- {
- pszStreamMimeType = pStream->GetStreamType();
- pStreamHeader = pStream->GetHeader();
- if (pStreamHeader)
- {
- pnrIntrDurTypeRet =
- pStreamHeader->GetPropertyCString(
- "intrinsicDurationType",
- pIntrinsicDurType);
- }
- }
- }
- // /We don't want to handle discrete media that's one
- // of multiple streams in a track since it will take
- // on the dur of the other streams so leave it alone.
- if (uNumStreams == 1)
- {
- if (pStream)
- {
- if (pStreamHeader)
- {
- pnrStrmHdrDurationRet =
- pStreamHeader->GetPropertyULONG32(
- "duration",
- ulStreamHeaderDuration);
- HX_ASSERT(HXR_OK ==
- pnrStrmHdrDurationRet);
- if (pszStreamMimeType &&
- 0==strcmp(pszStreamMimeType,
- "application/vnd.rn-gifstream2") ||
- 0==strcmp(pszStreamMimeType,
- "application/vnd.rn-gifstream3") ||
- 0==strcmp(pszStreamMimeType,
- "application/vnd.rn-jpegstream") ||
- 0==strcmp(pszStreamMimeType,
- "application/vnd.rn-pngstream") ||
- 0==strcmp(pszStreamMimeType,
- "application/vnd.rn-jpegstream") )
- {
- bIsDiscreteImageMedia = TRUE;
- }
- else if (pszStreamMimeType &&
- 0==strcmp(pszStreamMimeType,
- "text/plain"))
- {
- bIsDiscreteTextMedia = TRUE;
- }
- }
- }
- }
- HX_RELEASE(pStreamHeader);
- HX_RELEASE(pStream);
- HX_RELEASE(pUnk);
- }
- #define XXXEH_HACK_TO_GET_AROUND_CORE_BAD_CURRENTGROUP_IN_GetSourceInfo
- #if defined(XXXEH_HACK_TO_GET_AROUND_CORE_BAD_CURRENTGROUP_IN_GetSourceInfo)
- // /XXXEH- This happens in SMIL 2.0 Structure Interop test case #1.1:
- // this is what's failing in the core that got us here; m_nCurrentGroup
- // is sometimes 1 and sometimes (erroneously) 0:
- /*HXPlayer::GetSourceInfo(...)
- {
- ...
- if (uGroupIndex != m_nCurrentGroup)
- {
- */
- // /XXXEH- treat as discrete image for interop:
- else if(5000 == ulDuration)
- {
- HX_ASSERT(0);
- bIsDiscreteImageMedia = TRUE;
- ulStreamHeaderDuration = 5000;
- }
- #endif
- }
- HX_RELEASE(pTrack);
- HX_RELEASE(pGroup2);
- // /If the stream declared itself as discrete media and there
- // is no dur, end, max, ...etc. attribute on the media
- // element that overrides its intrinsic duration, then we
- // should use 0s for its duration even if the stream header
- // says otherwise. This allows new file formats to stream to
- // old renderers and vice versa, without breaking old content
- // or having new SMIL content behave differently depending on
- // the version of the discrete media file format:
- BOOL bIsDiscreteMedia = FALSE;
- if (HXR_OK == pnrIntrDurTypeRet && pIntrinsicDurType)
- {
- const char* pIntrDurBuf =
- (const char*)pIntrinsicDurType->GetBuffer();
- if (pIntrDurBuf && 0==strcmp(pIntrDurBuf,
- "intrinsicDurationDiscrete"))
- {
- bIsDiscreteMedia = TRUE;
- }
- }
- // /else is undeclared, so assume non-discrete media
- // unless the duration is exactly 5000msec and the stream
- // mime type is that of a discrete media type (gif, jpg,
- // png, plain text):
- else
- {
- const char* pStreamURL = NULL;
- // /We shouldn't be here if this is NULL:
- // / HX_ASSERT(pStreamSource);
- if (pStreamSource)
- {
- pStreamURL = pStreamSource->GetURL();
- }
- if (5000+ulDelay == ulStreamHeaderDuration &&
- (UINT32)-1 == pThisElement->m_ulAuthoredDur)
- {
- // /For testing only; does ulDuration include
- // delay? If so, we need to adjust for delay...:
- HX_ASSERT(5000+ulDelay == ulDuration);
- if (bIsDiscreteImageMedia)
- {
- bIsDiscreteMedia = TRUE;
- }
- else if (pStreamURL)
- {
- const char* pTmp = (const char*)pStreamURL;
- LONG32 lLen = strlen(pStreamURL);
- if (lLen > 4)
- {
- pTmp = pTmp + (lLen-4);// /4==len(".foo")
- if (0==strcmp(pTmp, ".gif") ||
- 0==strcmp(pTmp, ".jpg") ||
- 0==strcmp(pTmp, ".png") )
- {
- bIsDiscreteMedia = TRUE;
- // /For testing, let's make sure that
- // we always have an image mime type
- // when we simultaneously have an
- // image extension:
- HX_ASSERT(bIsDiscreteImageMedia);
- }
- }
- }
- }
- else if (60000+ulDelay == ulStreamHeaderDuration &&
- (UINT32)-1 == pThisElement->m_ulAuthoredDur)
- {
- // /For testing only; does ulDuration include
- // delay? If so, we need to adjust for delay...:
- HX_ASSERT(60000+ulDelay == ulDuration);
- if (bIsDiscreteTextMedia)
- {
- bIsDiscreteMedia = TRUE;
- }
- // /Might be old RealText-served .txt file with
- // the RealText stream mime type:
- else
- {
- const char* pTmp = (const char*)pStreamURL;
- LONG32 lLen = strlen(pTmp);
- if (lLen > 4)
- {
- pTmp = pTmp + (lLen-4);// /4==len(".txt")
- if (0==strcmp(pTmp, ".txt"))
- {
- bIsDiscreteMedia = TRUE;
- }
- }
- }
- }
- }
- if (bIsDiscreteMedia)
- {
- bAlreadyHandledAsDiscreteMedia = TRUE;
- pPlayToAssoc->m_bDurationResolved = TRUE;
- pPlayToAssoc->m_ulDelay = ulDelay;
- // /Sets it so parent will use 0 dur:
- // /Note: this used to subtract the ulDelay but that was
- // totally messed up since *THIS* particular duration
- // variable does not account for the delay (unlike other
- // duration variables used in our system). Removing that
- // fixes the last part of SMIL 2.0 Interop Timing case
- // 1.15 (at least it lets the second image show up) and
- // fixes a whole slew of SMIL 2.0 Interop Transition
- // cases including 1.1 and 1.2:
- ulDuration = ZERO_DUR;
- BOOL bDurationIncludesDelay = FALSE;
- BOOL bResetDurationHandled = FALSE;
- // /If this had a repeatDur, repeatCount, or repeat on
- // it, we need to set its seq-for-repeat-wrapper
- // parent's dur to 0 (or 1?); get syncAncestor and then
- // see if its m_bIsSeqWrapperForRepeatElement is TRUE:
- SMILNode* pSyncAncestor = NULL;
- if (pThisElement && pThisElement->m_pNode)
- {
- pSyncAncestor = m_pSmilParser->getSyncAncestor(
- pThisElement->m_pNode);
- if (pSyncAncestor &&
- pSyncAncestor->m_bIsSeqWrapperForRepeatElement)
- {
- if (pSyncAncestor->m_pElement)
- {
- UINT32 ulPriorPureDuration =
- pThisElement->getPureDuration();
- if (ZERO_DUR == ulPriorPureDuration)
- { // /Don't send same value as prior:
- ulPriorPureDuration++;
- }
- // /XXXEH- use 1 (not 0) to keep core happy:
- m_pSmilParser->resetTimelineElementDuration(
- pSyncAncestor->m_id, ZERO_DUR,
- ulPriorPureDuration);
- bResetDurationHandled = TRUE;
- m_pSmilParser->durationResolved(
- pSyncAncestor->m_id, ZERO_DUR, TRUE);
- }
- }
- }
- // /HOWEVER (see note about not adding delay to duration,
- // above), we need to add beginOffset to duration, but
- // ONLY if it's set to a valid value above 0:
- if (pThisElement && pThisElement->m_pNode)
- {
- if (pThisElement->m_bBeginOffsetSet &&
- pThisElement->m_lBeginOffset > 0)
- {
- ulDuration += ulDelay;
- bDurationIncludesDelay = TRUE;
- }
- }
- // /To fix PR 79748 (broken on 20010307 when ulDelay was
- // no longer subtracted from ulDuration, here), we need
- // to subtract the ulDelay once again (as we did prior to
- // 20010307) to send the pure duration to
- // durationResolved() which in turn calls
- // CSmilTimelineElement::setDuration() which assumes
- // the duration passed to it doesn't include the syncbase
- // offset. The "broken" file that got fixed on 20010307,
- // called "...discrete_media_with_begin_offset_causes_...",
- // still works with this reversion, so something in the
- // core must have been fixed since. 20010307 bug was an
- // infinite loop in core for which this was a work-around:
- pPlayToAssoc->m_ulDuration = ulDuration -
- // /Helps fix PR 82119, by only subtracting the
- // delay if we know it's been added, above:
- (bDurationIncludesDelay? ulDelay : 0);
- HX_ASSERT(pThisElement->m_ulDuration == pThisElement->getPureDuration());
- m_pSmilParser->durationResolved(pPlayToAssoc->m_id,
- pPlayToAssoc->m_ulDuration);
- if (!bResetDurationHandled) // /Don't call reset twice:
- {
- UINT32 ulPriorPureDuration = pThisElement->getPureDuration();
- if (pPlayToAssoc->m_ulDuration == ulPriorPureDuration)
- { // /Don't send same value as prior:
- ulPriorPureDuration++;
- }
- m_pSmilParser->resetTimelineElementDuration(
- pPlayToAssoc->m_id,
- pPlayToAssoc->m_ulDuration, ulPriorPureDuration);
- }
- handleElements();
- }
- HX_RELEASE(pIntrinsicDurType);
- HX_RELEASE(pStreamSource);
- }
- #endif /* HANDLE_DISCRETE_MEDIA_IN_TrackDurationSet */
- }
- if (!bAlreadyHandledAsDiscreteMedia)
- {
- SMILNode* pSyncBaseNode = NULL;
- ULONG32 ulDelayBeyondSyncBase = 0;
- BOOL bAdjustedDurForPartialPlayFactor = FALSE;
- // /Had to add this now that external media markers are
- // causing playToAssoc's id to be something like
- // "xmmf_0x0..."
- if (pThisElement)
- {
- // /Part of fix for PR 57230; SMIL element needs to keep
- // track of whether or not it's live so its 0 dur won't
- // be used to compute its end time:
- if (bLiveSource)
- {
- HX_ASSERT(pPlayToAssoc->m_bLiveSource);
- pThisElement->m_bCurrentSourceIsLive = TRUE;
- }
- // /Fixes PR 54251:
- // /If partialPlayFactor is < 1.0 and this is not a repeat
- // element (i.e., initial partial play factor is < 1.0),
- // and if min is not constraining the lower end,
- // then multiply the ulDuration by this factor:
- if (pThisElement->m_pNode->m_fPartialPlayFactor < 1.0 &&
- (UINT32)-1 == pThisElement->m_ulDuration &&
- ulDurToUseForGroup >
- pThisElement->m_ulMinActiveDur)
- {
- double fDur = double(float(ulDuration - ulDelay));
- fDur *= pThisElement->m_pNode->m_fPartialPlayFactor;
- ULONG32 ulDurTmp = ULONG32(float(fDur)) + ulDelay;
- if (ulDurTmp < ulDurToUseForGroup)
- {
- ulDurToUseForGroup = ulDurTmp;
- if (pThisElement->m_ulMinActiveDur >
- ulDurToUseForGroup)
- {
- ulDurToUseForGroup =
- pThisElement->m_ulMinActiveDur;
- }
- bAdjustedDurForPartialPlayFactor = TRUE;
- }
- }
- pSyncBaseNode = m_pSmilParser->getSyncAncestor(
- pThisElement->m_pNode);
- if (!pSyncBaseNode || !pSyncBaseNode->m_pElement)
- {
- HX_ASSERT(pSyncBaseNode && pSyncBaseNode->m_pElement);
- pSyncBaseNode = pThisElement->m_pNode->m_pParent;
- }
- HX_ASSERT(ulDelay <= pThisElement->m_ulDelay);
- ulDelayBeyondSyncBase = pThisElement->m_ulDelay -
- pSyncBaseNode->m_pElement->m_ulDelay;
- // /Hold on, though: in a seq, the true "sync base" is
- // actually the prior sibling's end, not the begin of the
- // time container, i.e, sync ancestor, (unless there is
- // no prior sibling) so we don't want to use the whole
- // delay from the parent in that case (just the begin
- // offset part of this delay):
- if (SMILSeq == pSyncBaseNode->m_tag)
- {
- ulDelayBeyondSyncBase = 0;
- if (pThisElement->m_bBeginOffsetSet)
- {
- ulDelayBeyondSyncBase =
- (pThisElement->m_lBeginOffset > 0 ?
- (UINT32)pThisElement->m_lBeginOffset : 0);
- }
- }
- }
- pPlayToAssoc->m_bDurationResolved = TRUE;
- pPlayToAssoc->m_ulDelay = ulDelay;
- // If the value of the element duration has
- // changed since we called AddTrack (AND, for
- // now, we have an explicit end), then don't use
- // the duration that came in through TrackDurationSet().
- // Rather, use the newer value of m_ulDuration that
- // is already in the element.
- if (pThisElement->m_ulDuration != pThisElement->m_ulDurationInAddTrack &&
- pThisElement->m_bHasExplicitEnd)
- {
- // Use the element duration instead
- pPlayToAssoc->m_ulDuration = pThisElement->m_ulDuration;
- // /NOTE: PR 63622 content's Superman logo plays from 5s to 62s as it
- // should when it performs the above even though
- // pThisElement->getPureDuration() != pPlayToAssoc->m_ulDuration.
- // Could be a hide-site thing, i.e., if you assign above to
- // pure dur instead, hide (and not media end) could be all
- // that's happening early.
- }
- else
- {
- // Do what we've always done
- pPlayToAssoc->m_ulDuration =
- ulDurToUseForGroup > ulDelay ? ulDurToUseForGroup - ulDelay : 0;
- HX_ASSERT(!pThisElement->m_bDurationIncludesDelayBeyondSyncbase);
- }
- // /But wait! If track has a delay that is greater than
- // the parent delay, we want to use that difference added
- // to the duration:
- if (ulDelayBeyondSyncBase > 0)
- {
- // /XXXEH- I need to figure out if there is ever a case
- // where the element is delayed beyond its parent and
- // has a begin offset that is *not* equal to this delay:
- HX_ASSERT(pThisElement->m_bBeginOffsetSet?
- (INT32)ulDelayBeyondSyncBase ==
- pThisElement->m_lBeginOffset: 1);
- pThisElement->m_bCurBeginIsOffsetFromSyncBase = TRUE;
- pThisElement->m_ulBeginOffsetFromSyncBase =
- ulDelayBeyondSyncBase;
- if ((UINT32)-1 != pThisElement->m_ulDuration &&
- pThisElement->m_ulDuration > pPlayToAssoc->m_ulDuration)
- {
- pThisElement->m_bDurationIncludesDelayBeyondSyncbase=TRUE;
- // /Weird: I'm getting here even though if() checks for this:
- HX_ASSERT((UINT32)-1 != pThisElement->m_ulDuration);
- HX_ASSERT(ulDelayBeyondSyncBase ==
- pThisElement->m_ulDuration -
- pPlayToAssoc->m_ulDuration && "ehodge");
- }
- // /NOTE: I got rid of logic here that "fixed"
- // SMIL 2.0 Interop Timing #18.7. The right place for
- // that logic is in the subsequent call to
- // CSmilTimelineElement::setDuration(), where
- // logic has existed for a while to deal with the case
- // where the duration doesn't yet include the delay. In
- // *this* function we're in now, we treat every begin the
- // same: the duration passed to durationResolved now
- // *never* includes the delay.
- }
- // /If an external marker file is the "track", here, then
- // it's not really a valid track (does not partake in the
- // timeline) so it doesn't have an associated CSmilElement
- // and should not cause the timeline to be extended if its
- // duration is longer than the others in its group:
- if (!pThisElement)
- {
- // /Make it 1 millisecond:
- pPlayToAssoc->m_ulDuration = 1;
- }
- if(bLiveSource &&
- pPlayToAssoc->m_ulDuration == 0)
- {
- // don't resolve duration
- }
- else
- {
- if (bAdjustedDurForPartialPlayFactor)
- {
- // /XXXEH- This needs to be looked at, since all other
- // cases (post-PR-79699 fix) use pure, delay-free
- // durations for resetTimelineElementDuration():
- UINT32 ulNewDuration = pPlayToAssoc->m_ulDuration +
- // /Ultimately, handleSourceUpdate() gets
- // called which expects the delay (beyond
- // the parent begin, not the total delay) to
- // be built-in to the duration:
- ulDelayBeyondSyncBase;
- HX_ASSERT(ulNewDuration == pThisElement->getPureDuration());
- UINT32 ulPriorPureDuration = pThisElement->getPureDuration();
- if (ulNewDuration == ulPriorPureDuration)
- { // /Don't send same value as prior:
- ulPriorPureDuration++;
- }
- m_pSmilParser->resetTimelineElementDuration(
- pPlayToAssoc->m_id, ulNewDuration,
- ulPriorPureDuration);
- }
- HX_ASSERT(pThisElement->m_ulDuration == pThisElement->getPureDuration());
- m_pSmilParser->durationResolved(pPlayToAssoc->m_id,
- pPlayToAssoc->m_ulDuration);
- }
- handleElements();
- }
- }
- #if defined(HELIX_FEATURE_SMIL2_ANIMATION)
- // Check to see if this element has any children
- // which extend past the end of this track.
- checkAnimChildren(pThisElement, ulDuration);
- #endif /* #if defined(HELIX_FEATURE_SMIL2_ANIMATION) */
-
- SMILGroupInfo* pGroupInfo = NULL;
- if(m_pGroupInfoMap->Lookup(ulGroupIndex, (void*&)pGroupInfo) &&
- !pGroupInfo->m_bDurationSet)
- {
- if (ulDurToUseForGroup >
- // /Changing this from pGroupInfo->m_ulDuration to
- // m_ulCurGroupDuration fixes PR 56686:
- m_ulCurGroupDuration) // /was: pGroupInfo->m_ulDuration)
- {
- // duration is the end of group
- pGroupInfo->m_ulDuration = ulDurToUseForGroup;
- }
- if (pGroupInfo->m_ulDuration < m_ulCurGroupDuration)
- {
- pGroupInfo->m_ulDuration = m_ulCurGroupDuration;
- }
- // keep tracking the duration set calls so that
- // we can notify the parent persistent renderer upon
- // the resolvement of its duration
- pGroupInfo->m_nTrackDurationsSet++;
- if (pGroupInfo->m_nTrackDurationsSet == pGroupInfo->m_nTracks)
- {
- pGroupInfo->m_bDurationSet = TRUE;
- ignoreLastHideEvent(ulGroupIndex, pGroupInfo);
- // XXXMEH - if duration due to animations is longer than
- // the group duration, then we need to up the duration
- if (m_ulAnimDuration > pGroupInfo->m_ulDuration)
- {
- // First update the group duration
- pGroupInfo->m_ulDuration = m_ulAnimDuration;
- // Now update the "persistent layout stream duration"
- if (m_pPersistentLayoutStream)
- {
- IHXValues* pStreamProps = NULL;
- m_pPersistentLayoutStream->GetProperties(pStreamProps);
- if (pStreamProps)
- {
- pStreamProps->SetPropertyULONG32("duration", m_ulAnimDuration);
- m_pPersistentLayoutStream->SetProperties(pStreamProps);
- }
- HX_RELEASE(pStreamProps);
- }
- }
- PersistentDurationSet(pGroupInfo->m_ulDuration,
- m_pSmilParser->m_ulPersistentComponentDelay,
- bLiveSource);
- }
- }
- retVal = HXR_OK;
- goto cleanup;
- }
- else // /Failed: no pPlayToAssoc
- {
- retVal = HXR_FAILED;
- }
- cleanup:
- m_bInTrackDurationSetCall = FALSE;
- return retVal;
- }
- HX_RESULT CSmilDocumentRenderer::ignoreLastHideEvent(UINT32 ulGroupIndex,
- SMILGroupInfo* pGroupInfo)
- {
- HX_RESULT retVal = HXR_OK;
- #if 1
- if (pGroupInfo &&
- pGroupInfo->m_bDurationSet &&
- m_pEventList)
- {
- LISTPOSITION pos = m_pEventList->GetHeadPosition();
- while (pos)
- {
- CSmilLayoutEvent* pEvent =
- (CSmilLayoutEvent*) m_pEventList->GetNext(pos);
- if (pEvent &&
- pEvent->m_type == CSmilLayoutEvent::eHideSite)
- {
- CSmilShowSiteEvent* pHideEvent = (CSmilShowSiteEvent*) pEvent;
- // Does this media have fill="remove"?
- FillType eFill = getMediaFillBehavior((const char*) pHideEvent->getMediaID());
- // If our remove event is scheduled for the group
- // duration and we don't have fill="remove" behavior,
- // then set the flag to ignore the hide event.
- if (pEvent->m_uGroupIndex == (UINT16) ulGroupIndex &&
- pEvent->m_ulEventTime >= pGroupInfo->m_ulDuration &&
- eFill != FillRemove)
- {
- pEvent->m_bIgnorEvent = TRUE;
- }
- }
- }
- }
- #else
- if (pGroupInfo->m_bDurationSet && m_pSiteInfoList)
- {
- // walk through the site info list, finding sites that end
- // at the track duration, and remove their last hide event.
- CHXSimpleList::Iterator i = m_pSiteInfoList->Begin();
- for (;i != m_pSiteInfoList->End(); ++i)
- {
- SMILSiteInfo* pSiteInfo = (SMILSiteInfo*)(*i);
- if (pSiteInfo->m_uGroupIndex == ulGroupIndex &&
- pSiteInfo->m_ulDuration == pGroupInfo->m_ulDuration)
- {
- // this site ends at the end of this group...
- // remove its last hide event...
- LISTPOSITION pos = m_pEventList->GetHeadPosition();
- while (pos)
- {
- CSmilLayoutEvent* pEvent = (CSmilLayoutEvent*)
- m_pEventList->GetAt(pos);
- if (pEvent &&
- pEvent->m_type == CSmilLayoutEvent::eHideSite)
- {
- // Cast to show site event
- CSmilShowSiteEvent* pHideEvent = (CSmilShowSiteEvent*) pEvent;
- // Get the fill behavior for the media
- FillType eFill = getMediaFillBehavior((const char*) pHideEvent->getMediaID());
- // Decide if we need to supress the hide
- if (pEvent->m_uGroupIndex == ulGroupIndex &&
- pEvent->m_ulEventTime == pSiteInfo->m_ulDuration &&
- eFill != FillRemove)
- {
- pEvent->m_bIgnorEvent = TRUE;
- break;
- }
- }
- m_pEventList->GetNext(pos);
- }
- }
- }
- }
- #endif
- return retVal;
- }
- STDMETHODIMP
- CSmilDocumentRenderer::RepeatedTrackDurationSet(const char* pID,
- UINT32 ulDuration,
- BOOL bIsLive)
- {
- MLOG_SRC(m_pErrorMessages,
- "RepeatedTrackDurationSet(%s,%lu,%lu) m_ulCurrentTime=%lun",
- pID, ulDuration, bIsLive, m_ulCurrentTime);
- if(!bIsLive)
- {
- m_pSmilParser->durationResolved(pID,
- ulDuration);
- handleElements();
- }
- return HXR_OK;
- }
- STDMETHODIMP
- CSmilDocumentRenderer::TrackUpdated(UINT32 ulGroupIndex,
- UINT32 ulTrackIndex,
- IHXValues* pValues)
- {
- HX_RESULT rc = HXR_OK;
- UINT16 uNewTrackIndex = 0;
- UINT32 ulNewTrackIndex = 0;
- SMILPlayToAssoc* pPlayToAssoc = getPlayToAssoc((UINT16)ulGroupIndex,
- (UINT16)ulTrackIndex);
- if (!pPlayToAssoc)
- {
- rc = HXR_UNEXPECTED;
- goto cleanup;
- }
- // /Don't cast a UINT16& to a UINT32& here otherwise Big-endian
- // machines will not receive the right 2 bytes (part of fix for
- // PR 121880; rest of fix is in client/core):
- if (HXR_OK == pValues->GetPropertyULONG32("TrackIndex", ulNewTrackIndex))
- {
- pPlayToAssoc->m_uTrackIndex = (UINT16)ulNewTrackIndex;
- }
- cleanup:
- return rc;
- }
-
- STDMETHODIMP CSmilDocumentRenderer::AddShowEvents(const char* pRegionName,
- IHXSite* pSite)
- {
- HX_RESULT rc = HXR_OK;
- SMILPlayToAssoc* pPlayToAssoc = getPlayToAssoc(pRegionName);
- if(pPlayToAssoc)
- {
- showSite(pSite, FALSE);
-
- UINT32 ulShowTime = pPlayToAssoc->m_ulDelay;
- UINT32 ulRemoveTime = pPlayToAssoc->m_ulDuration +
- pPlayToAssoc->m_ulDelay;
- if (ulShowTime != ulRemoveTime)
- {
- // show site after m_ulDelay
- CSmilShowSiteEvent* pShowEvent =
- new CSmilShowSiteEvent(pPlayToAssoc->m_uGroupIndex,
- ulShowTime,
- pSite,
- NULL,
- TRUE);
- insertEvent(pShowEvent);
-
- #if defined(HELIX_FEATURE_SMIL2_TRANSITIONS)
- if (pPlayToAssoc->m_beginTransition.GetLength() > 0)
- {
- CSmilTransitionEvent* pTransEvent =
- new CSmilTransitionEvent(pPlayToAssoc->m_ulDelay,
- pPlayToAssoc, pSite, TRUE, this);
- insertEvent(pTransEvent);
- }
- #endif /* #if defined(HELIX_FEATURE_SMIL2_TRANSITIONS) */
- // hide site after m_ulDuration if it isn't live
- if(pPlayToAssoc->m_bRemoveSite &&
- !pPlayToAssoc->m_bLiveSource)
- {
- CSmilShowSiteEvent* pHideEvent =
- new CSmilShowSiteEvent(pPlayToAssoc->m_uGroupIndex,
- ulRemoveTime,
- pSite,
- NULL,
- FALSE);
- insertEvent(pHideEvent);
- // Set the event time into the element
- setElementRemoveTime(pPlayToAssoc->m_id, ulRemoveTime);
- }
- #if defined(HELIX_FEATURE_SMIL2_TRANSITIONS)
- // schedule an end transition if there is one.
- if (pPlayToAssoc->m_endTransition.GetLength() > 0 &&
- !pPlayToAssoc->m_bLiveSource)
- {
- CSmilTransitionInfo* pTInfo = getTransition(
- pPlayToAssoc->m_endTransition);
- if (pTInfo)
- {
- CSmilTransitionEvent* pTransEvent =
- new CSmilTransitionEvent(
- pPlayToAssoc->m_ulDelay + pPlayToAssoc->m_ulDuration - pTInfo->m_pTrans->m_ulDuration,
- pPlayToAssoc, pSite, FALSE, this);
- insertEvent(pTransEvent);
- }
- }
- #endif /* #if defined(HELIX_FEATURE_SMIL2_TRANSITIONS) */
- }
- }
- return rc;
- }
- STDMETHODIMP CSmilDocumentRenderer::SiteUserAttachSite(CSmilSiteUser* pUser, IHXSite* pSite)
- {
- HX_RESULT retVal = HXR_OK;
- if (pUser && pSite)
- {
- if (m_pRootLayout &&
- m_pRootLayout->m_pSiteUser == pUser)
- {
- MLOG_LAYOUT(m_pErrorMessages,
- "root-layout AttachSite() m_ulCurrentTime=%lu tick=%lun",
- m_ulCurrentTime, HX_GET_BETTERTICKCOUNT());
- // Save the top-level site
- HX_RELEASE(m_pRootLayout->m_pSite);
- m_pRootLayout->m_pSite = pSite;
- m_pRootLayout->m_pSite->AddRef();
- // Create a passive site watcher object for
- // the top-level site
- HX_DELETE(m_pRootLayout->m_pPassiveSiteWatcher);
- m_pRootLayout->m_pPassiveSiteWatcher =
- new CSmilPassiveSiteWatcher((CSmilPassiveSiteWatcherResponse*) this,
- m_pRootLayout->m_pSite);
- if (m_pRootLayout->m_pPassiveSiteWatcher)
- {
- m_pRootLayout->m_pPassiveSiteWatcher->AddRef();
- }
- // Set the size of the top-level site
- setTopLevelSiteSize();
- // Clear the flag saying we've detached the root-layout site
- m_bRootLayoutSiteDetached = FALSE;
- }
- #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT)
- else
- {
- // Check and see if this is a viewport
- CSmilBasicViewport* pPort = getViewportBySiteUser(pUser);
- if (pPort)
- {
- // Save the site
- HX_RELEASE(pPort->m_pSite);
- pPort->m_pSite = pSite;
- pPort->m_pSite->AddRef();
- // Set the position
- HXxPoint cPos = {0, 0};
- pPort->m_pSite->SetPosition(cPos);
- // Set the size
- HXxSize cSize = {HXxRECT_WIDTH(pPort->m_Rect),
- HXxRECT_HEIGHT(pPort->m_Rect)};
- #if defined(XXXMEH_DO_VIEWPORT_TLC) && defined(_WINDOWS)
- cSize.cx += GetSystemMetrics(SM_CXFIXEDFRAME) * 2;
- cSize.cy += GetSystemMetrics(SM_CYFIXEDFRAME) * 2 +
- GetSystemMetrics(SM_CYCAPTION);
- #endif
- pPort->m_pSite->SetSize(cSize);
- // Create a passive site watcher object for
- // the top-level site
- HX_DELETE(pPort->m_pPassiveSiteWatcher);
- pPort->m_pPassiveSiteWatcher =
- new CSmilPassiveSiteWatcher((CSmilPassiveSiteWatcherResponse*) this,
- pPort->m_pSite);
- if (pPort->m_pPassiveSiteWatcher)
- {
- pPort->m_pPassiveSiteWatcher->AddRef();
- }
- // Now we need to finish the setup for this viewport
- retVal = finishOneViewportSetup(pPort);
- }
- }
- #endif /* #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT) */
- }
- else
- {
- retVal = HXR_FAIL;
- }
- return retVal;
- }
- STDMETHODIMP CSmilDocumentRenderer::SiteUserDetachSite(CSmilSiteUser* pUser)
- {
- HX_RESULT retVal = HXR_OK;
- BOOL bNeedToRelease = FALSE;
- if (pUser)
- {
- // Determine if this is a root
- if (m_pRootLayout &&
- m_pRootLayout->m_pSiteUser == pUser)
- {
- // Destroy the renderer sites of those renderers playing
- // to regions which are under the root-layout. This also
- // deletes the corresponding site watchers as well.
- destroyRendererSites(m_pRootLayout);
- // Properly destroy the parent-child relationships -
- // this makes sure that the proper parent calls
- // DestroyChild(), but it does not delete the CSmilBasicRegion
- // itself, since the region map owns that.
- destroyRegionSites(m_pRootLayout->m_pChildList);
- // keep the region info around so that all layout/region/renderer
- // sites can be re-created during nested meta playlist navigation
- if (m_bCloseCalled ||
- (m_pParent && !m_pParent->m_bUseNestedMeta))
- {
- // Now destroy the CSmilBasicRegion's which
- // are under the root-layout
- destroyRegions(m_pRootLayout->m_pChildList);
- }
- // Close the root layout's passive site watcher. This
- // causes it to release its ref on us.
- if (m_pRootLayout->m_pPassiveSiteWatcher)
- {
- m_pRootLayout->m_pPassiveSiteWatcher->Close();
- }
- // Remove the site user as a layout group
- if (m_pRootLayout->m_pSiteUser && m_pParent)
- {
- IUnknown* pThisUnk = NULL;
- m_pRootLayout->m_pSiteUser->QueryInterface(IID_IUnknown, (void**) &pThisUnk);
- if (pThisUnk)
- {
- m_pParent->HandleRemoveLayoutSiteGroup(pThisUnk);
- }
- HX_RELEASE(pThisUnk);
- }
- // Close the root layout's site user. This causes it
- // to release its ref on us. So before we do that,
- // we AddRef() ourselves and we will release ourselves
- // directly below.
- AddRef();
- bNeedToRelease = TRUE;
- // Close the root-layout's site user
- if (m_pRootLayout->m_pSiteUser)
- {
- m_pRootLayout->m_pSiteUser->Close();
- }
- // Release the top-level site
- HX_RELEASE(m_pRootLayout->m_pSite);
- // Delete the root-layout ONLY if close
- // has been called. If close has been called, then
- // this is the last line of defense.
- if (m_bCloseCalled)
- {
- HX_DELETE(m_pRootLayout);
- }
- // Set the flag saying we've detached the root-layout site
- m_bRootLayoutSiteDetached = TRUE;
- #ifdef _MACINTOSH
- if (m_bResetCursor)
- {
- m_bResetCursor = FALSE;
- ::InitCursor();
- }
- #endif
- }
- #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT)
- else
- {
- // Is this a DetachSite() for one of the viewports?
- CSmilBasicViewport* pPort = getViewportBySiteUser(pUser);
- if (pPort)
- {
- // Destroy the renderer sites of those renderers playing
- // to regions which are under this viewport. This also
- // deletes the corresponding site watchers as well.
- destroyRendererSites(pPort);
- // Properly destroy the parent-child relationships -
- // this makes sure that the proper parent calls
- // DestroyChild(), but it does not delete the CSmilBasicRegion
- // itself, since the region map owns that.
- destroyRegionSites(pPort->m_pChildList);
- // Now destroy the CSmilBasicRegion's which
- // are under this viewport
- destroyRegions(pPort->m_pChildList);
- // Close this viewport's passive site watcher. This
- // causes it to release its ref on us.
- if (pPort->m_pPassiveSiteWatcher)
- {
- pPort->m_pPassiveSiteWatcher->Close();
- }
- // Close this viewport's site user
- if (pPort->m_pSiteUser)
- {
- pPort->m_pSiteUser->Close();
- }
- // Release this viewport's site
- HX_RELEASE(pPort->m_pSite);
- }
- }
- #endif /* #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT) */
- }
- else
- {
- retVal = HXR_FAIL;
- }
- m_bSitesDetached = TRUE;
- if (bNeedToRelease)
- {
- Release();
- }
-
- return retVal;
- }
- STDMETHODIMP CSmilDocumentRenderer::SiteUserHandleEvent(CSmilSiteUser* pUser,
- HXxEvent* pEvent)
- {
- HX_RESULT retVal = HXR_OK;
- if (pUser && pEvent)
- {
- switch (pEvent->event)
- {
- case HX_SET_FOCUS:
- {
- pEvent->handled = TRUE;
- }
- break;
- case HX_LOSE_FOCUS:
- {
- pEvent->handled = TRUE;
- }
- break;
- case HX_CHAR:
- {
- UINT16 uCharPressed = (UINT16) (UINT32)pEvent->param1;
- // XXXEH: TODO: Handle this: "The character is a single
- // character from [[ISO10646]]."
- retVal = HandleCharEvent(uCharPressed);
- if (SUCCEEDED(retVal))
- {
- // XXXMEH - we will no longer claim that we handle
- // keystrokes. This will allow renderers such as
- // flash to get the keystrokes for forms, etc.
- pEvent->handled = FALSE;
- }
- }
- break;
- #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT)
- #ifdef XXXMEH_DO_VIEWPORT_TLC
- case HX_DETACH_WINDOW:
- {
- // This message could be the result of either: a) the
- // user closing the viewport window; or b) the SMIL renderer
- // shutting down. If this is the result of the SMIL renderer
- // shutting down, then the SMIL renderer has ALREADY called
- // IHXViewPortManager::CloseViewPort(), so we should not call
- // it again. However, if this is the result of the user
- // closing the viewport window, then we need to call
- // CloseViewPort.
- if (!m_bSMILViewportClose)
- {
- // Are we a viewport?
- CSmilBasicViewport* pPort = getViewportBySiteUser(pUser);
- if (pPort && m_pViewPortManager)
- {
- // We are getting a viewport close, so close the viewport
- retVal = m_pViewPortManager->CloseViewPort(pPort->m_id);
- if (SUCCEEDED(retVal))
- {
- pEvent->handled = TRUE;
- }
- }
- }
- }
- break;
- #if defined(_WINDOWS)
- case WM_SETFOCUS:
- {
- // Are we a viewport?
- CSmilBasicViewport* pPort = getViewportBySiteUser(pUser);
- if (pPort && m_pViewPortManager)
- {
- // Get the viewport
- IHXViewPort* pVP = NULL;
- retVal = m_pViewPortManager->GetViewPort(pPort->m_id, pVP);
- if (SUCCEEDED(retVal))
- {
- retVal = pVP->SetFocus();
- }
- HX_RELEASE(pVP);
- }
- }
- break;
- case WM_SIZING:
- {
- HXxRect cRect = {0, 0, 0, 0};
- LPRECT pWinRect = (LPRECT) pEvent->param2;
- if (pWinRect)
- {
- cRect.left = pWinRect->left;
- cRect.top = pWinRect->top;
- cRect.right = pWinRect->right;
- cRect.bottom = pWinRect->bottom;
- }
- // Are we a viewport?
- CSmilBasicViewport* pPort = getViewportBySiteUser(pUser);
- if (pPort && pPort->m_pSite)
- {
- HXxSize cOldSize = {0, 0};
- pPort->m_pSite->GetSize(cOldSize);
- HXxSize cSize = {HXxRECT_WIDTH(cRect), HXxRECT_HEIGHT(cRect)};
- if (cSize.cx > 0 && cSize.cy > 0 &&
- (cSize.cx != cOldSize.cx ||
- cSize.cy != cOldSize.cy))
- {
- pPort->m_pSite->SetSize(cSize);
- }
- }
- }
- break;
- #endif // #if defined(_WINDOWS)
- #endif // #ifdef XXXMEH_DO_VIEWPORT_TLC
- #endif /* #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT) */
- default:
- break;
- }
- // Set the result
- if (SUCCEEDED(retVal))
- {
- pEvent->result = retVal;
- }
- }
- else
- {
- retVal = HXR_FAIL;
- }
- return retVal;
- }
- STDMETHODIMP
- CSmilDocumentRenderer::RendererInitialized(IHXRenderer* pRenderer,
- IUnknown* pStream, IHXValues* pInfo)
- {
- HX_RESULT rc = HXR_OK;
- BOOL bIsWindowed = FALSE;
- BOOL bHandleElement = FALSE;
- HX_DISPLAY_TYPE ulFlags;
- IHXBuffer* pBuf = 0;
- if(HXR_OK == pRenderer->GetDisplayType(ulFlags, pBuf))
- {
- if (HX_DISPLAY_WINDOW == (HX_DISPLAY_WINDOW & ulFlags))
- {
- bIsWindowed = TRUE;
- }
- HX_RELEASE(pBuf);
- }
- UINT32 ulGroupIndex = 0;
- UINT32 ulTrackIndex = 0;
- UINT32 ulDelay = 0;
- UINT32 ulDuration = 0;
- UINT32 ulLiveSource = 0;
- pInfo->GetPropertyULONG32("GroupIndex", ulGroupIndex);
- pInfo->GetPropertyULONG32("TrackIndex", ulTrackIndex);
- pInfo->GetPropertyULONG32("Delay", ulDelay);
- // "duration" is really the end time in the current group
- pInfo->GetPropertyULONG32("Duration", ulDuration);
- pInfo->GetPropertyULONG32("LiveSource", ulLiveSource);
- MLOG_SRC(m_pErrorMessages,"RendererInitialized() grp=%lu trk=%lu m_ulCurrentTime=%lu t=%lun",
- ulGroupIndex, ulTrackIndex, m_ulCurrentTime, HX_GET_BETTERTICKCOUNT());
- IHXBuffer* pBuffer = NULL;
- SMILPlayToAssoc* pPlayToAssoc = NULL;
- if (HXR_OK == pInfo->GetPropertyCString("id", pBuffer))
- {
- pPlayToAssoc = getPlayToAssocByMedia((const char*)pBuffer->GetBuffer());
- }
- HX_RELEASE(pBuffer);
- if (!pPlayToAssoc)
- {
- // XXX HP we shouldn't be here
- HX_ASSERT(FALSE);
- pPlayToAssoc = getPlayToAssoc((UINT16)ulGroupIndex, (UINT16)ulTrackIndex);
- }
- UINT16 uStreamNumber = 0;
- IHXStream* pStr = 0;
- if(HXR_OK == pStream->QueryInterface(IID_IHXStream,
- (void**)&pStr))
- {
- uStreamNumber = pStr->GetStreamNumber();
- // Here we want to get the URL and save it
- // in the playToAssoc, so that we can look
- // it up later if necessary
- //
- // QI for IHXStreamSource
- IHXStreamSource* pStreamSource = NULL;
- pStr->GetSource(pStreamSource);
- if (pStreamSource)
- {
- if (pPlayToAssoc)
- {
- pPlayToAssoc->m_URL = pStreamSource->GetURL();
- // If we are a external media marker source, then
- // we need to update our info struct with this url
- if (pPlayToAssoc->m_bXMMSource && m_pExternalMediaMarkerList)
- {
- IHXBuffer* pTB = NULL;
- pInfo->GetPropertyCString("url", pTB);
- if (pTB)
- {
- HX_RELEASE(pTB);
- }
- LISTPOSITION pos = m_pExternalMediaMarkerList->GetHeadPosition();
- while (pos)
- {
- CExternalMediaMarkerInfo* pMInfo =
- (CExternalMediaMarkerInfo*) m_pExternalMediaMarkerList->GetNext(pos);
- if (pMInfo &&
- pMInfo->m_usGroupIndex == (UINT16) ulGroupIndex &&
- pMInfo->m_usTrackIndex == (UINT16) ulTrackIndex)
- {
- HX_VECTOR_DELETE(pMInfo->m_pszRendererURL);
- pMInfo->m_pszRendererURL =
- new char [pPlayToAssoc->m_URL.GetLength() + 1];
- if (pMInfo->m_pszRendererURL)
- {
- strcpy(pMInfo->m_pszRendererURL, pPlayToAssoc->m_URL); /* Flawfinder: ignore */
- break;
- }
- }
- }
- }
- }
- }
- HX_RELEASE(pStreamSource);
- HX_RELEASE(pStr);
- }
- // /Get SMIL layout stream:
- // XXX HP the following if statement will be obsolete after using
- // nested meta logic since m_pPersistentLayoutStream should
- // be set in ::InitPersistent()
- if (!m_pParent->m_bUseNestedMeta && !m_pPersistentLayoutStream)
- {
- if (HXR_OK != pStream->QueryInterface(IID_IHXLayoutStream,
- (void**)&m_pPersistentLayoutStream))
- {
- HX_ASSERT(m_pPersistentLayoutStream);
- }
- }
- CSmilBasicRegion* pRegion = NULL;
- if(bIsWindowed)
- {
- // This is the box at which we need to
- // re-compute the z-order stack
- CSmilBasicBox* pZOrderBox = NULL;
- IHXLayoutStream* pLayoutStream = NULL;
- if(HXR_OK == pStream->QueryInterface(IID_IHXLayoutStream,
- (void**)&pLayoutStream))
- {
- BOOL bNoRegion = TRUE;
- if(pPlayToAssoc)
- {
- CHXSimpleList* pRendererList = NULL;
- SMILSourceInfo* pSourceInfo = NULL;
- const char* pPlayTo = pPlayToAssoc->m_playTo;
- // re-create layout/region/renderer sites if
- // sites have been detached upon playlist navigation
- if (m_bSitesDetached)
- {
- m_bSitesDetached = FALSE;
- rc = setupRootLayout(FALSE);
- HX_ASSERT(HXR_OK == rc);
- }
- // See if we need to layout this renderer
- //
- // First check to see if we have a region by id
- pRegion = getRegionByID(pPlayTo);
- if(pRegion)
- {
- bNoRegion = FALSE;
- // We will need to recompute the z-order
- // stack of this region's parent
- pZOrderBox = getTopLevelBox(pRegion);
- }
- else
- {
- // We didn't find it by id, so try finding
- // a region by regionName
- pRegion = getFirstRegionByName(pPlayTo);
- if (pRegion)
- {
- bNoRegion = FALSE;
- // We will need to recompute the z-order
- // stack of this region's parent
- pZOrderBox = getTopLevelBox(pRegion);
- }
- else
- {
- // We didn't find a <region> by id and we
- // didn't find a <region> by the "regionName"
- // indirection, so we are going to have to
- // fall back to the "default" region.
- pRegion = setupDefaultLayout();
- if (pRegion)
- {
- // Clear the flag
- bNoRegion = FALSE;
- // Change the parameters
- pPlayToAssoc->m_playTo = pRegion->m_region;
- pPlayToAssoc->m_regionName = pRegion->m_region;
- pPlayTo = (const char*) pRegion->m_region;
- // We will need to recompute the z-order
- // stack of this region's parent
- pZOrderBox = getTopLevelBox(pRegion);
- }
- }
- }
- // /vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
- // /XXXEH- To do: this is same code as found inside
- // AttachElementLayout(), below. Combine into single function:
- pSourceInfo = new SMILSourceInfo;
- pSourceInfo->m_pStream = pStream;
- if(pSourceInfo->m_pStream)
- {
- pSourceInfo->m_pStream->AddRef();
- }
- pSourceInfo->m_pRenderer = pRenderer;
- if(pSourceInfo->m_pRenderer)
- {
- pSourceInfo->m_pRenderer->AddRef();
- }
-
- pSourceInfo->m_ulDelay = ulDelay;
- pSourceInfo->m_ulDuration = ulDuration - ulDelay;
- char cTemp[20]; /* Flawfinder: ignore */
- ::sprintf(cTemp,"%#010lx",(ULONG32)(void*)pSourceInfo); /* Flawfinder: ignore */
- pSourceInfo->m_tunerName = (const char*) cTemp;
- ::sprintf(cTemp,"%#010lx",(ULONG32)(void*)pSourceInfo+1); /* Flawfinder: ignore */
- pSourceInfo->m_childTunerName = (const char*)cTemp;
- const char* pChildTuner = pSourceInfo->m_childTunerName;
- // get to the site manager and set an event hook
- IHXEventHookMgr* pHookMgr = NULL;
- if(HXR_OK ==
- m_pSiteMgr->QueryInterface(IID_IHXEventHookMgr,
- (void**)&pHookMgr))
- {
- CSmilEventHook* pChildEventHook = NULL;
- // create event hook for playto
- pChildEventHook = new CSmilEventHook((CSmilEventHookResponse*) this,
- pPlayTo, pChildTuner, bNoRegion,
- (const char*) pPlayToAssoc->m_id);
- pChildEventHook->AddRef();
- pHookMgr->AddHook(pChildEventHook, pChildTuner, 0);
- pSourceInfo->m_pRendererEventHook = pChildEventHook;
- pHookMgr->Release();
- }
- else
- {
- pSourceInfo->m_pRendererEventHook = NULL;
- }
- if (NULL == pPlayToAssoc->m_sourceMap[uStreamNumber])
- {
- pPlayToAssoc->m_sourceMap[uStreamNumber] = new CHXSimpleList();
- pPlayToAssoc->m_tunerName = pSourceInfo->m_tunerName;
- pPlayToAssoc->m_childTunerName = pSourceInfo->m_childTunerName;
- pPlayToAssoc->m_ulDelay = pSourceInfo->m_ulDelay;
- pPlayToAssoc->m_ulDuration = pSourceInfo->m_ulDuration;
- pPlayToAssoc->m_bLiveSource = ulLiveSource ? TRUE : FALSE;
- pPlayToAssoc->m_pRendererEventHook = pSourceInfo->m_pRendererEventHook;
- // add hyperlinks
- CSmilElement* pElement = m_pSmilParser->findElement(
- pPlayToAssoc->m_id);
- if(pElement && pElement->m_pHyperlinks)
- {
- CHXSimpleList::Iterator i =
- pElement->m_pHyperlinks->Begin();
- for(; i != pElement->m_pHyperlinks->End(); ++i)
- {
- CSmilAAnchorElement* pAnchor =
- (CSmilAAnchorElement*)(*i);
- //[SMIL 1.0 Compliance] Fixes PR 26473:
- // We want to add in LIFO fashion so inner
- // (nested) anchors will be found first in
- // CSmilDocumentRenderer::findHyperlinkElement(),
- // below. In other words, we're giving an
- // effective higher link "z-order" to the
- // decendants of other links. This used to
- // call AddTail():
- pPlayToAssoc->m_pHyperlinks->AddHead(pAnchor);
- }
- }
- bHandleElement = TRUE;
- }
- pRendererList = (CHXSimpleList*) pPlayToAssoc->m_sourceMap[uStreamNumber];
- pRendererList->AddTail(pSourceInfo);
- IHXValues* pValues = 0;
- IHXBuffer* pPlayToBuffer = 0;
- IHXBuffer* pRegionName = 0;
- IHXCommonClassFactory* pFactory = m_pParent->getFactory();
- if ((HXR_OK == pFactory->CreateInstance(CLSID_IHXValues, (void**)&pValues)) &&
- (HXR_OK == pFactory->CreateInstance(CLSID_IHXBuffer, (void**)&pPlayToBuffer)) &&
- (HXR_OK == pFactory->CreateInstance(CLSID_IHXBuffer, (void**)&pRegionName)))
- {
- pPlayToBuffer->Set((BYTE*)pChildTuner, strlen(pChildTuner)+1);
- pValues->SetPropertyCString("playto", pPlayToBuffer);
- HX_RELEASE(pPlayToBuffer);
- if(pPlayToAssoc->m_regionName.GetLength() > 0)
- {
- const char* pName = pPlayToAssoc->m_regionName;
- pRegionName->Set((BYTE*)pName, strlen(pName)+1);
- pValues->SetPropertyCString("region", pRegionName);
- }
- HX_RELEASE(pRegionName);
- pLayoutStream->SetProperties(pValues);
- pValues->Release();
- }
- if(!pRegion->m_bImplicitRegion)
- {
- addSiteForRenderer(pPlayToAssoc, pSourceInfo, pRenderer, bNoRegion);
- }
- // /XXXEH- end of "To do: this is same code as...".
- // /^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- }
- }
- // XXXMEH - now we re-adjust the z-order.
- if (pZOrderBox)
- {
- resolveZOrder(pZOrderBox, m_ulCurrentTime);
- }
- HX_RELEASE(pLayoutStream);
- }
- else // non-windowed renderer
- {
- if(pPlayToAssoc)
- {
- SMILSourceInfo* pSourceInfo = NULL;
- CHXSimpleList* pRendererList = NULL;
- if (NULL == pPlayToAssoc->m_sourceMap[uStreamNumber])
- {
- pPlayToAssoc->m_sourceMap[uStreamNumber] = new CHXSimpleList();
- pPlayToAssoc->m_ulDuration = ulDuration - ulDelay;
- bHandleElement = TRUE;
- }
-
- pSourceInfo = new SMILSourceInfo;
- pSourceInfo->m_pStream = pStream;
- if(pSourceInfo->m_pStream)
- {
- pSourceInfo->m_pStream->AddRef();
- }
- pSourceInfo->m_pRenderer = pRenderer;
- if(pSourceInfo->m_pRenderer)
- {
- pSourceInfo->m_pRenderer->AddRef();
- }
- pSourceInfo->m_pRendererEventHook = NULL;
- pSourceInfo->m_ulDelay = ulDelay;
- // /Holy ancient typo, batman!! This was "p->m = ulDur = ulDelay"
- // but it meant to say "p->m = ulDur - [not '='!] ulDelay". Doh!.
- // Ran across this while fixing PR 79699 and this change is needed
- // for PR 81715 crash to happen (otherwise 81715 freezes player):
- pSourceInfo->m_ulDuration = ulDuration - ulDelay;
-
- pRendererList = (CHXSimpleList*) pPlayToAssoc->m_sourceMap[uStreamNumber];
- pRendererList->AddTail(pSourceInfo);
- }
- }
- // We need to set the following parameters into the renderer:
- //
- // SMIL default namespace
- // rn:backgroundOpacity
- // rn:mediaOpacity
- // rn:chromaKey
- // rn:chromaKeyTolerance
- // rn:chromaKeyOpacity
- // any <param> children properties
- //
- if (pPlayToAssoc)
- {
- // QI the renderer for IHXValues
- IHXValues* pRendValues = NULL;
- pRenderer->QueryInterface(IID_IHXValues, (void**) &pRendValues);
- if (pRendValues)
- {
- // Set the default namespace
- if (m_pSMILDefaultNamespaceStr)
- {
- pRendValues->SetPropertyCString("SMILDefaultNamespace",
- m_pSMILDefaultNamespaceStr);
- }
- // Now, if any of the opacity/chromaKey parameters
- // were specified, then we need to set them into the
- // renderer as well.
- //
- // First we need to get the source
- CSmilSource* pSource = getSource(pPlayToAssoc->m_id);
- if (pSource)
- {
- if (pSource->m_bBackgroundOpacitySpecified)
- {
- pRendValues->SetPropertyULONG32("backgroundOpacity",
- pSource->m_ulBackgroundOpacity);
- }
- if (pSource->m_bMediaOpacitySpecified)
- {
- pRendValues->SetPropertyULONG32("mediaOpacity",
- pSource->m_ulMediaOpacity);
- }
- if (pSource->m_bChromaKeySpecified)
- {
- pRendValues->SetPropertyULONG32("chromaKey",
- pSource->m_ulChromaKey);
- pRendValues->SetPropertyULONG32("chromaKeyTolerance",
- pSource->m_ulChromaKeyTolerance);
- pRendValues->SetPropertyULONG32("chromaKeyOpacity",
- pSource->m_ulChromaKeyOpacity);
- }
- // /To help fix PR 59951 (SMIL part of the fix), we need to
- // notify the renderer what the region width and height is;
- // that allows the renderer to resize its internal window to
- // fill its region if it has no intrinsic width or height:
- ULONG32 ulDisplayAreaWidth = 0;
- ULONG32 ulDisplayAreaHeight = 0;
- if (pSource->m_region.GetLength()>0 && pRegion)
- {
- ulDisplayAreaWidth = // /Region size:
- pRegion->m_rect.right - pRegion->m_rect.left;
- ulDisplayAreaHeight = // /Region size:
- pRegion->m_rect.bottom - pRegion->m_rect.top;
- }
- // /However, if the media element has a "width" attribute
- // set, we should use it instead:
- if (pSource->m_Rect.m_dWidth > 0)
- {
- ulDisplayAreaWidth = pSource->m_Rect.m_dWidth;
- }
- // /Same for if the media element has a "height" attribute
- // set; we should use it instead:
- if (pSource->m_Rect.m_dHeight > 0)
- {
- ulDisplayAreaHeight = pSource->m_Rect.m_dHeight;
- }
- // /Now, notify the renderer what size its display area is:
- if (ulDisplayAreaWidth > 0)
- {
- pRendValues->SetPropertyULONG32("regionWidth",
- ulDisplayAreaWidth);
- }
- if (ulDisplayAreaHeight > 0)
- {
- pRendValues->SetPropertyULONG32("regionHeight",
- ulDisplayAreaHeight);
- }
- // Add any param children (if there are any)
- // Note that these will be added as CString properties,
- // rather than ULONG32 properties as the opacity properties
- // Also note that the FALSE arguments below mean that
- // we will pass ALL <param> children to the client, regardless
- // of whether they have rn:delivery="server" or rn:delivery="client"
- if (hasParamChildren(pSource, FALSE))
- {
- addParamProperties(pSource,
- pRendValues,
- m_pContext,
- FALSE);
- }
- }
- }
- HX_RELEASE(pRendValues);
- IHXPersistentRenderer* pPersistentRenderer = NULL;
- if (HXR_OK == pRenderer->QueryInterface(IID_IHXPersistentRenderer, (void**)&pPersistentRenderer))
- {
- pPlayToAssoc->m_bIsPersistentSource = TRUE;
- }
- HX_RELEASE(pPersistentRenderer);
- }
- // Set up listening for external events coming from this
- // renderer, if there are any
- if (m_pSmilParser && pPlayToAssoc)
- {
- // Are there any external events associated with
- // this renderer?
- if (m_pSmilParser->anyExternalEvents(pPlayToAssoc->m_id))
- {
- // We do have some external events, so first we
- // need to set up the SMIL renderer as an event sink,
- // if it is not already
- if (!m_bEventSinkWasSetup)
- {
- // TRUE adds us, FALSE removes us
- addRemoveEventSink(TRUE);
- }
- // Loop through the external events based off
- // of this renderer, and add filter rules based on
- // each event.
- ExternalEventInfo* pInfo =
- m_pSmilParser->getFirstExternalEvent(pPlayToAssoc->m_id);
- while (pInfo)
- {
- // Add a rule for this external event
- addEventSinkFilterRule(pPlayToAssoc->m_URL, NULL,
- pInfo->m_PrefixedEventName);
- // Get the next external event
- pInfo = m_pSmilParser->getNextExternalEvent(pPlayToAssoc->m_id);
- }
- }
- }
- // update the stream timing if it's been called in handleSourceUpdate()
- if(m_pDeferredSourceMap)
- {
- SMILDeferredSourceInfo* pDeferredInfo = NULL;
- const char* pDeferredID = (const char*)pPlayToAssoc->m_id;
- if(m_pDeferredSourceMap->Lookup(pDeferredID,
- (void*&)pDeferredInfo))
- {
- CSmilElement* pThisElement =
- m_pSmilParser->findElement(pDeferredID);
- #if 0 /* Remove: it's causing problems for discrete media updates
- * like PR 69780 & PR 79748 (which worked OK on 20020618 but
- * was broken (elsewhere in the code) after that:
- */
- if(pThisElement &&
- pThisElement->m_bBeginOffsetSet)
- {
- if((INT32)pDeferredInfo->m_ulDuration > pThisElement->m_lBeginOffset)
- {
- updateStreamTiming(pDeferredID,
- #if 0 /*Remove: it's causing problems for non-neg begin cases like PR 79699: */
- (UINT32)((INT32)pDeferredInfo->m_ulDuration -
- // /Fixes Timing Interop cases, including 1.33,
- // prev_begin_in_a_par6.smil, which was playing 2 sec
- // too long due to -2 sec beginOffset being used here
- (pThisElement->m_lBeginOffset<0?
- 0:pThisElement->m_lBeginOffset) ) );
- #else
- (UINT32)((INT32)pDeferredInfo->m_ulDuration) );
- #endif
- }
- else
- {
- updateStreamTiming(pDeferredID, 0);
- }
- }
- else
- #endif
- {
- updateStreamTiming(pDeferredID, pDeferredInfo->m_ulDuration);
- }
- }
- }
- if (pPlayToAssoc)
- {
- const char* pID = (const char*)pPlayToAssoc->m_id;
- {
- CSmilElement* pThisElement = m_pSmilParser->findElement(pID);
- if (pThisElement)
- {
- // /make sure we don't reset the stream's duration or delay
- // if the renderer isn't init'd yet (PR 62688-case2) & others:
- // /DOH!! Somehow, I checked the following without "= TRUE",
- // causing PR 59851 to fail. Fixes PR 59851 once again:
- pThisElement->m_bRendererInitialized = TRUE;
- }
- }
- }
- // Add this renderer to the media ID -> renderer map
- if (pPlayToAssoc && pRenderer)
- {
- addRendererToMap((const char*) pPlayToAssoc->m_id, pRenderer);
- }
- // If this renderer specifies an event handler, OR this renderer IS
- // an event handler for another renderer, then setup the event pipe
- if (pPlayToAssoc)
- {
- // Get this media's id
- const char* pszID = (const char*) pPlayToAssoc->m_id;
- // Look up the element
- CSmilElement* pEl = m_pSmilParser->findElement(pszID);
- if (pEl && pEl->m_pNode)
- {
- // Cast to a source
- CSmilSource* pSrc = (CSmilSource*) pEl;
- // Does this media specify a handler or is
- // this media a handler?
- if (pSrc->m_HandlerID.GetLength() > 0)
- {
- // This media specifies a handler
- setupEventPipe((const char*) pEl->m_pNode->m_id,
- (const char*) pSrc->m_HandlerID,
- NULL);
- }
- else if (pSrc->m_HandlerFor.GetLength() > 0)
- {
- // This media IS a handler
- setupEventPipe((const char*) pSrc->m_HandlerFor,
- (const char*) pEl->m_pNode->m_id,
- NULL);
- }
- }
- }
- if (bHandleElement)
- {
- handleElements();
- }
- return HXR_OK;
- }
- #if defined(_UNIX) && (!(defined(_BEOS))) && defined(USE_XWINDOWS)
- XData* CSmilDocumentRenderer::InitXVisualSupport(IHXSite* pSite, HXxWindow* pWnd)
- {
- // create new XData object
- XData* pxData = new XData();
- // use the pointer to the X display and window
- // conveniently given us by CHXSiteWindowed::HandleEvent
- m_pPixmapDisplay = (Display*) pWnd->display;
- Window window = (Window) pWnd->window;
- // save ptr to display in XData object also...
- pxData->m_Display = m_pPixmapDisplay;
- // get visual & set m_depth
- XWindowAttributes attr;
- XLockDisplay(m_pPixmapDisplay);
- XGetWindowAttributes(m_pPixmapDisplay, window, &attr);
- XUnlockDisplay(m_pPixmapDisplay);
- // get visual info & depth
- XVisualInfo visInfoMask;
- memset(&visInfoMask, 0, sizeof(XVisualInfo));
- visInfoMask.visualid = attr.visual->visualid;
- if (m_pVisualInfo)
- {
- XFree(m_pVisualInfo);
- m_pVisualInfo = NULL;
- }
- int nv;
- XLockDisplay(m_pPixmapDisplay);
- m_pVisualInfo = XGetVisualInfo(m_pPixmapDisplay, VisualIDMask, &visInfoMask, &nv);
- XUnlockDisplay(m_pPixmapDisplay);
- UINT32 nDepth = 32;
- nDepth = (UINT32)m_pVisualInfo->depth;
- pxData->m_colormap = attr.colormap;
- // get bits per pixel information for the best depth we can display
- ULONG32 bitsPerPixel = 32;
- int i, n;
- XLockDisplay(m_pPixmapDisplay);
- XPixmapFormatValues *pixmap_formats = XListPixmapFormats(m_pPixmapDisplay, &n);
- XUnlockDisplay(m_pPixmapDisplay);
- if (pixmap_formats)
- {
- for (i = 0; i < n; i++)
- {
- if (pixmap_formats[i].depth == nDepth)
- {
- bitsPerPixel = pixmap_formats[i].bits_per_pixel;
- }
- }
- }
- XFree(pixmap_formats);
- // get site size
- HXxSize siteWinSize;
- pSite->GetSize(siteWinSize);
- pxData->m_backgroundBitmapInfoHeader.biSize = sizeof(HXBitmapInfoHeader);
- pxData->m_backgroundBitmapInfoHeader.biWidth = siteWinSize.cx;
- pxData->m_backgroundBitmapInfoHeader.biHeight = siteWinSize.cy;
- pxData->m_backgroundBitmapInfoHeader.biPlanes = 1; // just seems to be the convention
- pxData->m_backgroundBitmapInfoHeader.biBitCount = bitsPerPixel;
- HX_ASSERT(pxData->m_backgroundBitmapInfoHeader.biBitCount % 8 == 0);
- // BI_RGB just seems to be the convention
- switch (pxData->m_backgroundBitmapInfoHeader.biBitCount)
- {
- case 8:
- case 24:
- case 32:
- pxData->m_backgroundBitmapInfoHeader.biCompression = BI_RGB;
- break;
- case 16:
- pxData->m_backgroundBitmapInfoHeader.biCompression = HXCOLOR_RGB565_ID;
- break;
- default:
- HX_ASSERT(FALSE);
- }
- pxData->m_backgroundBitmapInfoHeader.biSizeImage = //size of image (bytes):
- pxData->m_backgroundBitmapInfoHeader.biWidth * pxData->m_backgroundBitmapInfoHeader.biHeight *
- pxData->m_backgroundBitmapInfoHeader.biBitCount;
- pxData->m_backgroundBitmapInfoHeader.biXPelsPerMeter = 0;
- pxData->m_backgroundBitmapInfoHeader.biYPelsPerMeter = 0;
- pxData->m_backgroundBitmapInfoHeader.biClrUsed = 0;
- pxData->m_backgroundBitmapInfoHeader.biClrImportant = 0;
- pxData->m_backgroundBitmapInfoHeader.rcolor = m_pVisualInfo->red_mask;
- pxData->m_backgroundBitmapInfoHeader.gcolor = m_pVisualInfo->green_mask;
- pxData->m_backgroundBitmapInfoHeader.bcolor = m_pVisualInfo->blue_mask;
- XLockDisplay(m_pPixmapDisplay);
- pxData->m_Pixmap = XCreatePixmap(m_pPixmapDisplay,
- window,
- pxData->m_backgroundBitmapInfoHeader.biWidth,
- pxData->m_backgroundBitmapInfoHeader.biHeight,
- nDepth);
- XUnlockDisplay(m_pPixmapDisplay);
- return pxData;
- }
- #endif
- #if defined(_DEBUG)
- void CSmilDocumentRenderer::DumpEventQueue()
- {
- MLOG_EVENT(m_pErrorMessages,
- "======================================================n"
- "Event Queue at %lu Current Group %d (%lu events):n"
- " type time grp ohs ignn",
- m_ulCurrentTime, m_uCurrentGroupIndex,
- (m_pEventList? m_pEventList->GetCount() : 0));
- if (m_pEventList)
- {
- LISTPOSITION pos = m_pEventList->GetHeadPosition();
- while(pos)
- {
- CSmilLayoutEvent* pEvent =
- (CSmilLayoutEvent*) m_pEventList->GetNext(pos);
- if (pEvent)
- {
- MLOG_EVENT(m_pErrorMessages,
- "%16s %7lu %1u %1lu %1lu",
- pEvent->getEventTypeName(),
- pEvent->m_ulEventTime,
- pEvent->m_uGroupIndex,
- pEvent->m_bOnlyHideSite,
- pEvent->m_bIgnorEvent);
- switch (pEvent->m_type)
- {
- case CSmilLayoutEvent::eShowSite:
- case CSmilLayoutEvent::eHideSite:
- {
- CSmilShowSiteEvent* pShow = (CSmilShowSiteEvent*) pEvent;
- MLOG_EVENT(m_pErrorMessages,
- "tmedia=%stregion=%sn",
- pShow->getMediaID(),
- pShow->getRegionID());
- }
- break;
- default:
- MLOG_EVENT(m_pErrorMessages, "n");
- }
- }
- }
- }
- MLOG_EVENT(m_pErrorMessages,
- "======================================================n");
- }
- void CSmilDocumentRenderer::DumpZOrder(CSmilBasicBox* pBox, UINT32 ulIndentLevel)
- {
- if (pBox)
- {
- for (UINT32 i = 0; i < ulIndentLevel; i++)
- {
- MLOG_LAYOUT(m_pErrorMessages, "t");
- }
- BOOL bIsRoot = (pBox->m_pParent == NULL ? TRUE : FALSE);
- const char* pszName = NULL;
- if (bIsRoot)
- {
- pszName = "root";
- }
- else
- {
- CSmilBasicRegion* pReg = (CSmilBasicRegion*) pBox;
- pszName = (const char*) pReg->m_region;
- }
- MLOG_LAYOUT(m_pErrorMessages, "site=0x%08xt(%s)tzOrder=%ldn",
- pBox->m_pSite, pszName, getSiteZIndex(pBox->m_pSite));
- // Dump children
- if (pBox->m_pChildList)
- {
- LISTPOSITION pos = pBox->m_pChildList->GetHeadPosition();
- while (pos)
- {
- CSmilBasicBox* pChildBox = (CSmilBasicBox*) pBox->m_pChildList->GetNext(pos);
- DumpZOrder(pChildBox, ulIndentLevel + 1);
- }
- }
- }
- }
- void CSmilDocumentRenderer::DumpAllGroupInfo(UINT32 ulTime)
- {
- if (m_pParent)
- {
- IHXPlayer* pPlayer = m_pParent->getPlayer();
- if (pPlayer)
- {
- IHXGroupManager* pGroupManager = NULL;
- pPlayer->QueryInterface(IID_IHXGroupManager, (void**) &pGroupManager);
- if (pGroupManager)
- {
- MLOG_SRC(m_pErrorMessages,"Group Information Dump at %lu:n", ulTime);
- UINT16 usNumGroups = pGroupManager->GetGroupCount();
- UINT16 usCurGroup = 0;
- pGroupManager->GetCurrentGroup(usCurGroup);
- MLOG_SRC(m_pErrorMessages,"tNumber of Groups: %un", usNumGroups);
- MLOG_SRC(m_pErrorMessages,"tCurrent Group: %un", usCurGroup);
- for (UINT16 i = 0; i < usNumGroups; i++)
- {
- IHXGroup* pGroup = NULL;
- pGroupManager->GetGroup(i, pGroup);
- if (pGroup)
- {
- MLOG_SRC(m_pErrorMessages,"tGroup %u Info:n", i);
- UINT16 usNumTracks = pGroup->GetTrackCount();
- MLOG_SRC(m_pErrorMessages,"ttNumber of Tracks: %un", usNumTracks);
- MLOG_SRC(m_pErrorMessages,"ttGroup Properties:n");
- IHXValues* pGrpProp = pGroup->GetGroupProperties();
- if (pGrpProp)
- {
- DumpAllProperties(pGrpProp, 3);
- }
- HX_RELEASE(pGrpProp);
- // Dump track properties
- for (UINT16 j = 0; j < usNumTracks; j++)
- {
- IHXValues* pTrackValues = NULL;
- pGroup->GetTrack(j, pTrackValues);
- if (pTrackValues)
- {
- MLOG_SRC(m_pErrorMessages,"ttTrack %u Properties:n", j);
- DumpAllProperties(pTrackValues, 3);
- }
- HX_RELEASE(pTrackValues);
- }
- }
- HX_RELEASE(pGroup);
- }
- }
- HX_RELEASE(pGroupManager);
- }
- }
- }
- void CSmilDocumentRenderer::DumpAllProperties(IHXValues* pValues, UINT32 ulNumTabIndent)
- {
- if (pValues)
- {
- // Dump CString properties
- // char szDbgStr[256];
- UINT32 i = 0;
- IHXBuffer* pValue = NULL;
- const char* pszName = NULL;
- HX_RESULT rv = pValues->GetFirstPropertyCString(pszName, pValue);
- while (SUCCEEDED(rv))
- {
- // for (i = 0; i < ulNumTabIndent; i++) DEBUGPRINTF(szDbgStr, "t");
- // DEBUGPRINTF(szDbgStr, "%s = %sn", pszName,
- // (const char*) pValue->GetBuffer());
- HX_RELEASE(pValue);
- rv = pValues->GetNextPropertyCString(pszName, pValue);
- }
- // Dump ULONG32 properties
- UINT32 ulValue = 0;
- rv = pValues->GetFirstPropertyULONG32(pszName, ulValue);
- while (SUCCEEDED(rv))
- {
- // for (i = 0; i < ulNumTabIndent; i++) DEBUGPRINTF(szDbgStr, "t");
- // DEBUGPRINTF(szDbgStr, "%s = %lun", pszName, ulValue);
- HX_RELEASE(pValue);
- rv = pValues->GetNextPropertyULONG32(pszName, ulValue);
- }
- // Dump Buffer properties
- rv = pValues->GetFirstPropertyBuffer(pszName, pValue);
- while (SUCCEEDED(rv))
- {
- // for (i = 0; i < ulNumTabIndent; i++) DEBUGPRINTF(szDbgStr, "t");
- // DEBUGPRINTF(szDbgStr, "%s = ", pszName);
- UINT32 ulSize = pValue->GetSize();
- BYTE* pBuf = pValue->GetBuffer();
- for (i = 0; i < ulSize; i++)
- {
- // DEBUGPRINTF(szDbgStr, "%02X ", pBuf[i]);
- }
- // DEBUGPRINTF(szDbgStr, "n");
- HX_RELEASE(pValue);
- rv = pValues->GetNextPropertyBuffer(pszName, pValue);
- }
- }
- }
- void CSmilDocumentRenderer::DumpAllSiteInfo(const char* pszFileName, UINT32 ulTime)
- {
- if (pszFileName)
- {
- FILE* fp = fopen(pszFileName, "a");
- if (fp)
- {
- fprintf(fp, "======================================================n");
- fprintf(fp, "Dumping all site info at time %lu:nn", ulTime);
- DumpBoxSiteInfo(m_pRootLayout, fp, 0);
- fprintf(fp, "======================================================n");
- fclose(fp);
- }
- }
- }
- void CSmilDocumentRenderer::DumpBoxSiteInfo(CSmilBasicBox* pBox, FILE* fp, UINT32 ulIndentLevel)
- {
- if (pBox && fp && ulIndentLevel < 64)
- {
- // Set up indent string
- char szIndent[64]; /* Flawfinder: ignore */
- for (UINT32 i = 0; i < ulIndentLevel; i++) szIndent[0] = 't';
- szIndent[ulIndentLevel] = ' ';
- // Dump info on this box itself
- //
- // Is this box a root?
- if (pBox->m_pParent)
- {
- // It has a parent, so it can't be a root -
- // it must be a region
- CSmilBasicRegion* pRegion = (CSmilBasicRegion*) pBox;
- fprintf(fp, "%sDumping site info for region %s:n",
- szIndent, (const char*) pRegion->m_region);
- }
- else
- {
- // No parent, so it is a root
- fprintf(fp, "%sDumping site info for root box:n", szIndent);
- }
- // Dump the info on this box's site
- HXxSize cSize = {0, 0};
- HXxPoint cPos = {0, 0};
- if (pBox->m_pSite)
- {
- pBox->m_pSite->GetSize(cSize);
- pBox->m_pSite->GetPosition(cPos);
- }
- fprintf(fp, "%stsize=(%ld,%ld) pos=(%ld,%ld) vis=%lu z-index=%ldn",
- szIndent, cSize.cx, cSize.cy, cPos.x, cPos.y,
- isSiteVisible(pBox->m_pSite), getSiteZIndex(pBox->m_pSite));
- // Dump info on this box's renderer sites
- if (pBox->m_pChildRendererSiteList)
- {
- fprintf(fp, "%strenderer children sites:n", szIndent);
- LISTPOSITION pos = pBox->m_pChildRendererSiteList->GetHeadPosition();
- while (pos)
- {
- IHXSite* pChildRendSite =
- (IHXSite*) pBox->m_pChildRendererSiteList->GetNext(pos);
- if (pChildRendSite)
- {
- pChildRendSite->GetSize(cSize);
- pChildRendSite->GetPosition(cPos);
- CHXString cMediaID("unknown");
- getMediaIDFromSite(pChildRendSite, cMediaID);
- fprintf(fp, "%sttid=%s size=(%ld,%ld) pos=(%ld,%ld) vis=%lu z-index=%ldn",
- szIndent, (const char*) cMediaID,
- cSize.cx, cSize.cy, cPos.x, cPos.y,
- isSiteVisible(pChildRendSite),
- getSiteZIndex(pChildRendSite));
- }
- }
- }
- // Now recursively force updates on any children
- if (pBox->m_pChildList)
- {
- fprintf(fp, "%stbox children:n", szIndent);
- LISTPOSITION pos = pBox->m_pChildList->GetHeadPosition();
- while (pos)
- {
- CSmilBasicBox* pChildBox =
- (CSmilBasicBox*) pBox->m_pChildList->GetNext(pos);
- DumpBoxSiteInfo(pChildBox, fp, ulIndentLevel + 1);
- }
- }
- }
- }
- #endif // #if defined(_DEBUG)
- HX_RESULT CSmilDocumentRenderer::getMediaIDFromSite(IHXSite* pSite,
- REF(CHXString) rcStr)
- {
- HX_RESULT retVal = HXR_FAIL;
- if (pSite && m_pSiteWatcherMap)
- {
- void* pVoid = NULL;
- if (m_pSiteWatcherMap->Lookup(pSite, pVoid) && pVoid)
- {
- CSmilSiteWatcher* pWatcher = (CSmilSiteWatcher*) pVoid;
- retVal = HXR_OK;
- rcStr = pWatcher->GetSourceID();
- }
- }
- return retVal;
- }
- void CSmilDocumentRenderer::queueSiteForAnimationRedraw(IHXSite* pSite)
- {
- if (pSite && m_pAnimSiteRedrawMap)
- {
- m_pAnimSiteRedrawMap->SetAt((void*) pSite, (void*) pSite);