⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 macroot.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:

void CMacRootSurface::CheckRectRgn( Rect r, RgnHandle rgn, Point globalOffset )
{
    if ( r.bottom <= r.top || r.right <= r.left || !RectInRgn( &r, rgn ) )
    {
	// if the rect is empty or ain't in the region, bail.
	return;
    }
    
    if ( IsRegionRectangular( rgn ) )
    {
	// since the region is a rectangle, add that rectangle and bail.
	Rect* newRect = new Rect;
	GetRegionBounds(rgn, newRect);
	
	newRect->left += globalOffset.h;
	newRect->top += globalOffset.v;
	newRect->right += globalOffset.h;
	newRect->bottom += globalOffset.v;
	
	m_pVisRgnRects->AddTail( newRect );
	return;
    }
    
    // we've established that it's not clearly defined, so divide and conquer.
    
    Rect newRect1 = r;
    Rect newRect2 = r;
    
    if ( r.bottom - r.top > r.right - r.left )
    {
	// more vertically oriented
	short interimValue = ( r.bottom + r.top ) / 2;
	newRect1.bottom = interimValue;
	newRect2.top = interimValue;
    }
    else
    {
	// more horizontally oriented
	short interimValue = ( r.left + r.right ) / 2;
	newRect1.right = interimValue;
	newRect2.left = interimValue;
    }
    
    RgnHandle newRgn1 = NewRgn();
    RgnHandle newRgn2 = NewRgn();
    
    RectRgn( newRgn1, &newRect1 );
    RectRgn( newRgn2, &newRect2 );
    
    SectRgn( rgn, newRgn1, newRgn1 );
    SectRgn( rgn, newRgn2, newRgn2 );
    
    CheckRectRgn( newRect1, newRgn1, globalOffset );
    CheckRectRgn( newRect2, newRgn2, globalOffset );
    
    DisposeRgn( newRgn1 );
    DisposeRgn( newRgn2 );
}

/************************************************************************
 *  Method:
 *    CMacRootSurface::UpdateRegionIfNecessary
 *
 */

void
CMacRootSurface::UpdateRegionIfNecessary(Rect boundingRect, Point globalOffset, BOOL bForceItToUpdate /* = FALSE */ )
{
#if defined(_CARBON) || defined(_MAC_UNIX)
    return; // xxxbobclark just to keep from crashing???
#else
    HX_ASSERT(!HXMM_ATINTERRUPT());
    
    if (HXMM_ATINTERRUPT()) return;
    
    GrafPtr savePort;
    ::GetPort(&savePort);
    
    WindowPtr macWindow = m_pSite->GetWindow() ? (WindowPtr)m_pSite->GetWindow()->window : NULL;

    if (CHXMacSite::zm_bFullScreenActive)
    {
	CHXMacSite* pMacSite = (CHXMacSite*)m_pSite;
	if (pMacSite->m_pHXxFullScreenWindow)
	{
	    macWindow = (WindowPtr)pMacSite->m_pHXxFullScreenWindow->window;
	}
    }

    HX_ASSERT(macWindow);
    
    if (!macWindow) return;
    
#if defined(_CARBON) || defined(_MAC_UNIX)
    ::SetPort( GetWindowPort( macWindow ) );
#else
    ::SetPort(macWindow);
#endif
    
    RgnHandle theClippedVisRgn = ::NewRgn();
#if defined(_CARBON) || defined(_MAC_UNIX)
    RgnHandle visRgn = ::NewRgn();
    ::GetPortVisibleRegion( GetWindowPort(macWindow), visRgn );
    RgnHandle clipRgn = ::NewRgn();
    ::GetPortClipRegion( GetWindowPort(macWindow), clipRgn );
    ::SectRgn( visRgn, clipRgn, theClippedVisRgn );
    ::DisposeRgn( clipRgn );
    ::DisposeRgn( visRgn );
#else
    ::SectRgn( macWindow->visRgn, macWindow->clipRgn, theClippedVisRgn );
#endif
    
    // first, dispose and null out m_LastVisRgn if necessary (or forced)
    if ( m_LastVisRgn && ( bForceItToUpdate || !::EqualRgn(theClippedVisRgn, m_LastVisRgn) ) )
    {
	::DisposeRgn(m_LastVisRgn);
	m_LastVisRgn = NULL;
    }
    
    if (!m_LastVisRgn)
    {
	m_LastVisRgn = ::NewRgn();
	
	::CopyRgn(theClippedVisRgn, m_LastVisRgn);
	RgnHandle interimRgn = ::NewRgn();
	::RectRgn(interimRgn, &boundingRect);
	::SectRgn(m_LastVisRgn, interimRgn, interimRgn);
	
	while (m_pVisRgnRects->GetCount())
	{
	    Rect* r = (Rect*)m_pVisRgnRects->RemoveHead();
	    delete r;
	}
	CheckRectRgn(boundingRect, interimRgn, globalOffset);
//	RegionToRectsByNoodlingThroughRegion(interimRgn, globalOffset, m_VisRgnRects);
	::DisposeRgn(interimRgn);
    }
    
    ::DisposeRgn(theClippedVisRgn);
    
    ::SetPort(savePort);
#endif
}




/************************************************************************
 *  Method:
 *    CMacRootSurface::_PreFlightBlt
 *
 *    This is called AFTER the current sub-rectangle has been determined,
 *    but BEFORE any assumptions about screen depth or anything have been
 *    made. Basically this is where I can hijack the cross-platform code's
 *    assumptions and surreptitiously slide in an appropriate
 *    m_pCompositionSurface and other variables.
 *
 */

void
CMacRootSurface::_PreFlightBlt(HXxRect& dst)
{
    if (!m_bItsOKToDoAnInterruptBlit) return;
    
    m_pCompositionSurface = nil;
    m_nBlitDepthEnum = -1;
    
    Rect r;
    r.left = dst.left + m_LocalToGlobalCoords.h;
    r.top = dst.top + m_LocalToGlobalCoords.v;
    r.right = dst.right + m_LocalToGlobalCoords.h;
    r.bottom = dst.bottom + m_LocalToGlobalCoords.v;
    
#ifdef USE_LOW_LEVEL_QT_API
    int i = zm_uNumberOfAttachedDevices;
#else
    for (int i = 0; i < zm_uNumberOfAttachedDevices; i++)
#endif
    {
	Rect intersectionRect;
	
	if ((i == zm_uNumberOfAttachedDevices) || (::SectRect(&r, &(**zm_AttachedDevice[i]).gdRect, &intersectionRect)))
	{
	    // now figure out which GWorld we need to use.
	    
	    // XXXbobclark I'm starting out with a copy-n-paste of
	    // _CreateCompositionSurface(). Ewww. But the problem is that
	    // we don't know -- until now -- which depths and therefore
	    // which GWorlds we need. Dayum. ...And what makes it worse is
	    // that it might be interrupt time before stuff's created. That
	    // will be a weird circumstance -- and one where the blit won't
	    // actually succeed -- but it might screw things up in the
	    // meantime, like if it tries to blit into the NULL composition
	    // surface. Crash. So maybe if it fails everywhere else I'll
	    // force the composition surface to be the 32-bit one that's
	    // created in _CreateCompositionSurface just so the color
	    // converter has SOMETHING to blit into even though it will
	    // subsequently get ignored. Shee-it.
	    
	    // All (potentially three) offscreens will be full-sized. This
	    // could be a "waste" of memory, but solving it is excruciatingly
	    // subtle and has many tendrils, such as telling the color converter
	    // to convert into non 0,0-based rectangles, yeesh. The good news
	    // -- and an improvement over the older site code -- is that it
	    // only color-converts into the parts of the offscreen that
	    // eventually gets blitted to screen. So there's not a lot of
	    // wasted color conversion.
	    
	    PixMapHandle thePMH = NULL;
	    int pixelSize = 0;
	    INT32 whichDepth;
	    
#ifdef USE_LOW_LEVEL_QT_API
	    if (i == zm_uNumberOfAttachedDevices)
	    {
		whichDepth = kYUVDepth;
	    }
	    else
#endif
	    {
		thePMH = (**zm_AttachedDevice[i]).gdPMap;
		pixelSize = (**thePMH).pixelSize;
		whichDepth = DepthToDepthEnum(pixelSize);
	    }

	    if (m_RootSurfaceGWorld[whichDepth])
	    {
		// now see if it needs to be reinitialized.
		
		Rect thePortRect;
#if defined(_CARBON) || defined(_MAC_UNIX)
		GetPortBounds(m_RootSurfaceGWorld[whichDepth], &thePortRect);
#else
		thePortRect = m_RootSurfaceGWorld[whichDepth]->portRect;
#endif
		
		BOOL bNeedToRecreate = FALSE;
		
		if (m_compositionSize.cx > thePortRect.right - thePortRect.left) bNeedToRecreate = TRUE;
		if (m_compositionSize.cy > thePortRect.bottom - thePortRect.top) bNeedToRecreate = TRUE;
		
#ifdef USE_LOW_LEVEL_QT_API
		if (whichDepth == kYUVDepth)
		{
		    // xxxbobclark if it's using YUV then the QT calls assume that the whole
		    // GWorld is being used, so using just the upper-left portion
		    // doesn't work.
		    if (m_compositionSize.cx != thePortRect.right-thePortRect.left) bNeedToRecreate = TRUE;
		    if (m_compositionSize.cy != thePortRect.bottom-thePortRect.top) bNeedToRecreate = TRUE;
		}
#endif
		
		if (bNeedToRecreate)
		{
		    ::UnlockPixels(m_RootGWorldPixMap[whichDepth]);
		    ::DisposeGWorld(m_RootSurfaceGWorld[whichDepth]);
		    m_RootSurfaceGWorld[whichDepth] = nil;
		    m_RootGWorldPixMap[whichDepth] = nil;
		}
	    }
	    
	    if (!m_RootSurfaceGWorld[whichDepth])
	    {
		// need to (re)create it
		
		Rect r;
		::SetRect(&r, 0, 0, m_compositionSize.cx, m_compositionSize.cy);
		
#ifdef USE_LOW_LEVEL_QT_API

		if (whichDepth == kYUVDepth)
		{
		    ::QTNewGWorld(&m_RootSurfaceGWorld[whichDepth], 'yuvs', &r, nil, nil, useTempMem | 16 | 32);
		    if (!m_RootSurfaceGWorld[whichDepth])
		    {
			::QTNewGWorld(&m_RootSurfaceGWorld[whichDepth], 'yuvs', &r, nil, nil, useTempMem | 32);
		    }
		    if (!m_RootSurfaceGWorld[whichDepth])
		    {
			::QTNewGWorld(&m_RootSurfaceGWorld[whichDepth], 'yuvs', &r, nil, nil, useTempMem | 16);
		    }
		    if (!m_RootSurfaceGWorld[whichDepth])
		    {
			::QTNewGWorld(&m_RootSurfaceGWorld[whichDepth], 'yuvs', &r, nil, nil, 16 | 32);
		    }
		    if (!m_RootSurfaceGWorld[whichDepth])
		    {
			::QTNewGWorld(&m_RootSurfaceGWorld[whichDepth], 'yuvs', &r, nil, nil, 32);
		    }
		    if (!m_RootSurfaceGWorld[whichDepth])
		    {
			::QTNewGWorld(&m_RootSurfaceGWorld[whichDepth], 'yuvs', &r, nil, nil, 16);
		    }
		    if (!m_RootSurfaceGWorld[whichDepth])
		    {
			::QTNewGWorld(&m_RootSurfaceGWorld[whichDepth], 'yuvs', &r, nil, nil, useTempMem);
		    }
		    if (!m_RootSurfaceGWorld[whichDepth])
		    {
			return;
		    }
		}
		else
#endif

		{
		    ::NewGWorld(&m_RootSurfaceGWorld[whichDepth], pixelSize, &r, nil, nil, useTempMem);
		    if (!m_RootSurfaceGWorld[whichDepth])
		    {
			::NewGWorld(&m_RootSurfaceGWorld[whichDepth], pixelSize, &r, nil, nil, 0);

			if (!m_RootSurfaceGWorld[whichDepth]) return;
		    }
		}
		
#if defined(_CARBON) || defined(_MAC_UNIX)
		m_RootGWorldPixMap[whichDepth] = GetPortPixMap(m_RootSurfaceGWorld[whichDepth]);
#else
		m_RootGWorldPixMap[whichDepth] = m_RootSurfaceGWorld[whichDepth]->portPixMap;
#endif
		::LockPixels(m_RootGWorldPixMap[whichDepth]);
		
	    }
	    
	    // OK now the offscreen stuff should all be reinitialized if
	    // it came to that... in any case we're now ready to do the
	    // actual work? nah... kludgey? nah... surreptitious! stuff.
	    
	    if (m_RootSurfaceGWorld[whichDepth] && m_RootGWorldPixMap[whichDepth])
	    {
		m_pCompositionSurface = (unsigned char*)::GetPixBaseAddr(m_RootGWorldPixMap[whichDepth]);
		m_nBlitDepthEnum = whichDepth;
		Rect hold;
#if defined(_CARBON) || defined(_MAC_UNIX)
		GetPortBounds(m_RootSurfaceGWorld[whichDepth], &hold);
#else
		hold = m_RootSurfaceGWorld[whichDepth]->portRect;
#endif
		m_allocatedCompositionSize.cx = hold.right-hold.left;
		m_allocatedCompositionSize.cy = hold.bottom-hold.top;
		m_nCompositionPitch = (**m_RootGWorldPixMap[whichDepth]).rowBytes & 0x3fff;
		m_boundsRect.left = 0;
		m_boundsRect.top = 0;
		m_boundsRect.right = m_allocatedCompositionSize.cx;
		m_boundsRect.bottom = m_allocatedCompositionSize.cy;
		
		switch (whichDepth)
		{
		    case kThirtyTwoBitDepth:
			m_nCompositionSurfaceCID = CID_RGB32;
			break;
			
		    case kSixteenBitDepth:
			m_nCompositionSurfaceCID = CID_RGB555;
			break;
			
#ifdef USE_LOW_LEVEL_QT_API
		    case kYUVDepth:
			m_nCompositionSurfaceCID = CID_YUY2;
			break;
#endif

		    default:
			m_nCompositionSurfaceCID = CID_RGB8;
			break;
		}
	    }
	}
    }
    
    if (!m_pCompositionSurface)
    {
	// this is possible if we're at interrupt time and we're trying to
	// blit to bad places.
	if (m_RootSurfaceGWorld[kThirtyTwoBitDepth] && m_RootGWorldPixMap[kThirtyTwoBitDepth])
	{
	    m_pCompositionSurface = (unsigned char*)GetPixBaseAddr(m_RootGWorldPixMap[kThirtyTwoBitDepth]);
	    m_nBlitDepthEnum = kThirtyTwoBitDepth;

	    m_nCompositionPitch = (**m_RootGWorldPixMap[kThirtyTwoBitDepth]).rowBytes & 0x3fff;

	    m_boundsRect.left = 0;
	    m_boundsRect.top = 0;
	    m_boundsRect.right = m_compositionSize.cx;
	    m_boundsRect.bottom = m_compositionSize.cy;

	    m_nCompositionSurfaceCID = CID_RGB32;
	    
	}
    }
}


/************************************************************************
 *  Method:
 *    CMacRootSurface::_GetNumberOfMonitors
 *
 */

UINT32 CMacRootSurface::_GetNumberOfMonitors()
{
    return zm_uNumberOfAttachedDevices;
}


/************************************************************************
 *  Method:
 *    CMacRootSurface::_RectOnNthMonitor
 *
 */

BOOL CMacRootSurface::_RectOnNthMonitor(HXxRect rect, UINT32 uMonitor, HXxRect& intersectRect)
{
    HX_ASSERT(uMonitor < zm_uNumberOfAttachedDevices);
    
    if (/*It's using an overlay*/1)
    {
	if (uMonitor == 0)
	{
	    intersectRect = rect;
	    return TRUE;
	}
	else
	{
	    return FALSE;
	}
    }
    
    if (!m_bItsOKToDoAnInterruptBlit)
    {
	// XXXbobclark well, um, the thing is, if it's at interrupt time
	// we'll bail out this instant; if it's at system time that means
	// we can probably pass through a (possibly bogus) rectangle so
	// the code in _MinimalBlt() catches it and can set m_bItsOKToAn-
	// InterruptBlit to true.
	
	intersectRect = rect;
	return TRUE;
    }
    
    Rect r;
    r.left = rect.left + m_LocalToGlobalCoords.h;
    r.top = rect.top + m_LocalToGlobalCoords.v;
    r.right = rect.right + m_LocalToGlobalCoords.h;
    r.bottom = rect.bottom + m_LocalToGlobalCoords.v;
    
    Rect intR;
    if (::SectRect(&r, &(**zm_AttachedDevice[uMonitor]).gdRect, &intR))
    {
	intersectRect.left = intR.left - m_LocalToGlobalCoords.h;
	intersectRect.top = intR.top - m_LocalToGlobalCoords.v;
	intersectRect.right = intR.right - m_LocalToGlobalCoords.h;
	intersectRect.bottom = intR.bottom - m_LocalToGlobalCoords.v;

	return TRUE;
    }
    return FALSE;
}

⌨️ 快捷键说明

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