macroot.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:44k
- /* ***** BEGIN LICENSE BLOCK *****
- * Source last modified: $Id: macroot.cpp,v 1.7.20.1 2004/07/09 01:59:02 hubbe Exp $
- *
- * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
- *
- * The contents of this file, and the files included with this file,
- * are subject to the current version of the RealNetworks Public
- * Source License (the "RPSL") available at
- * http://www.helixcommunity.org/content/rpsl unless you have licensed
- * the file under the current version of the RealNetworks Community
- * Source License (the "RCSL") available at
- * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
- * will apply. You may also obtain the license terms directly from
- * RealNetworks. You may not use this file except in compliance with
- * the RPSL or, if you have a valid RCSL with RealNetworks applicable
- * to this file, the RCSL. Please see the applicable RPSL or RCSL for
- * the rights, obligations and limitations governing use of the
- * contents of the file.
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL") in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your version of
- * this file only under the terms of the GPL, and not to allow others
- * to use your version of this file under the terms of either the RPSL
- * or RCSL, indicate your decision by deleting the provisions above
- * and replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient may
- * use your version of this file under the terms of any one of the
- * RPSL, the RCSL or the GPL.
- *
- * This file is part of the Helix DNA Technology. RealNetworks is the
- * developer of the Original Code and owns the copyrights in the
- * portions it created.
- *
- * This file, and the files included with this file, is distributed
- * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
- * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
- * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
- * ENJOYMENT OR NON-INFRINGEMENT.
- *
- * Technology Compatibility Kit Test Suite(s) Location:
- * http://www.helixcommunity.org/content/tck
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
- #include "hxcom.h"
- #include "hxtypes.h"
- #include "hxwintyp.h"
- #include "hxmap.h"
- #include "hxslist.h"
- #include "ihxpckts.h"
- #include "hxwin.h"
- #include "hxengin.h"
- #include "hxsite2.h"
- #include "chxxtype.h"
- #include "hxvctrl.h"
- #include "hxvsurf.h"
- #include "hxcodec.h"
- #include "surface.h"
- #include "vidosurf.h"
- #include "sitetext.h"
- #include "chxpckts.h"
- #include "hxevent.h"
- #include "bltpatch.h"
- #include "hxprefs.h"
- #include "hxevent.h"
- #include "hxthread.h"
- #include "basesite.h"
- #include "platform/mac/macroot.h"
- #include "platform/mac/macsite.h"
- #include "platform/mac/macsurf.h"
- #include "platform/mac/hx_moreprocesses.h"
- #ifndef _MAC_UNIX
- #include "hxmm.h"
- #endif
- #include "hxcore.h"
- #ifndef _MACINTOSH
- #ifndef _MAC_UNIX
- #error This is the Macintosh platform specific implementation.
- #endif
- #endif
- #if !defined(_CARBON) && !defined(_MAC_UNIX)
- #error This is an OS X and later implementation!
- #endif
- #include "hxheap.h"
- #ifdef _DEBUG
- #undef HX_THIS_FILE
- static const char HX_THIS_FILE[] = __FILE__;
- #endif
- UINT32 CMacRootSurface::zm_uNumberOfAttachedDevices = 0;
- GDHandle CMacRootSurface::zm_AttachedDevice[CMacRootSurface::kMaxMonitors];
- CHXSimpleList CMacRootSurface::zm_RootSurfaceList;
- CMacRootSurface::OverlayInfoStruct CMacRootSurface::zm_OverlayInfo[CMacRootSurface::kMaxMonitors];
- /************************************************************************
- * Method:
- * CMacRootSurface constructor
- */
- CMacRootSurface::CMacRootSurface(IUnknown* pContext, CHXBaseSite* pSite)
- : CBaseRootSurface(pContext, pSite)
- , m_bItsOKToDoAnInterruptBlit(FALSE)
- , m_pVisRgnRects(NULL)
- , m_LastVisRgn(NULL)
- , m_bNeedToForceVisRgnUpdate(FALSE)
- , m_nBlitDepthEnum(-1)
- , m_bInBlueBox(FALSE)
- , m_bAllowedToITBInBlueBox(TRUE)
- {
- m_pVisRgnRects = new CHXSimpleList();
-
- int i;
- for (i = 0; i < kNumberOfDepths; i++)
- {
- m_RootSurfaceGWorld[i] = nil;
- m_RootGWorldPixMap[i] = nil;
- }
- if (zm_uNumberOfAttachedDevices == 0)
- {
- // OK, first zero it all out
- for (i=0; i < kMaxMonitors; i++)
- {
- zm_AttachedDevice[i] = NULL;
-
- zm_OverlayInfo[i].b_OverlayExists = FALSE;
- zm_OverlayInfo[i].b_OverlayInitialized = FALSE;
- }
-
- // now fill it in with all attached devices!
-
- // check for multiple monitors. Also grab main device...
- GDHandle mainGD = ::GetMainDevice();
- GDHandle gdH = ::GetDeviceList();
- while ( gdH )
- {
- zm_AttachedDevice[zm_uNumberOfAttachedDevices] = gdH;
- zm_uNumberOfAttachedDevices++;
- gdH = ::GetNextDevice( gdH );
-
- if (zm_uNumberOfAttachedDevices >= kMaxMonitors)
- {
- gdH = nil; // stop counting after ten monitors!
- }
- }
- }
-
- long blueBoxParams = 0;
- short err = Gestalt('bbox', &blueBoxParams);
- if (!err && blueBoxParams & 0x00000001)
- {
- m_bInBlueBox = TRUE;
- }
-
- m_LocalToGlobalCoords.h = -32768;
- m_LocalToGlobalCoords.v = -32768;
- zm_RootSurfaceList.AddTail(this);
- }
- /************************************************************************
- * Method:
- * CMacRootSurface destructor
- */
- CMacRootSurface::~CMacRootSurface()
- {
- LISTPOSITION pos = zm_RootSurfaceList.Find(this);
- zm_RootSurfaceList.RemoveAt(pos);
-
- int i;
- for (i = 0; i < kNumberOfDepths; i++)
- {
- if (m_RootSurfaceGWorld[i] != NULL)
- {
- ::UnlockPixels(m_RootGWorldPixMap[i]);
- ::DisposeGWorld(m_RootSurfaceGWorld[i]);
- m_RootSurfaceGWorld[i] = NULL;
- m_RootGWorldPixMap[i] = NULL;
- }
- }
-
- if (m_LastVisRgn)
- {
- ::DisposeRgn(m_LastVisRgn);
- m_LastVisRgn = nil;
- }
- delete m_pVisRgnRects;
- m_pVisRgnRects = NULL;
- }
- /************************************************************************
- * Method:
- * CMacRootSurface::_GetYUVScratchWidthHeight
- */
- void
- CMacRootSurface::_GetYUVScratchWidthHeight(UINT32* pWidth, UINT32* pHeight)
- {
- }
- /************************************************************************
- * Method:
- * CMacRootSurface::_CreateYUVScratchSurface
- */
- void
- CMacRootSurface::_CreateYUVScratchSurface(UINT32 width, UINT32 height)
- {
- }
- /************************************************************************
- * Method:
- * CMacRootSurface::_GetYUVScratchSurfacePointer
- */
- void
- CMacRootSurface::_GetYUVScratchSurfacePointer(UCHAR** pYUVBits, INT32* YUVPitch)
- {
- }
- /************************************************************************
- * Method:
- * CMacRootSurface::CreateScratchSurface
- */
- HX_RESULT
- CMacRootSurface::CreateScratchSurface(int nCompositionSurfaceCID, HXxSize* pSize)
- {
- return HXR_OK;
- }
- /************************************************************************
- * Method:
- * CMacRootSurface::ScratchLock
- */
- HX_RESULT
- CMacRootSurface::ScratchLock(UCHAR** pBits, INT32* pPitch_)
- {
- return HXR_OK;
- }
- /************************************************************************
- * Method:
- * CMacRootSurface::ScratchUnlock
- */
- HX_RESULT
- CMacRootSurface::ScratchUnlock(UCHAR* pBits)
- {
- return HXR_OK;
- }
- /************************************************************************
- * Method:
- * CMacRootSurface::_BltFromScratchToComposition
- */
- void
- CMacRootSurface::_BltFromScratchToComposition(HXxRect& rDestRect, HXxRect& rSrcRect)
- {
- }
- /************************************************************************
- * Method:
- * CMacRootSurface::_DebugBlt
- */
- HX_RESULT
- CMacRootSurface::_DebugBlt( UCHAR* pImageData,
- HXBitmapInfoHeader* pBitmapInfo,
- REF(HXxRect) rDestRect,
- REF(HXxRect) rSrcRect)
- {
- return HXR_OK;
- }
- /************************************************************************
- * Method:
- * CMacRootSurface::_MinimalUnlock
- */
- HX_RESULT
- CMacRootSurface::_MinimalUnlock(HXxWindow* pWindow)
- {
- return HXR_OK;
- }
- /************************************************************************
- * Method:
- * CMacRootSurface::_LockComposition
- */
- HX_RESULT
- CMacRootSurface::_LockComposition(UCHAR** pBits, INT32* pPitch)
- {
- if (m_bItsOKToDoAnInterruptBlit)
- {
- // if the OK to ITB boolean still needs to be set,
- // the region will be force-updated at an appropriate
- // time.
-
- // ensure that region is updated.
- Rect r;
- r.left = m_boundsRect.left;
- r.top = m_boundsRect.top;
- r.right = m_boundsRect.right;
- r.bottom = m_boundsRect.bottom;
- UpdateRegionIfNecessary(r, m_LocalToGlobalCoords, m_bNeedToForceVisRgnUpdate);
- m_bNeedToForceVisRgnUpdate = FALSE;
- }
- return HXR_OK;
- }
- /************************************************************************
- * Method:
- * CMacRootSurface::_CreateCompositionSurface
- */
- HX_RESULT
- CMacRootSurface::_CreateCompositionSurface()
- {
- // XXXbobclark The composition surface -- where stuff gets blitted
- // on an interim basis prior to being blitted straight to the screen
- // -- works most optimally if it's the same depth as the screen.
- // When all this shtuff was in comlib I did this by having possibly
- // three interim GWorlds, one each of depths 8-bit, 16-bit, and 32-bit.
- // Note that interrupt-time blitting REQUIRES a composition surface of the
- // same depth as the screen 'cause CopyBits() doesn't work. And multiple
- // monitors imply that multiple depths may need to be active simultaneously.
- // Since this gets called so often I'll never dispose the GWorld
- // in _DestroyCompositionSurface() so it won't recreate it here. But if
- // it stays this way then I'll need to check the size here to see if I
- // need to dispose the current GWorld and create a new, correctly-sized
- // one.
- if (m_compositionSize.cx > m_allocatedCompositionSize.cx || m_compositionSize.cy > m_allocatedCompositionSize.cy)
- {
- ::UnlockPixels(m_RootGWorldPixMap[kThirtyTwoBitDepth]);
- ::DisposeGWorld(m_RootSurfaceGWorld[kThirtyTwoBitDepth]);
- m_RootSurfaceGWorld[kThirtyTwoBitDepth] = nil;
- m_RootGWorldPixMap[kThirtyTwoBitDepth] = nil;
- m_pCompositionSurface = nil;
- m_nBlitDepthEnum = -1;
- }
-
- if (!m_pCompositionSurface)
- {
- short thePixelDepth = 32;
- Rect r;
- SetRect(&r, 0, 0, m_compositionSize.cx, m_compositionSize.cy);
- // It's possible that this is getting called extremely often -- like
- // once per blit! and it's also getting called occasionally at interrupt
- // time. So I need to get this being built at appropriate times only,
- // and then I think that copying it over in _MinimalBlt() I can blit it over
- // to the window and maybe just maybe I'll have something visible. Sheesh.
- ::NewGWorld(&m_RootSurfaceGWorld[kThirtyTwoBitDepth], thePixelDepth, &r, nil, nil, useTempMem);
- if (!m_RootSurfaceGWorld[kThirtyTwoBitDepth])
- {
- // it failed to create it in temp mem so try creating it in the application heap.
- ::NewGWorld(&m_RootSurfaceGWorld[kThirtyTwoBitDepth], thePixelDepth, &r, nil, nil, 0);
-
- if (!m_RootSurfaceGWorld[kThirtyTwoBitDepth]) return HXR_FAIL;
- }
- m_RootGWorldPixMap[kThirtyTwoBitDepth] = GetPortPixMap(m_RootSurfaceGWorld[kThirtyTwoBitDepth]);
- ::LockPixels(m_RootGWorldPixMap[kThirtyTwoBitDepth]);
- m_pCompositionSurface = (unsigned char*)GetPixBaseAddr(m_RootGWorldPixMap[kThirtyTwoBitDepth]);
- m_nBlitDepthEnum = kThirtyTwoBitDepth;
- m_allocatedCompositionSize = m_compositionSize;
- m_nCompositionPitch = (**m_RootGWorldPixMap[kThirtyTwoBitDepth]).rowBytes & 0x3fff;
- m_boundsRect.left = r.left;
- m_boundsRect.top = r.top;
- m_boundsRect.right = r.right;
- m_boundsRect.bottom = r.bottom;
- m_nCompositionSurfaceCID = CID_RGB32;
- }
- return HXR_OK;
- }
- /************************************************************************
- * Method:
- * CMacRootSurface::_DestroyCompositionSurface
- */
- HX_RESULT
- CMacRootSurface::_DestroyCompositionSurface()
- {
- // XXXbobclark I've gotta figure out what the story is here,
- // 'cause right now it's getting called every blit.
- // I certainly don't want to be destroying the whole GWorld!
- // So currently I'll never destroy it. Ehhh.
-
- return HXR_OK;
- }
- /************************************************************************
- * Method:
- * CMacRootSurface::_MinimalBlt
- */
- void
- CMacRootSurface::_MinimalBlt(HXxRect& src, HXxRect& dst)
- {
- {
- GrafPtr savePort;
- ::GetPort(&savePort);
- WindowPtr macWindow;
- macWindow = m_pSite->m_pWindow ? (WindowPtr)m_pSite->m_pWindow->window : NULL;
-
- if (CHXMacSite::zm_bFullScreenActive)
- {
- CHXMacSite* pMacSite = (CHXMacSite*)m_pSite;
- if (pMacSite->m_pHXxFullScreenWindow)
- {
- macWindow = (WindowPtr)pMacSite->m_pHXxFullScreenWindow->window;
- }
- }
-
- ::SetPort(GetWindowPort(macWindow));
- // XXXbobclark The "old site" surface implementation's innermost
- // blitting API, "BltImage", always happened to have the dest
- // rectangle at (0,0) and relied on SetOrigin to set it up
- // correctly. The "new site" implementation's innermost blittin
- // API is "_MinimalBlt", and in this case the rectangle is relative
- // to the core's area. So I remember the current origin (so I can
- // restore it 'cause some renderers need it) and reset it to the
- // core's offset.
- Point oldOrigin;
- Rect portRect;
- GetPortBounds(GetWindowPort(macWindow), &portRect);
- oldOrigin.h = portRect.left;
- oldOrigin.v = portRect.top;
- HXxWindow* pWindow = m_pSite->GetWindow();
- if (pWindow)
- {
- SetOriginAndMaintainClipRgn(-pWindow->x,-pWindow->y);
- }
- m_LocalToGlobalCoords.h = 0;
- m_LocalToGlobalCoords.v = 0;
- ::LocalToGlobal(&m_LocalToGlobalCoords);
-
- m_bItsOKToDoAnInterruptBlit = TRUE;
-
- Rect dstR;
- dstR.left = dst.left;
- dstR.top = dst.top;
- dstR.right = dst.right;
- dstR.bottom = dst.bottom;
- // Forcing the source rect to equal the destination rect; all the
- // complicated math actually takes place elsewhere so this is an
- // OK thing to do.
- Rect srcR = dstR;
- if (CHXMacSite::zm_bFullScreenActive)
- {
- CHXMacSite* pMacSite = (CHXMacSite*)m_pSite;
- if (!pMacSite->m_bInternalResizeOnFullscreen)
- {
- dstR.right = dstR.left + (long)(((double)dstR.right - (double)dstR.left)*pMacSite->m_fStretchMultiple);
- dstR.bottom = dstR.top + (long)(((double)dstR.bottom - (double)dstR.top)*pMacSite->m_fStretchMultiple);
- }
- }
- if (m_nBlitDepthEnum >= 0)
- {
- RGBColor blackRGB = {0x0000, 0x0000, 0x0000};
- RGBColor whiteRGB = {0xffff, 0xffff, 0xffff};
-
- ColorSpec prevFore;
- ColorSpec prevBack;
-
- ::SaveFore(&prevFore);
- ::SaveBack(&prevBack);
-
- ::RGBForeColor(&blackRGB);
- ::RGBBackColor(&whiteRGB);
-
- ::CopyBits( (BitMap*)*m_RootGWorldPixMap[m_nBlitDepthEnum],
- GetPortBitMapForCopyBits(GetWindowPort(macWindow)),
- &srcR, &dstR, srcCopy, nil );
-
- ::QDFlushPortBuffer( ::GetWindowPort(macWindow), NULL );
- ::RestoreFore(&prevFore);
- ::RestoreBack(&prevBack);
- }
- SetOriginAndMaintainClipRgn(oldOrigin.h, oldOrigin.v);
- ::SetPort(savePort);
- }
- }
- unsigned long
- CMacRootSurface::_GetScreenPixelValue(long globX, long globY)
- {
- unsigned long retVal = 0;
- int whichDevice;
- for (whichDevice = 0; whichDevice < zm_uNumberOfAttachedDevices; whichDevice++)
- {
- HX_ASSERT(zm_AttachedDevice[whichDevice]);
-
- PixMapHandle thePMH = (**zm_AttachedDevice[whichDevice]).gdPMap;
- unsigned long dstPtr = (unsigned long)::GetPixBaseAddr(thePMH);
- int pixelSize = (**thePMH).pixelSize;
-
- Rect deviceRect = (**zm_AttachedDevice[whichDevice]).gdRect;
-
- if (globX >= deviceRect.left && globX <= deviceRect.right
- && globY >= deviceRect.top && globY <= deviceRect.bottom)
- {
- int rowOffset = (globY - deviceRect.top) * ((**thePMH).rowBytes & 0x3fff);
- int columnOffset = (globX - deviceRect.left) * pixelSize / 8;
- dstPtr += rowOffset + columnOffset;
- switch (pixelSize)
- {
- case 32:
- retVal = *(unsigned long*)dstPtr;
- break;
- case 16:
- retVal = *(unsigned short*)dstPtr;
- break;
- case 8:
- retVal = *(unsigned char*)dstPtr;
- break;
- }
- }
- }
- return retVal;
- }
- unsigned long
- CMacRootSurface::_GetGWorldPixelValue(int whichDepth, long x, long y)
- {
- unsigned long retVal = 0;
- unsigned long offscreenPtr = (unsigned long)GetPixBaseAddr(m_RootGWorldPixMap[whichDepth]);
- offscreenPtr += y * ((**m_RootGWorldPixMap[whichDepth]).rowBytes & 0x3fff);
- switch (whichDepth)
- {
- case kEightBitDepth:
- offscreenPtr += x;
- retVal = *(unsigned char*)offscreenPtr;
- break;
- case kSixteenBitDepth:
- offscreenPtr += 2*x;
- retVal = *(unsigned short*)offscreenPtr;
- break;
- case kThirtyTwoBitDepth:
- offscreenPtr += 4*x;
- retVal = *(unsigned long*)offscreenPtr;
- break;
- }
- return retVal;
- }
- /************************************************************************
- * Method:
- * CMacRootSurface::InternalReflectRect
- *
- * Note that theRectToBlit needs to be in global coords!
- *
- * This is the function that slams it home. All obscuring menus have
- * been taken care of. Any vis region holes have been taken care of.
- * The rectangles that arrive at this rectangle are honest-to-God
- * blittable rectangles.
- *
- */
- void
- CMacRootSurface::InternalReflectRect(Rect theRectToBlit)
- {
- int whichDevice;
- for (whichDevice = 0; whichDevice < zm_uNumberOfAttachedDevices; whichDevice++)
- {
- HX_ASSERT(zm_AttachedDevice[whichDevice]);
-
- PixMapHandle thePMH = (**zm_AttachedDevice[whichDevice]).gdPMap;
- unsigned char* dstPtr = (unsigned char*)::GetPixBaseAddr(thePMH);
- int pixelSize = (**thePMH).pixelSize;
-
- INT32 whichDepth = DepthToDepthEnum(pixelSize);
-
- if ( 1 /* m_RootSurfaceGWorld[whichDepth] */ ) // <== this may be useful later but for now I want the assert to be executed that's maybe a dozen lines down.
- {
- Rect deviceRect = (**zm_AttachedDevice[whichDevice]).gdRect;
-
- Rect intersectionRect; // <== should always be equal to theRectToBlit I think XXXbobclark
- if (::SectRect(&theRectToBlit, &deviceRect, &intersectionRect))
- {
- // XXXbobclark
- // in the old site code we manually trimmed theRectToBlit to the limits of
- // intersectionRect; but since nowadays we're supposedly ensuring that we're
- // only getting rects wholly enclosed by their monitors we shouldn't need
- // to do that. Theoretically the only reason to do SectRect is to see if
- // this is actually the monitor that we need to blit to right now.
-
-
- HX_ASSERT(m_RootSurfaceGWorld[whichDepth]);
- if (!m_RootSurfaceGWorld[whichDepth]) return;
-
- unsigned char* offscreenPtr = (unsigned char*)GetPixBaseAddr(m_RootGWorldPixMap[whichDepth]);
-
- int localLeft = intersectionRect.left - m_LocalToGlobalCoords.h;
- int localTop = intersectionRect.top - m_LocalToGlobalCoords.v;
- int localRight = intersectionRect.right - m_LocalToGlobalCoords.h;
- int localBottom = intersectionRect.bottom - m_LocalToGlobalCoords.v;
-
- int localScreenLeft = intersectionRect.left - (**zm_AttachedDevice[whichDevice]).gdRect.left;
- int localScreenRight = intersectionRect.right - (**zm_AttachedDevice[whichDevice]).gdRect.left;
- int localScreenTop = intersectionRect.top - (**zm_AttachedDevice[whichDevice]).gdRect.top;
- int localScreenBottom = intersectionRect.bottom - (**zm_AttachedDevice[whichDevice]).gdRect.top;
-
- for (int localScreenRow = localScreenTop; localScreenRow < localScreenBottom; localScreenRow++)
- {
- int bytesPerPixel = pixelSize / 8;
- if (bytesPerPixel >= 1) // only ITB if at least 8-bit monitor
- {
- int localRow = (localScreenRow-localScreenTop) + localTop;
- long offscreenOffset = ((**m_RootGWorldPixMap[whichDepth]).rowBytes & 0x3fff) * localRow + localLeft * bytesPerPixel;
- long localScreenOffset = ((**thePMH).rowBytes & 0x3fff) * localScreenRow + localScreenLeft * bytesPerPixel;
-
- long srcP = (long)offscreenPtr + offscreenOffset;
- long dstP = (long)dstPtr + localScreenOffset;
-
- switch (bytesPerPixel)
- {
- case 4:
- // XXXbobclark
- // now we'll trash srcP and dstP...
- // it turns out that poking longs by hand is a lot faster
- // than going through BlockMoveData for some reason. In a
- // simplified test case, it was using 7-8 microseconds for
- // poking by hand, compared to 17-18 microseconds for using
- // BlockMoveData.
-
- {
- long maxP = dstP + (localRight-localLeft) * bytesPerPixel;
- for ( ; dstP < maxP; )
- {
- // if the pixel is lined up on an eight-byte boundary
- // and won't overwrite the right edge of the rectangle
- // then copy eight bytes at once.
- if ( (dstP % 8 == 0) && (maxP - dstP >= 8) )
- {
- *(double*)dstP = *(double*)srcP;
- srcP += 8;
- dstP += 8;
- }
- else
- {
- *(long*)dstP = *(long*)srcP;
- srcP += 4;
- dstP += 4;
- }
- }
- }
- break;
-
- default:
- // XXXbobclark
- // I could do something similar to the 32-bit case here,
- // where I attempt to outdo BlockMoveData()... but for
- // one thing, it would be even clunkier, since I'd need
- // more cases when it doesn't happen to line up on eight-
- // byte boundaries for super-fast copies, plus non-32-bit
- // cases are rarer than 32-bit cases.
- ::BlockMoveData( (void*)srcP, (void*)dstP, (localRight-localLeft)*bytesPerPixel );
- break;
- }
- }
- }
- }
- }
- }
- }
- /************************************************************************
- * Method:
- * CMacRootSurface::InternalReflectRectInVisRegion
- *
- * Note that theRectToBlit needs to be in global coords!
- *
- */
- void
- CMacRootSurface::InternalReflectRectInVisRegion(Rect theRectToBlit)
- {
- CHXSimpleList::Iterator ndx = m_pVisRgnRects->Begin();
- for (; ndx != m_pVisRgnRects->End(); ++ndx)
- {
- Rect* r = (Rect*)(*ndx);
-
- Rect blittableRect = theRectToBlit;
-
- if (blittableRect.left < r->left) blittableRect.left = r->left;
- if (blittableRect.top < r->top) blittableRect.top = r->top;
- if (blittableRect.right > r->right) blittableRect.right = r->right;
- if (blittableRect.bottom > r->bottom) blittableRect.bottom = r->bottom;
-
- if (blittableRect.left < blittableRect.right && blittableRect.top < blittableRect.bottom)
- {
- InternalReflectRect(blittableRect);
- }
- }
- }
- /************************************************************************
- * Method:
- * CMacRootSurface::PotentiallyAddRect
- *
- * Useful shortcut for constructing lists of rectangles for
- * menu-down blitting.
- *
- */
- void
- CMacRootSurface::PotentiallyAddRect( CHXSimpleList* theList, Rect originalVisRect, short left, short top, short right, short bottom )
- {
- if ( left < originalVisRect.left ) left = originalVisRect.left;
- if ( top < originalVisRect.top ) top = originalVisRect.top;
- if ( right > originalVisRect.right ) right = originalVisRect.right;
- if ( bottom > originalVisRect.bottom ) bottom = originalVisRect.bottom;
-
- if ( left < right && top < bottom )
- {
- // OK, it's a legal rect so let's add it.
- Rect* r = new Rect;
- r->left = left;
- r->top = top;
- r->right = right;
- r->bottom = bottom;
- theList->AddTail( r );
- }
- }
- /************************************************************************
- * Method:
- * CMacRootSurface::ReflectRectToFullScreen
- *
- * Note that theOriginalRectToBlit needs to be in global coords!
- *
- */
- void
- CMacRootSurface::ReflectRectToFullScreen(Rect theOriginalRectToBlit)
- {
- // xxxbobclark assumptions include that this rectangle
- // is smaller than the main screen (which is where it
- // assumes the full-screen is playing).
-
- // See InternalReflectRect for details of what up
-
- HX_ASSERT(CHXMacSite::zm_bFullScreenActive);
-
- int whichDevice;
- for (whichDevice = 0; whichDevice < zm_uNumberOfAttachedDevices; whichDevice++)
- {
- PixMapHandle thePMH = (**zm_AttachedDevice[whichDevice]).gdPMap;
- unsigned char* dstPtr = (unsigned char*)::GetPixBaseAddr(thePMH);
- int honestScreenRowBytes = (**thePMH).rowBytes & 0x3fff;
- int pixelSize = (**thePMH).pixelSize;
-
- INT32 whichDepth = DepthToDepthEnum(pixelSize);
-
- if (m_RootSurfaceGWorld[whichDepth])
- {
- Rect adjustedRect;
- CHXMacSite* pMacSite = (CHXMacSite*)m_pSite;
- double stretch = pMacSite->m_fStretchMultiple;
-
- adjustedRect.left = theOriginalRectToBlit.left + stretch * (theOriginalRectToBlit.left - m_LocalToGlobalCoords.h);
- adjustedRect.top = theOriginalRectToBlit.top + stretch * (theOriginalRectToBlit.top - m_LocalToGlobalCoords.v);
- adjustedRect.right = theOriginalRectToBlit.left + stretch * (theOriginalRectToBlit.right - m_LocalToGlobalCoords.h);
- adjustedRect.bottom = theOriginalRectToBlit.top + stretch * (theOriginalRectToBlit.bottom - m_LocalToGlobalCoords.v);
-
- Rect deviceRect = (**zm_AttachedDevice[whichDevice]).gdRect;
- if (adjustedRect.left >= deviceRect.left
- && adjustedRect.top >= deviceRect.top
- && adjustedRect.right <= deviceRect.right
- && adjustedRect.bottom <= deviceRect.bottom)
- {
- // xxxbobclark whew, we can blit here since it's full
- // screen and wholly enclosed.
-
- int bytesPerPixel = pixelSize / 8;
- if (bytesPerPixel < 1) return; // ack, can't handle less than 8-bit!
-
- unsigned char* offscreenPtr = (unsigned char*)GetPixBaseAddr(m_RootGWorldPixMap[whichDepth]);
- int honestOffscreenRowBytes = (**m_RootGWorldPixMap[whichDepth]).rowBytes & 0x3fff;
-
- int fromLeft = theOriginalRectToBlit.left - m_LocalToGlobalCoords.h;
- int fromTop = theOriginalRectToBlit.top - m_LocalToGlobalCoords.v;
- int fromRight = theOriginalRectToBlit.right - m_LocalToGlobalCoords.h;
- int fromBottom = theOriginalRectToBlit.bottom - m_LocalToGlobalCoords.v;
-
- for (int fromRow = fromTop; fromRow < fromBottom; fromRow++)
- {
- for (int fromColumn = fromLeft; fromColumn < fromRight; fromColumn++)
- {
- // xxxbobclark OK now here we have one pixel
- // in the offscreen. This could grow to
- // multiple pixels on screen so we'll have to
- // blit all of them.
-
- long* pixelPtr = (long*)((long)offscreenPtr + fromRow*(long)honestOffscreenRowBytes);
- pixelPtr = (long*)((long)pixelPtr + bytesPerPixel * fromColumn);
-
- long pixelValue = *pixelPtr;
-
- // ok, got the pixel value, now figure out where all we
- // need to poke it.
-
- int destLeft = (int)((double)(fromColumn - fromLeft) * stretch + (double)adjustedRect.left);
- int destTop = (int)((double)(fromRow - fromTop) * stretch + (double)adjustedRect.top);
- int destRight = (int)((double)(fromColumn - fromLeft + 1) * stretch + (double)adjustedRect.left);
- int destBottom = (int)((double)(fromRow - fromTop + 1) * stretch + (double)adjustedRect.top);
-
- pixelPtr = (long*)((long)dstPtr + destTop * honestScreenRowBytes);
- pixelPtr = (long*)((long)pixelPtr + bytesPerPixel * destLeft);
-
- for (int destRow = destTop; destRow < destBottom; destRow++)
- {
- for (int destColumn = destLeft; destColumn < destRight; destColumn++)
- {
- *pixelPtr = pixelValue;
-
- pixelPtr = (long*)((long)pixelPtr + bytesPerPixel);
- }
- pixelPtr = (long*)((long)pixelPtr + honestScreenRowBytes - (bytesPerPixel * (destRight-destLeft)));
- }
- }
- }
- }
- }
- }
- }
- /************************************************************************
- * Method:
- * CMacRootSurface::DepthToDepthEnum
- */
- int
- CMacRootSurface::DepthToDepthEnum( short depth )
- {
- int result = kEightBitDepth;
- switch ( depth )
- {
- case 32:
- result = kThirtyTwoBitDepth;
- break;
- case 16:
- result = kSixteenBitDepth;
- break;
- }
- return result;
- }
- /************************************************************************
- * Method:
- * CMacRootSurface::VisRgnChangedCallback
- *
- * This is called from several trap patches which can
- * change the vis region. This prevents subsequent blits
- * until the vis region we know about can be updated.
- */
- /* static */
- pascal void
- CMacRootSurface::VisRgnChangedCallback(void)
- {
- #ifndef _MAC_UNIX
- HXMM_INTERRUPTON();
- #endif
- // since the visRgn probably changed in the patched trap, let's wait until
- // we can update our version of the visRgn before doing any more interrupt-
- // time blits.
-
- CHXSimpleList::Iterator ndxSite = zm_RootSurfaceList.Begin();
- for (; ndxSite != zm_RootSurfaceList.End(); ++ndxSite)
- {
- CMacRootSurface* pRootSurface = (CMacRootSurface*)(*ndxSite);
-
- if ( pRootSurface )
- {
- pRootSurface->m_bItsOKToDoAnInterruptBlit = FALSE;
- }
- }
-
- if (CMacSurface::zm_pOverlaySurface)
- {
- CMacSurface::zm_bSafeToOverlayBlit = FALSE;
- }
- #ifndef _MAC_UNIX
- HXMM_INTERRUPTOFF();
- #endif
- }
- #define kSizeOfSimpleRectangleRegion 10
- /************************************************************************
- * 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
- *
- */
- 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;
- }