📄 macroot.cpp
字号:
* Method: * CMacRootSurface::CheckRectRgn * */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 * */voidCMacRootSurface::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. * */voidCMacRootSurface::_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 + -