basesite.cpp

来自「symbian 下的helix player源代码」· C++ 代码 · 共 2,191 行 · 第 1/5 页

CPP
2,191
字号
    HXxPoint* pOrigin = GetOrigin();

    //Crop
    if( rect.left < 0 )
        rect.left = 0;
    if( rect.top < 0 )
        rect.top = 0;
    if( rect.right > m_size.cx )
        rect.right = m_size.cx;
    if( rect.bottom > m_size.cy )
        rect.bottom = m_size.cy;

    //Translate rect to window coordinates.
    rect.left   += pOrigin->x;
    rect.right  += pOrigin->x;
    rect.top    += pOrigin->y;
    rect.bottom += pOrigin->y;

    rectTmp.x      = (short)rect.left;
    rectTmp.y      = (short)rect.top;
    rectTmp.width  = (short)(rect.right-rect.left);
    rectTmp.height = (short)(rect.bottom-rect.top);

    HXUnionRectWithRegion( &rectTmp, m_pDirtyRegion, m_pDirtyRegion);

    //Do OS specific stuff here.
    _DamageRect(rect);
#if defined(_MACINTOSH) || defined(_MAC_UNIX)
    _TLSUnlock();
#endif
    return HXR_OK;
}

//This is the same as DamageRect except that the coordinates are in
//Window relative coords and we don't do the OS specific stuff (like
//no invalidateRect.
void CHXBaseSite::DamageRectWindowRel(HXxRect rect)
{
    HXxPoint* pPosition = GetOrigin();

    //Crop
    HXREGION* pReg = HXCreateRectRegion( rect.left,
                                         rect.top,
                                         rect.right-rect.left,
                                         rect.bottom-rect.top
                                         );

    //Find out what part intersects us.
    HXREGION*   pTemp = Transition( pPosition->x, pPosition->y,
                                    pPosition->x + m_size.cx,
                                    pPosition->y + m_size.cy
                                    );
    HXIntersectRegion( pTemp, pReg, pReg );
    if( !HXEmptyRegion(pReg) )
    {
        HXUnionRegion( pReg, m_pDirtyRegion, m_pDirtyRegion);
        // We must call _DamageRect to give windows a chance to see if
        // we are occluded by a drop down menu. If we are, then we
        // have to invalidate the OS rect so Windows does not do a
        // save under.
        HXxRect rectTmp =
            {pTemp->extents.x1, pTemp->extents.y1, pTemp->extents.x2, pTemp->extents.y2};
        _DamageRect(rectTmp);
    }


    HXDestroyRegion( pReg );
    HXDestroyRegion( pTemp );
}


/************************************************************************
 *  Method:
 *    IHXSite::DamageRegion
 */
STDMETHODIMP CHXBaseSite::DamageRegion(HXxRegion region)

{
    HX_ASSERT( "Depricated method, do not use. Use the new damage region." == NULL );

    //This was never used and it was not defined what a HXxRegion was.
    //So, we just have to invalidate the whole site.
    //Users should use the new damage region that takes the cross platform
    //region that actually works.
    HXxRect rect;
    HXREGION* reg = (HXREGION*)region;
    rect.left   = 0;
    rect.top    = 0;
    rect.right  = m_size.cx;
    rect.bottom = m_size.cy;
    return DamageRect( rect );
}

// Method:
//    IHXSite::ForceRedraw
STDMETHODIMP CHXBaseSite::ForceRedraw()
{
    HXxEvent event;
    HXxWindow* hxxWin = GetWindow();

    if( IsCompositionLocked() && m_pVideoSurface->m_nBltMode!=HX_OVERLAY_BLT )
    {
        return HXR_OK;
    }

    // make sure we have a visible window event though this should be
    // computed from the list of rects.
    if (!_ShouldEnterForceRedraw())
    {
        return HXR_OK;
    }

    _TLSLock();

    AddRef();
    memset(&m_UpdateBltStatsRect, 0, sizeof(m_UpdateBltStatsRect));

    if(m_pTopLevelSite->m_bDisableForceRedraw)
    {
        m_pTopLevelSite->m_bDisableForceRedraw = TRUE;
    }
    else
    {
        BOOL bDoIt =
            ((m_bIsVisible && m_pUser && m_Region && !HXEmptyRegion(m_Region)) ||
             (m_AlphaBlendNotifiers.GetCount()!=0 || m_AlphaBlendSites.GetCount()!=0));

        if( bDoIt )
        {
            AboutToBlt();
            event.handled = 0;
            if( m_bUserWantsSubRects )
            {
                if( !HXEmptyRegion(m_pDirtyRegion) )
                {
                    HXxExposeInfo exposeInfo;
                    HXxBoxRegion    dirtRegion;

                    //Construct a dirty rect that is relative to the
                    //site's topleft corner.
                    HXREGION* pTmpReg = HXCreateRegion();
                    HXUnionRegion( pTmpReg, m_pDirtyRegion, pTmpReg );
                    HXOffsetRegion( pTmpReg, -m_topleft.x, -m_topleft.y );

                    // adjust for scrolling; essentially turning off
                    // subrect blitting while scrolling

                    if (GetXSliderPos() || GetYSliderPos())
                    {
			HXREGION* pMe = HXCreateRectRegion( 0,
						0,
						m_size.cx,
						m_size.cy
						);
			HXUnionRegion(pMe, pTmpReg, pTmpReg);
			HXDestroyRegion(pMe);
                    }

                    //Set up the cross platform region.
                    dirtRegion.numRects = pTmpReg->numRects;
                    dirtRegion.rects    = pTmpReg->rects;

                    exposeInfo.extents.left    = pTmpReg->extents.x1;
                    exposeInfo.extents.right   = pTmpReg->extents.x2;
                    exposeInfo.extents.top     = pTmpReg->extents.y1;
                    exposeInfo.extents.bottom  = pTmpReg->extents.y2;
                    exposeInfo.pRegion         = & dirtRegion;
                    exposeInfo.pWindow         = GetWindow();
                    exposeInfo.pParam1         = NULL;
                    exposeInfo.pParam2         = NULL;

                    event.event   = HX_SURFACE_UPDATE2;
                    event.window  = hxxWin?hxxWin->window : NULL;
                    event.param1  = m_pVideoSurface;
                    event.param2  = &exposeInfo;
                    event.result  = 0;
                    event.handled = 0;

                    // Clear the dirty region
                    HXZeroOutRegion( m_pDirtyRegion );

                    if( m_pUser )
                    {
                        if (!m_bDoNotGenerateWMPPaint)
                        {
                            m_bInForceRedraw = m_bSiteRefresh;
                            m_pUser->HandleEvent(&event);
                            m_bInForceRedraw = FALSE;
                        }
                    }
                    HXDestroyRegion( pTmpReg );
                }
            }
            else
            {
//XXXgfw OK, this is screwed up. Windows renders want a rectangle in
//XXXgfw param2 while the unix renderers want a Window there. To clean this
//XXXgfw up we need to clean up and unify the renderers.....
#if defined(_UNIX) && !defined(_MAC_UNIX)
                event.event   = HX_SURFACE_UPDATE;
                event.window  = hxxWin?hxxWin->window : NULL;
                event.param1  = m_pVideoSurface;
                event.param2  = GetWindow();
                event.result  = 0;
                event.handled = 0;
#else
                event.event   = HX_SURFACE_UPDATE;
                event.window  = m_pWindow? m_pWindow->window : NULL;
                event.param1  = m_pVideoSurface;
                event.param2  = NULL;
                event.result  = 0;
                event.handled = 0;
#endif
                // Clear the dirty region
                HXZeroOutRegion( m_pDirtyRegion );

                if( m_pUser )
                {
                    if (!m_bDoNotGenerateWMPPaint)
                    {
                        // Distinguishes between a new frame and a repaint of a prior frame
                        m_bInForceRedraw = m_bSiteRefresh;
                        m_pUser->HandleEvent(&event);
                        m_bInForceRedraw = FALSE;
                    }
                }
            }

            // If blt has never been called, then blt black to the
            // background.  Do not do this if we are a windowed
            // renderer.
            if (!event.handled && !m_bBltHasBeenCalled
                && !m_pWindow && m_pVideoSurface->m_nBltMode!=HX_OVERLAY_BLT )
            {
                // Get the current size of the site The source rect is
                // just a 1 by 1 black pixel that gets stretched to
                // fit the destination
                HXxRect rDestRect   = { 0, 0, m_size.cx, m_size.cy};
                HXxRect rSrcRect    = { 0, 0, 1, 1};

                HXBitmapInfoHeader bih;
                memset(&bih, 0, sizeof(HXBitmapInfoHeader));

                bih.biSize          = sizeof(HXBitmapInfoHeader);
                bih.biWidth         = 1;
                bih.biHeight        = 1;
                bih.biPlanes        = 1;
                bih.biBitCount      = 32;
                bih.biCompression   = HX_RGB;

                UCHAR pBuffer[4] = { 0,0,0,0 };
                m_pVideoSurface->Blt(pBuffer,
                                     &bih,
                                     rDestRect,
                                     rSrcRect);
                m_bBltHasBeenCalled = FALSE;
            }

            //Stupid Windowed renderers!
            if(!m_bDoNotGenerateWMPPaint &&
               !event.handled            &&
               m_pWindow                 &&
               m_pWindow->window )
            {
                _SendOSUpdateMessage();
            }
        }

        m_pVideoSurface->UpdateBltStats(&m_UpdateBltStatsRect);
    }

    _TLSUnlock();
    _ExitForceRedraw();

    Release();
    return HXR_OK;
}



/************************************************************************
 *  Method:
 *    IHXSite2::UpdateSiteWindow
 *
 *      Not used on Windows platform
 */
STDMETHODIMP CHXBaseSite::UpdateSiteWindow
(
    HXxWindow* /*IN*/ pWindow
    )
{
    return HXR_NOTIMPL;
}


/************************************************************************
 *  Method:
 *    IHXSite2::ShowSite
 */
STDMETHODIMP CHXBaseSite::ShowSite(BOOL bShow)
{
    _TLSLock();

    if(m_bIsVisible != bShow)
    {
        m_bIsVisible = bShow;

        //Invalidate the rect....
        HXxRect pTmp = { m_topleft.x,
                         m_topleft.y,
                         m_topleft.x+m_size.cx,
                         m_topleft.y+m_size.cy};
        m_pTopLevelSite->_RecursiveDamageRect( &pTmp, TRUE );

        if( this == m_pTopLevelSite )
        {
            RecomputeClip();
        }
        else
        {
            if(m_pTopLevelSite)
                m_pTopLevelSite->ScheduleCallback(CLIP, 0);
        }
    }

    _ShowSite(bShow);

    SizeSliders();

    _TLSUnlock();

    return HXR_OK;
}

void CHXBaseSite::_ForceRedrawAll()
{
    if( (IsSiteVisible() && m_Region && !HXEmptyRegion(m_Region)) ||
        (m_AlphaBlendSites.GetCount()||m_AlphaBlendNotifiers.GetCount() )
        )
    {

//         HXREGION* pReg = NULL;

//         if( pDirtyRect)
//         {
//             pReg = HXCreateRectRegion( pDirtyRect->left,
//                                         pDirtyRect->top,
//                                         pDirtyRect->right-pDirtyRect->left,
//                                         pDirtyRect->bottom-pDirtyRect->top );
//             HXIntersectRegion( m_Region, pReg, pReg );
//             HXUnionRegion( m_pDirtyRegion, pReg, m_pDirtyRegion );
//             HXDestroyRegion( pReg );
//         }
//         else
//         {
//            HXUnionRegion( m_pDirtyRegion, m_Region, m_pDirtyRegion );
//        }
        InternalForceRedraw();
    }

    //Now do all the children in z-order
    LISTPOSITION pos = m_ChildrenInZOrder.GetHeadPosition();
    while(pos)
    {
        CHXBaseSite* pSite = (CHXBaseSite*)m_ChildrenInZOrder.GetNext(pos);
        pSite->_ForceRedrawAll();
    }
}

BOOL CHXBaseSite::_CheckForVisibleChild()
{
    BOOL retVal = FALSE;
    if( m_bIsVisible && !m_bSiteNeverBlts )
    {
        retVal = TRUE;
    }
    else
    {
        LISTPOSITION pos = m_ChildrenInZOrder.GetHeadPosition();
        while(pos)
        {
            CHXBaseSite* pSite = (CHXBaseSite*)m_ChildrenInZOrder.GetNext(pos);
            if( pSite->_CheckForVisibleChild() )
            {
                retVal = TRUE;
                break;
            }
        }
    }
    return retVal;
}

/************************************************************************
 *  Method:
 *    IHXSite2::IsSiteVisible
 */
STDMETHODIMP_(BOOL) CHXBaseSite::IsSiteVisible()
{
    BOOL bIsVisible = m_bIsVisible;
    if(m_pParentSite)
    {
        bIsVisible &= m_pParentSite->IsSiteVisible();
    }

    if( bIsVisible )
    {
        //If we are a m_bSiteNeverBlts then it doesn't matter if we are
        //visible or not, we must have at least one child that is
        //visible and not m_bSiteNeverBlts. Otherwise we really aren't
        //visible at all. This distinction is needed because of our
        //favorite logic in computesubrecs not that we have transparent
        //regions.
        if(!_CheckForVisibleChild())
        {
            bIsVisible = FALSE;
        }
    }

    return bIsVisible;
}

/************************************************************************
 *  Method:
 *    IHXSite2::UpdateZOrder
 *    This method updates the Z order of its child sites since one of its
 *    child sites' Z order is being updated.
 */

void
CHXBaseSite::UpdateZOrder( CHXBaseSite* pUpdatedChildSite, INT32 lOldZOrder, INT32 lNewZOrder)
{
    HX_ASSERT(pUpdatedChildSite);
    LISTPOSITION pos = m_ChildrenInZOrder.Find((void*)pUpdatedChildSite);
    if (!pos)
    {
	return;
    }

    m_ChildrenInZOrder.RemoveAt(pos);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?