macroot.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:44k
源码类别:

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: macroot.cpp,v 1.7.20.1 2004/07/09 01:59:02 hubbe Exp $
  3.  * 
  4.  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
  5.  * 
  6.  * The contents of this file, and the files included with this file,
  7.  * are subject to the current version of the RealNetworks Public
  8.  * Source License (the "RPSL") available at
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10.  * the file under the current version of the RealNetworks Community
  11.  * Source License (the "RCSL") available at
  12.  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
  13.  * will apply. You may also obtain the license terms directly from
  14.  * RealNetworks.  You may not use this file except in compliance with
  15.  * the RPSL or, if you have a valid RCSL with RealNetworks applicable
  16.  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
  17.  * the rights, obligations and limitations governing use of the
  18.  * contents of the file.
  19.  * 
  20.  * Alternatively, the contents of this file may be used under the
  21.  * terms of the GNU General Public License Version 2 or later (the
  22.  * "GPL") in which case the provisions of the GPL are applicable
  23.  * instead of those above. If you wish to allow use of your version of
  24.  * this file only under the terms of the GPL, and not to allow others
  25.  * to use your version of this file under the terms of either the RPSL
  26.  * or RCSL, indicate your decision by deleting the provisions above
  27.  * and replace them with the notice and other provisions required by
  28.  * the GPL. If you do not delete the provisions above, a recipient may
  29.  * use your version of this file under the terms of any one of the
  30.  * RPSL, the RCSL or the GPL.
  31.  * 
  32.  * This file is part of the Helix DNA Technology. RealNetworks is the
  33.  * developer of the Original Code and owns the copyrights in the
  34.  * portions it created.
  35.  * 
  36.  * This file, and the files included with this file, is distributed
  37.  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
  38.  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
  39.  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
  40.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
  41.  * ENJOYMENT OR NON-INFRINGEMENT.
  42.  * 
  43.  * Technology Compatibility Kit Test Suite(s) Location:
  44.  *    http://www.helixcommunity.org/content/tck
  45.  * 
  46.  * Contributor(s):
  47.  * 
  48.  * ***** END LICENSE BLOCK ***** */
  49. #include "hxcom.h"
  50. #include "hxtypes.h"
  51. #include "hxwintyp.h"
  52. #include "hxmap.h"
  53. #include "hxslist.h"
  54. #include "ihxpckts.h"
  55. #include "hxwin.h"
  56. #include "hxengin.h"
  57. #include "hxsite2.h"
  58. #include "chxxtype.h"
  59. #include "hxvctrl.h"
  60. #include "hxvsurf.h"
  61. #include "hxcodec.h"
  62. #include "surface.h"
  63. #include "vidosurf.h"
  64. #include "sitetext.h"
  65. #include "chxpckts.h"
  66. #include "hxevent.h"
  67. #include "bltpatch.h"
  68. #include "hxprefs.h"
  69. #include "hxevent.h"
  70. #include "hxthread.h"
  71. #include "basesite.h"
  72. #include "platform/mac/macroot.h"
  73. #include "platform/mac/macsite.h"
  74. #include "platform/mac/macsurf.h"
  75. #include "platform/mac/hx_moreprocesses.h"
  76. #ifndef _MAC_UNIX
  77. #include "hxmm.h"
  78. #endif
  79. #include "hxcore.h"
  80. #ifndef _MACINTOSH
  81. #ifndef _MAC_UNIX
  82. #error This is the Macintosh platform specific implementation.
  83. #endif
  84. #endif
  85. #if !defined(_CARBON) && !defined(_MAC_UNIX)
  86. #error This is an OS X and later implementation!
  87. #endif
  88. #include "hxheap.h"
  89. #ifdef _DEBUG
  90. #undef HX_THIS_FILE
  91. static const char HX_THIS_FILE[] = __FILE__;
  92. #endif
  93. UINT32 CMacRootSurface::zm_uNumberOfAttachedDevices = 0;
  94. GDHandle CMacRootSurface::zm_AttachedDevice[CMacRootSurface::kMaxMonitors];
  95. CHXSimpleList CMacRootSurface::zm_RootSurfaceList;
  96. CMacRootSurface::OverlayInfoStruct CMacRootSurface::zm_OverlayInfo[CMacRootSurface::kMaxMonitors];
  97. /************************************************************************
  98.  *  Method:
  99.  *    CMacRootSurface constructor
  100.  */
  101. CMacRootSurface::CMacRootSurface(IUnknown* pContext, CHXBaseSite* pSite)
  102.  : CBaseRootSurface(pContext, pSite)
  103.  , m_bItsOKToDoAnInterruptBlit(FALSE)
  104.  , m_pVisRgnRects(NULL)
  105.  , m_LastVisRgn(NULL)
  106.  , m_bNeedToForceVisRgnUpdate(FALSE)
  107.  , m_nBlitDepthEnum(-1)
  108.  , m_bInBlueBox(FALSE)
  109.  , m_bAllowedToITBInBlueBox(TRUE)
  110. {
  111.     m_pVisRgnRects = new CHXSimpleList();
  112.     
  113.     int i;
  114.     for (i = 0; i < kNumberOfDepths; i++)
  115.     {
  116. m_RootSurfaceGWorld[i] = nil;
  117. m_RootGWorldPixMap[i] = nil;
  118.     }
  119.     if (zm_uNumberOfAttachedDevices == 0)
  120.     {
  121. // OK, first zero it all out
  122. for (i=0; i < kMaxMonitors; i++)
  123. {
  124.     zm_AttachedDevice[i] = NULL;
  125.     
  126.     zm_OverlayInfo[i].b_OverlayExists = FALSE;
  127.     zm_OverlayInfo[i].b_OverlayInitialized = FALSE;
  128. }
  129. // now fill it in with all attached devices!
  130. // check for multiple monitors. Also grab main device...
  131. GDHandle mainGD = ::GetMainDevice();
  132. GDHandle gdH = ::GetDeviceList();
  133. while ( gdH )
  134. {
  135.     zm_AttachedDevice[zm_uNumberOfAttachedDevices] = gdH;
  136.     zm_uNumberOfAttachedDevices++;
  137.     gdH = ::GetNextDevice( gdH );
  138.     
  139.     if (zm_uNumberOfAttachedDevices >= kMaxMonitors)
  140.     {
  141. gdH = nil; // stop counting after ten monitors!
  142.     }
  143. }
  144.     }
  145.     
  146.     long blueBoxParams = 0;
  147.     short err = Gestalt('bbox', &blueBoxParams);
  148.     if (!err && blueBoxParams & 0x00000001)
  149.     {
  150. m_bInBlueBox = TRUE;
  151.     }
  152.     
  153.     m_LocalToGlobalCoords.h = -32768;
  154.     m_LocalToGlobalCoords.v = -32768;
  155.     zm_RootSurfaceList.AddTail(this);
  156. }
  157. /************************************************************************
  158.  *  Method:
  159.  *    CMacRootSurface destructor
  160.  */
  161. CMacRootSurface::~CMacRootSurface()
  162. {
  163.     LISTPOSITION pos = zm_RootSurfaceList.Find(this);
  164.     zm_RootSurfaceList.RemoveAt(pos);
  165.     
  166.     int i;
  167.     for (i = 0; i < kNumberOfDepths; i++)
  168.     {
  169. if (m_RootSurfaceGWorld[i] != NULL)
  170. {
  171.     ::UnlockPixels(m_RootGWorldPixMap[i]);
  172.     ::DisposeGWorld(m_RootSurfaceGWorld[i]);
  173.     m_RootSurfaceGWorld[i] = NULL;
  174.     m_RootGWorldPixMap[i] = NULL;
  175. }
  176.     }
  177.     
  178.     if (m_LastVisRgn)
  179.     {
  180. ::DisposeRgn(m_LastVisRgn);
  181. m_LastVisRgn = nil;
  182.     }
  183.     delete m_pVisRgnRects;
  184.     m_pVisRgnRects = NULL;
  185. }
  186. /************************************************************************
  187.  *  Method:
  188.  *    CMacRootSurface::_GetYUVScratchWidthHeight
  189.  */
  190. void
  191. CMacRootSurface::_GetYUVScratchWidthHeight(UINT32* pWidth, UINT32* pHeight)
  192. {
  193. }
  194. /************************************************************************
  195.  *  Method:
  196.  *    CMacRootSurface::_CreateYUVScratchSurface
  197.  */
  198. void
  199. CMacRootSurface::_CreateYUVScratchSurface(UINT32 width, UINT32 height)
  200. {
  201. }
  202. /************************************************************************
  203.  *  Method:
  204.  *    CMacRootSurface::_GetYUVScratchSurfacePointer
  205.  */
  206. void
  207. CMacRootSurface::_GetYUVScratchSurfacePointer(UCHAR** pYUVBits, INT32* YUVPitch)
  208. {
  209. }
  210. /************************************************************************
  211.  *  Method:
  212.  *    CMacRootSurface::CreateScratchSurface
  213.  */
  214. HX_RESULT
  215. CMacRootSurface::CreateScratchSurface(int nCompositionSurfaceCID, HXxSize* pSize)
  216. {
  217.     return HXR_OK;
  218. }
  219. /************************************************************************
  220.  *  Method:
  221.  *    CMacRootSurface::ScratchLock
  222.  */
  223. HX_RESULT
  224. CMacRootSurface::ScratchLock(UCHAR** pBits, INT32* pPitch_)
  225. {
  226.     return HXR_OK;
  227. }
  228. /************************************************************************
  229.  *  Method:
  230.  *    CMacRootSurface::ScratchUnlock
  231.  */
  232. HX_RESULT
  233. CMacRootSurface::ScratchUnlock(UCHAR* pBits)
  234. {
  235.     return HXR_OK;
  236. }
  237. /************************************************************************
  238.  *  Method:
  239.  *    CMacRootSurface::_BltFromScratchToComposition
  240.  */
  241. void
  242. CMacRootSurface::_BltFromScratchToComposition(HXxRect& rDestRect, HXxRect& rSrcRect)
  243. {
  244. }
  245. /************************************************************************
  246.  *  Method:
  247.  *    CMacRootSurface::_DebugBlt
  248.  */
  249. HX_RESULT
  250. CMacRootSurface::_DebugBlt( UCHAR*               pImageData,
  251.                         HXBitmapInfoHeader* pBitmapInfo,
  252.                         REF(HXxRect)         rDestRect,
  253.                         REF(HXxRect)         rSrcRect)
  254. {
  255.     return HXR_OK;
  256. }
  257. /************************************************************************
  258.  *  Method:
  259.  *    CMacRootSurface::_MinimalUnlock
  260.  */
  261. HX_RESULT
  262. CMacRootSurface::_MinimalUnlock(HXxWindow* pWindow)
  263. {
  264.     return HXR_OK;
  265. }
  266. /************************************************************************
  267.  *  Method:
  268.  *    CMacRootSurface::_LockComposition
  269.  */
  270. HX_RESULT
  271. CMacRootSurface::_LockComposition(UCHAR** pBits, INT32* pPitch)
  272. {
  273.     if (m_bItsOKToDoAnInterruptBlit)
  274.     {
  275.         // if the OK to ITB boolean still needs to be set,
  276.         // the region will be force-updated at an appropriate
  277.         // time.
  278.         
  279.         // ensure that region is updated.
  280.         Rect r;
  281.         r.left = m_boundsRect.left;
  282.         r.top = m_boundsRect.top;
  283.         r.right = m_boundsRect.right;
  284.         r.bottom = m_boundsRect.bottom;
  285.         UpdateRegionIfNecessary(r, m_LocalToGlobalCoords, m_bNeedToForceVisRgnUpdate);
  286.         m_bNeedToForceVisRgnUpdate = FALSE;
  287.     }
  288.     return HXR_OK;
  289. }
  290. /************************************************************************
  291.  *  Method:
  292.  *    CMacRootSurface::_CreateCompositionSurface
  293.  */
  294. HX_RESULT
  295. CMacRootSurface::_CreateCompositionSurface()
  296. {
  297.     // XXXbobclark The composition surface -- where stuff gets blitted
  298.     // on an interim basis prior to being blitted straight to the screen
  299.     // -- works most optimally if it's the same depth as the screen.
  300.     // When all this shtuff was in comlib I did this by having possibly
  301.     // three interim GWorlds, one each of depths 8-bit, 16-bit, and 32-bit.
  302.     // Note that interrupt-time blitting REQUIRES a composition surface of the
  303.     // same depth as the screen 'cause CopyBits() doesn't work. And multiple
  304.     // monitors imply that multiple depths may need to be active simultaneously.
  305.     // Since this gets called so often I'll never dispose the GWorld
  306.     // in _DestroyCompositionSurface() so it won't recreate it here. But if
  307.     // it stays this way then I'll need to check the size here to see if I
  308.     // need to dispose the current GWorld and create a new, correctly-sized
  309.     // one.
  310.     if (m_compositionSize.cx > m_allocatedCompositionSize.cx || m_compositionSize.cy > m_allocatedCompositionSize.cy)
  311.     {
  312. ::UnlockPixels(m_RootGWorldPixMap[kThirtyTwoBitDepth]);
  313. ::DisposeGWorld(m_RootSurfaceGWorld[kThirtyTwoBitDepth]);
  314. m_RootSurfaceGWorld[kThirtyTwoBitDepth] = nil;
  315. m_RootGWorldPixMap[kThirtyTwoBitDepth] = nil;
  316. m_pCompositionSurface = nil;
  317. m_nBlitDepthEnum = -1;
  318.     }
  319.     
  320.     if (!m_pCompositionSurface)
  321.     {
  322. short thePixelDepth = 32;
  323. Rect r;
  324. SetRect(&r, 0, 0, m_compositionSize.cx, m_compositionSize.cy);
  325. // It's possible that this is getting called extremely often -- like
  326. // once per blit! and it's also getting called occasionally at interrupt
  327. // time. So I need to get this being built at appropriate times only,
  328. // and then I think that copying it over in _MinimalBlt() I can blit it over
  329. // to the window and maybe just maybe I'll have something visible. Sheesh.
  330. ::NewGWorld(&m_RootSurfaceGWorld[kThirtyTwoBitDepth], thePixelDepth, &r, nil, nil, useTempMem);
  331. if (!m_RootSurfaceGWorld[kThirtyTwoBitDepth])
  332. {
  333.     // it failed to create it in temp mem so try creating it in the application heap.
  334.     ::NewGWorld(&m_RootSurfaceGWorld[kThirtyTwoBitDepth], thePixelDepth, &r, nil, nil, 0);
  335.     
  336.     if (!m_RootSurfaceGWorld[kThirtyTwoBitDepth]) return HXR_FAIL;
  337. }
  338. m_RootGWorldPixMap[kThirtyTwoBitDepth] = GetPortPixMap(m_RootSurfaceGWorld[kThirtyTwoBitDepth]);
  339. ::LockPixels(m_RootGWorldPixMap[kThirtyTwoBitDepth]);
  340. m_pCompositionSurface = (unsigned char*)GetPixBaseAddr(m_RootGWorldPixMap[kThirtyTwoBitDepth]);
  341. m_nBlitDepthEnum = kThirtyTwoBitDepth;
  342. m_allocatedCompositionSize = m_compositionSize;
  343. m_nCompositionPitch = (**m_RootGWorldPixMap[kThirtyTwoBitDepth]).rowBytes & 0x3fff;
  344. m_boundsRect.left = r.left;
  345. m_boundsRect.top = r.top;
  346. m_boundsRect.right = r.right;
  347. m_boundsRect.bottom = r.bottom;
  348. m_nCompositionSurfaceCID = CID_RGB32;
  349.     }
  350.     return HXR_OK;
  351. }
  352. /************************************************************************
  353.  *  Method:
  354.  *    CMacRootSurface::_DestroyCompositionSurface
  355.  */
  356. HX_RESULT
  357. CMacRootSurface::_DestroyCompositionSurface()
  358. {
  359.     // XXXbobclark I've gotta figure out what the story is here,
  360.     // 'cause right now it's getting called every blit.
  361.     // I certainly don't want to be destroying the whole GWorld!
  362.     // So currently I'll never destroy it. Ehhh.
  363.     
  364.     return HXR_OK;
  365. }
  366. /************************************************************************
  367.  *  Method:
  368.  *    CMacRootSurface::_MinimalBlt
  369.  */
  370. void
  371. CMacRootSurface::_MinimalBlt(HXxRect& src, HXxRect& dst)
  372. {
  373.     {
  374. GrafPtr savePort;
  375. ::GetPort(&savePort);
  376. WindowPtr macWindow;
  377. macWindow = m_pSite->m_pWindow ? (WindowPtr)m_pSite->m_pWindow->window : NULL;
  378. if (CHXMacSite::zm_bFullScreenActive)
  379. {
  380.     CHXMacSite* pMacSite = (CHXMacSite*)m_pSite;
  381.     if (pMacSite->m_pHXxFullScreenWindow)
  382.     {
  383. macWindow = (WindowPtr)pMacSite->m_pHXxFullScreenWindow->window;
  384.     }
  385. }
  386. ::SetPort(GetWindowPort(macWindow));
  387. // XXXbobclark The "old site" surface implementation's innermost
  388. // blitting API, "BltImage", always happened to have the dest
  389. // rectangle at (0,0) and relied on SetOrigin to set it up
  390. // correctly. The "new site" implementation's innermost blittin
  391. // API is "_MinimalBlt", and in this case the rectangle is relative
  392. // to the core's area. So I remember the current origin (so I can
  393. // restore it 'cause some renderers need it) and reset it to the
  394. // core's offset.
  395. Point oldOrigin;
  396. Rect portRect;
  397. GetPortBounds(GetWindowPort(macWindow), &portRect);
  398. oldOrigin.h = portRect.left;
  399. oldOrigin.v = portRect.top;
  400. HXxWindow* pWindow = m_pSite->GetWindow();
  401. if (pWindow)
  402. {
  403.     SetOriginAndMaintainClipRgn(-pWindow->x,-pWindow->y);
  404. }
  405. m_LocalToGlobalCoords.h = 0;
  406. m_LocalToGlobalCoords.v = 0;
  407. ::LocalToGlobal(&m_LocalToGlobalCoords);
  408. m_bItsOKToDoAnInterruptBlit = TRUE;
  409. Rect dstR;
  410. dstR.left = dst.left;
  411. dstR.top = dst.top;
  412. dstR.right = dst.right;
  413. dstR.bottom = dst.bottom;
  414. // Forcing the source rect to equal the destination rect; all the
  415. // complicated math actually takes place elsewhere so this is an
  416. // OK thing to do.
  417. Rect srcR = dstR;
  418. if (CHXMacSite::zm_bFullScreenActive)
  419. {
  420.     CHXMacSite* pMacSite = (CHXMacSite*)m_pSite;
  421.     if (!pMacSite->m_bInternalResizeOnFullscreen)
  422.     {
  423. dstR.right = dstR.left + (long)(((double)dstR.right - (double)dstR.left)*pMacSite->m_fStretchMultiple);
  424. dstR.bottom = dstR.top + (long)(((double)dstR.bottom - (double)dstR.top)*pMacSite->m_fStretchMultiple);
  425.     }
  426. }
  427. if (m_nBlitDepthEnum >= 0)
  428. {
  429.     RGBColor blackRGB = {0x0000, 0x0000, 0x0000};
  430.     RGBColor whiteRGB = {0xffff, 0xffff, 0xffff};
  431.     
  432.     ColorSpec prevFore;
  433.     ColorSpec prevBack;
  434.     
  435.     ::SaveFore(&prevFore);
  436.     ::SaveBack(&prevBack);
  437.     
  438.     ::RGBForeColor(&blackRGB);
  439.     ::RGBBackColor(&whiteRGB);
  440.             
  441.     ::CopyBits( (BitMap*)*m_RootGWorldPixMap[m_nBlitDepthEnum],
  442.     GetPortBitMapForCopyBits(GetWindowPort(macWindow)),
  443.     &srcR, &dstR, srcCopy, nil );
  444.     
  445.     ::QDFlushPortBuffer( ::GetWindowPort(macWindow), NULL );
  446.     ::RestoreFore(&prevFore);
  447.     ::RestoreBack(&prevBack);
  448. }
  449. SetOriginAndMaintainClipRgn(oldOrigin.h, oldOrigin.v);
  450. ::SetPort(savePort);
  451.     }
  452. }
  453. unsigned long
  454. CMacRootSurface::_GetScreenPixelValue(long globX, long globY)
  455. {
  456.     unsigned long retVal = 0;
  457.     int whichDevice;
  458.     for (whichDevice = 0; whichDevice < zm_uNumberOfAttachedDevices; whichDevice++)
  459.     {
  460. HX_ASSERT(zm_AttachedDevice[whichDevice]);
  461. PixMapHandle thePMH = (**zm_AttachedDevice[whichDevice]).gdPMap;
  462. unsigned long dstPtr = (unsigned long)::GetPixBaseAddr(thePMH);
  463. int pixelSize = (**thePMH).pixelSize;
  464. Rect deviceRect = (**zm_AttachedDevice[whichDevice]).gdRect;
  465. if (globX >= deviceRect.left && globX <= deviceRect.right
  466. && globY >= deviceRect.top && globY <= deviceRect.bottom)
  467. {
  468.     int rowOffset = (globY - deviceRect.top) * ((**thePMH).rowBytes & 0x3fff);
  469.     int columnOffset = (globX - deviceRect.left) * pixelSize / 8;
  470.     dstPtr += rowOffset + columnOffset;
  471.     switch (pixelSize)
  472.     {
  473. case 32:
  474.     retVal = *(unsigned long*)dstPtr;
  475.     break;
  476. case 16:
  477.     retVal = *(unsigned short*)dstPtr;
  478.     break;
  479. case 8:
  480.     retVal = *(unsigned char*)dstPtr;
  481.     break;
  482.     }
  483. }
  484.     }
  485.     return retVal;
  486. }
  487. unsigned long
  488. CMacRootSurface::_GetGWorldPixelValue(int whichDepth, long x, long y)
  489. {
  490.     unsigned long retVal = 0;
  491.     unsigned long offscreenPtr = (unsigned long)GetPixBaseAddr(m_RootGWorldPixMap[whichDepth]);
  492.     offscreenPtr += y * ((**m_RootGWorldPixMap[whichDepth]).rowBytes & 0x3fff);
  493.     switch (whichDepth)
  494.     {
  495. case kEightBitDepth:
  496.     offscreenPtr += x;
  497.     retVal = *(unsigned char*)offscreenPtr;
  498.     break;
  499. case kSixteenBitDepth:
  500.     offscreenPtr += 2*x;
  501.     retVal = *(unsigned short*)offscreenPtr;
  502.     break;
  503. case kThirtyTwoBitDepth:
  504.     offscreenPtr += 4*x;
  505.     retVal = *(unsigned long*)offscreenPtr;
  506.     break;
  507.     }
  508.     return retVal;
  509. }
  510. /************************************************************************
  511.  *  Method:
  512.  *    CMacRootSurface::InternalReflectRect
  513.  *
  514.  *    Note that theRectToBlit needs to be in global coords!
  515.  *
  516.  *    This is the function that slams it home. All obscuring menus have
  517.  *    been taken care of. Any vis region holes have been taken care of.
  518.  *    The rectangles that arrive at this rectangle are honest-to-God
  519.  *    blittable rectangles.
  520.  *
  521.  */
  522. void
  523. CMacRootSurface::InternalReflectRect(Rect theRectToBlit)
  524. {
  525.     int whichDevice;
  526.     for (whichDevice = 0; whichDevice < zm_uNumberOfAttachedDevices; whichDevice++)
  527.     {
  528. HX_ASSERT(zm_AttachedDevice[whichDevice]);
  529. PixMapHandle thePMH = (**zm_AttachedDevice[whichDevice]).gdPMap;
  530. unsigned char* dstPtr = (unsigned char*)::GetPixBaseAddr(thePMH);
  531. int pixelSize = (**thePMH).pixelSize;
  532. INT32 whichDepth = DepthToDepthEnum(pixelSize);
  533. 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.
  534. {
  535.     Rect deviceRect = (**zm_AttachedDevice[whichDevice]).gdRect;
  536.     
  537.     Rect intersectionRect; // <== should always be equal to theRectToBlit I think XXXbobclark
  538.     if (::SectRect(&theRectToBlit, &deviceRect, &intersectionRect))
  539.     {
  540. // XXXbobclark
  541. // in the old site code we manually trimmed theRectToBlit to the limits of
  542. // intersectionRect; but since nowadays we're supposedly ensuring that we're
  543. // only getting rects wholly enclosed by their monitors we shouldn't need
  544. // to do that. Theoretically the only reason to do SectRect is to see if
  545. // this is actually the monitor that we need to blit to right now.
  546. HX_ASSERT(m_RootSurfaceGWorld[whichDepth]);
  547. if (!m_RootSurfaceGWorld[whichDepth]) return;
  548. unsigned char* offscreenPtr = (unsigned char*)GetPixBaseAddr(m_RootGWorldPixMap[whichDepth]);
  549. int localLeft = intersectionRect.left - m_LocalToGlobalCoords.h;
  550. int localTop = intersectionRect.top - m_LocalToGlobalCoords.v;
  551. int localRight = intersectionRect.right - m_LocalToGlobalCoords.h;
  552. int localBottom = intersectionRect.bottom - m_LocalToGlobalCoords.v;
  553. int localScreenLeft = intersectionRect.left - (**zm_AttachedDevice[whichDevice]).gdRect.left;
  554. int localScreenRight = intersectionRect.right - (**zm_AttachedDevice[whichDevice]).gdRect.left;
  555. int localScreenTop = intersectionRect.top - (**zm_AttachedDevice[whichDevice]).gdRect.top;
  556. int localScreenBottom = intersectionRect.bottom - (**zm_AttachedDevice[whichDevice]).gdRect.top;
  557. for (int localScreenRow = localScreenTop; localScreenRow < localScreenBottom; localScreenRow++)
  558. {
  559.     int bytesPerPixel = pixelSize / 8;
  560.     if (bytesPerPixel >= 1) // only ITB if at least 8-bit monitor
  561.     {
  562. int localRow = (localScreenRow-localScreenTop) + localTop;
  563. long offscreenOffset = ((**m_RootGWorldPixMap[whichDepth]).rowBytes & 0x3fff) * localRow + localLeft * bytesPerPixel;
  564. long localScreenOffset = ((**thePMH).rowBytes & 0x3fff) * localScreenRow + localScreenLeft * bytesPerPixel;
  565. long srcP = (long)offscreenPtr + offscreenOffset;
  566. long dstP = (long)dstPtr + localScreenOffset;
  567. switch (bytesPerPixel)
  568. {
  569.     case 4:
  570. // XXXbobclark
  571. // now we'll trash srcP and dstP...
  572. // it turns out that poking longs by hand is a lot faster
  573. // than going through BlockMoveData for some reason. In a
  574. // simplified test case, it was using 7-8 microseconds for
  575. // poking by hand, compared to 17-18 microseconds for using
  576. // BlockMoveData.
  577. {
  578.                                     long maxP = dstP + (localRight-localLeft) * bytesPerPixel;
  579.                                     for ( ; dstP < maxP; )
  580.                                     {
  581.                                         // if the pixel is lined up on an eight-byte boundary
  582.                                         // and won't overwrite the right edge of the rectangle
  583.                                         // then copy eight bytes at once.
  584.                                         if ( (dstP % 8 == 0) && (maxP - dstP >= 8) )
  585.                                         {
  586.                                             *(double*)dstP = *(double*)srcP;
  587.                                             srcP += 8;
  588.                                             dstP += 8;
  589.                                         }
  590.                                         else
  591.                                         {
  592.                                             *(long*)dstP = *(long*)srcP;
  593.                                             srcP += 4;
  594.                                             dstP += 4;
  595.                                         }
  596.                                     }
  597.                                 }
  598. break;
  599.     
  600.     default:
  601. // XXXbobclark
  602. // I could do something similar to the 32-bit case here,
  603. // where I attempt to outdo BlockMoveData()... but for
  604. // one thing, it would be even clunkier, since I'd need
  605. // more cases when it doesn't happen to line up on eight-
  606. // byte boundaries for super-fast copies, plus non-32-bit
  607. // cases are rarer than 32-bit cases.
  608. ::BlockMoveData( (void*)srcP, (void*)dstP, (localRight-localLeft)*bytesPerPixel );
  609. break;
  610. }
  611.     }
  612. }
  613.     }
  614. }
  615.     }
  616. }
  617. /************************************************************************
  618.  *  Method:
  619.  *    CMacRootSurface::InternalReflectRectInVisRegion
  620.  *
  621.  *    Note that theRectToBlit needs to be in global coords!
  622.  *
  623.  */
  624. void
  625. CMacRootSurface::InternalReflectRectInVisRegion(Rect theRectToBlit)
  626. {
  627.     CHXSimpleList::Iterator ndx = m_pVisRgnRects->Begin();
  628.     for (; ndx != m_pVisRgnRects->End(); ++ndx)
  629.     {
  630. Rect* r = (Rect*)(*ndx);
  631. Rect blittableRect = theRectToBlit;
  632. if (blittableRect.left < r->left) blittableRect.left = r->left;
  633. if (blittableRect.top < r->top) blittableRect.top = r->top;
  634. if (blittableRect.right > r->right) blittableRect.right = r->right;
  635. if (blittableRect.bottom > r->bottom) blittableRect.bottom = r->bottom;
  636. if (blittableRect.left < blittableRect.right && blittableRect.top < blittableRect.bottom)
  637. {
  638.     InternalReflectRect(blittableRect);
  639. }
  640.     }
  641. }
  642. /************************************************************************
  643.  *  Method:
  644.  *    CMacRootSurface::PotentiallyAddRect
  645.  *
  646.  *    Useful shortcut for constructing lists of rectangles for
  647.  *    menu-down blitting.
  648.  *
  649.  */
  650. void
  651. CMacRootSurface::PotentiallyAddRect( CHXSimpleList* theList, Rect originalVisRect, short left, short top, short right, short bottom )
  652. {
  653.     if ( left < originalVisRect.left ) left = originalVisRect.left;
  654.     if ( top < originalVisRect.top ) top = originalVisRect.top;
  655.     if ( right > originalVisRect.right ) right = originalVisRect.right;
  656.     if ( bottom > originalVisRect.bottom ) bottom = originalVisRect.bottom;
  657.     
  658.     if ( left < right && top < bottom )
  659.     {
  660. // OK, it's a legal rect so let's add it.
  661. Rect* r = new Rect;
  662. r->left = left;
  663. r->top = top;
  664. r->right = right;
  665. r->bottom = bottom;
  666. theList->AddTail( r );
  667.     }
  668. }
  669. /************************************************************************
  670.  *  Method:
  671.  *    CMacRootSurface::ReflectRectToFullScreen
  672.  *
  673.  *    Note that theOriginalRectToBlit needs to be in global coords!
  674.  *
  675.  */
  676. void
  677. CMacRootSurface::ReflectRectToFullScreen(Rect theOriginalRectToBlit)
  678. {
  679.     // xxxbobclark assumptions include that this rectangle
  680.     // is smaller than the main screen (which is where it
  681.     // assumes the full-screen is playing).
  682.     
  683.     // See InternalReflectRect for details of what up
  684.     
  685.     HX_ASSERT(CHXMacSite::zm_bFullScreenActive);
  686.     
  687.     int whichDevice;
  688.     for (whichDevice = 0; whichDevice < zm_uNumberOfAttachedDevices; whichDevice++)
  689.     {
  690. PixMapHandle thePMH = (**zm_AttachedDevice[whichDevice]).gdPMap;
  691. unsigned char* dstPtr = (unsigned char*)::GetPixBaseAddr(thePMH);
  692. int honestScreenRowBytes = (**thePMH).rowBytes & 0x3fff;
  693. int pixelSize = (**thePMH).pixelSize;
  694. INT32 whichDepth = DepthToDepthEnum(pixelSize);
  695. if (m_RootSurfaceGWorld[whichDepth])
  696. {
  697.     Rect adjustedRect;
  698.     CHXMacSite* pMacSite = (CHXMacSite*)m_pSite;
  699.     double stretch = pMacSite->m_fStretchMultiple;
  700.     
  701.     adjustedRect.left = theOriginalRectToBlit.left + stretch * (theOriginalRectToBlit.left - m_LocalToGlobalCoords.h);
  702.     adjustedRect.top = theOriginalRectToBlit.top + stretch * (theOriginalRectToBlit.top - m_LocalToGlobalCoords.v);
  703.     adjustedRect.right = theOriginalRectToBlit.left + stretch * (theOriginalRectToBlit.right - m_LocalToGlobalCoords.h);
  704.     adjustedRect.bottom = theOriginalRectToBlit.top + stretch * (theOriginalRectToBlit.bottom - m_LocalToGlobalCoords.v);
  705.     
  706.     Rect deviceRect = (**zm_AttachedDevice[whichDevice]).gdRect;
  707.     if (adjustedRect.left >= deviceRect.left
  708. && adjustedRect.top >= deviceRect.top
  709. && adjustedRect.right <= deviceRect.right
  710. && adjustedRect.bottom <= deviceRect.bottom)
  711.     {
  712. // xxxbobclark whew, we can blit here since it's full
  713. // screen and wholly enclosed.
  714. int bytesPerPixel = pixelSize / 8;
  715. if (bytesPerPixel < 1) return; // ack, can't handle less than 8-bit!
  716. unsigned char* offscreenPtr = (unsigned char*)GetPixBaseAddr(m_RootGWorldPixMap[whichDepth]);
  717. int honestOffscreenRowBytes = (**m_RootGWorldPixMap[whichDepth]).rowBytes & 0x3fff;
  718. int fromLeft = theOriginalRectToBlit.left - m_LocalToGlobalCoords.h;
  719. int fromTop = theOriginalRectToBlit.top - m_LocalToGlobalCoords.v;
  720. int fromRight = theOriginalRectToBlit.right - m_LocalToGlobalCoords.h;
  721. int fromBottom = theOriginalRectToBlit.bottom - m_LocalToGlobalCoords.v;
  722. for (int fromRow = fromTop; fromRow < fromBottom; fromRow++)
  723. {
  724.     for (int fromColumn = fromLeft; fromColumn < fromRight; fromColumn++)
  725.     {
  726. // xxxbobclark OK now here we have one pixel
  727. // in the offscreen. This could grow to
  728. // multiple pixels on screen so we'll have to
  729. // blit all of them.
  730. long* pixelPtr = (long*)((long)offscreenPtr + fromRow*(long)honestOffscreenRowBytes);
  731. pixelPtr = (long*)((long)pixelPtr + bytesPerPixel * fromColumn);
  732. long pixelValue = *pixelPtr;
  733. // ok, got the pixel value, now figure out where all we
  734. // need to poke it.
  735. int destLeft = (int)((double)(fromColumn - fromLeft) * stretch + (double)adjustedRect.left);
  736. int destTop = (int)((double)(fromRow - fromTop) * stretch + (double)adjustedRect.top);
  737. int destRight = (int)((double)(fromColumn - fromLeft + 1) * stretch + (double)adjustedRect.left);
  738. int destBottom = (int)((double)(fromRow - fromTop + 1) * stretch + (double)adjustedRect.top);
  739. pixelPtr = (long*)((long)dstPtr + destTop * honestScreenRowBytes);
  740. pixelPtr = (long*)((long)pixelPtr + bytesPerPixel * destLeft);
  741. for (int destRow = destTop; destRow < destBottom; destRow++)
  742. {
  743.     for (int destColumn = destLeft; destColumn < destRight; destColumn++)
  744.     {
  745. *pixelPtr = pixelValue;
  746. pixelPtr = (long*)((long)pixelPtr + bytesPerPixel);
  747.     }
  748.     pixelPtr = (long*)((long)pixelPtr + honestScreenRowBytes - (bytesPerPixel * (destRight-destLeft)));
  749. }
  750.     }
  751. }
  752.     }
  753. }
  754.     }
  755. }
  756. /************************************************************************
  757.  *  Method:
  758.  *    CMacRootSurface::DepthToDepthEnum
  759.  */
  760. int
  761. CMacRootSurface::DepthToDepthEnum( short depth )
  762. {
  763.     int result = kEightBitDepth;
  764.     switch ( depth )
  765.     {
  766. case 32:
  767.     result = kThirtyTwoBitDepth;
  768.     break;
  769. case 16:
  770.     result = kSixteenBitDepth;
  771.     break;
  772.     }
  773.     return result;
  774. }
  775. /************************************************************************
  776.  *  Method:
  777.  *    CMacRootSurface::VisRgnChangedCallback
  778.  *
  779.  *    This is called from several trap patches which can
  780.  *    change the vis region. This prevents subsequent blits
  781.  *    until the vis region we know about can be updated.
  782.  */
  783. /* static */
  784. pascal void
  785. CMacRootSurface::VisRgnChangedCallback(void)
  786. {
  787. #ifndef _MAC_UNIX
  788.     HXMM_INTERRUPTON();
  789. #endif
  790.     // since the visRgn probably changed in the patched trap, let's wait until
  791.     // we can update our version of the visRgn before doing any more interrupt-
  792.     // time blits.
  793.     
  794.     CHXSimpleList::Iterator ndxSite = zm_RootSurfaceList.Begin();
  795.     for (;  ndxSite != zm_RootSurfaceList.End(); ++ndxSite)
  796.     {
  797. CMacRootSurface* pRootSurface = (CMacRootSurface*)(*ndxSite);
  798. if ( pRootSurface )
  799. {
  800.     pRootSurface->m_bItsOKToDoAnInterruptBlit = FALSE;
  801. }
  802.     }
  803.     
  804.     if (CMacSurface::zm_pOverlaySurface)
  805.     {
  806. CMacSurface::zm_bSafeToOverlayBlit = FALSE;
  807.     }
  808. #ifndef _MAC_UNIX
  809.     HXMM_INTERRUPTOFF();
  810. #endif
  811. }
  812. #define kSizeOfSimpleRectangleRegion 10
  813. /************************************************************************
  814.  *  Method:
  815.  *    CMacRootSurface::CheckRectRgn
  816.  *
  817.  */
  818. void CMacRootSurface::CheckRectRgn( Rect r, RgnHandle rgn, Point globalOffset )
  819. {
  820.     if ( r.bottom <= r.top || r.right <= r.left || !RectInRgn( &r, rgn ) )
  821.     {
  822. // if the rect is empty or ain't in the region, bail.
  823. return;
  824.     }
  825.     
  826.     if ( IsRegionRectangular( rgn ) )
  827.     {
  828. // since the region is a rectangle, add that rectangle and bail.
  829. Rect* newRect = new Rect;
  830. GetRegionBounds(rgn, newRect);
  831. newRect->left += globalOffset.h;
  832. newRect->top += globalOffset.v;
  833. newRect->right += globalOffset.h;
  834. newRect->bottom += globalOffset.v;
  835. m_pVisRgnRects->AddTail( newRect );
  836. return;
  837.     }
  838.     
  839.     // we've established that it's not clearly defined, so divide and conquer.
  840.     
  841.     Rect newRect1 = r;
  842.     Rect newRect2 = r;
  843.     
  844.     if ( r.bottom - r.top > r.right - r.left )
  845.     {
  846. // more vertically oriented
  847. short interimValue = ( r.bottom + r.top ) / 2;
  848. newRect1.bottom = interimValue;
  849. newRect2.top = interimValue;
  850.     }
  851.     else
  852.     {
  853. // more horizontally oriented
  854. short interimValue = ( r.left + r.right ) / 2;
  855. newRect1.right = interimValue;
  856. newRect2.left = interimValue;
  857.     }
  858.     
  859.     RgnHandle newRgn1 = NewRgn();
  860.     RgnHandle newRgn2 = NewRgn();
  861.     
  862.     RectRgn( newRgn1, &newRect1 );
  863.     RectRgn( newRgn2, &newRect2 );
  864.     
  865.     SectRgn( rgn, newRgn1, newRgn1 );
  866.     SectRgn( rgn, newRgn2, newRgn2 );
  867.     
  868.     CheckRectRgn( newRect1, newRgn1, globalOffset );
  869.     CheckRectRgn( newRect2, newRgn2, globalOffset );
  870.     
  871.     DisposeRgn( newRgn1 );
  872.     DisposeRgn( newRgn2 );
  873. }
  874. /************************************************************************
  875.  *  Method:
  876.  *    CMacRootSurface::UpdateRegionIfNecessary
  877.  *
  878.  */
  879. void
  880. CMacRootSurface::UpdateRegionIfNecessary(Rect boundingRect, Point globalOffset, BOOL bForceItToUpdate /* = FALSE */ )
  881. {
  882. #if defined(_CARBON) || defined(_MAC_UNIX)
  883.     return; // xxxbobclark just to keep from crashing???
  884. #else
  885.     HX_ASSERT(!HXMM_ATINTERRUPT());
  886.     
  887.     if (HXMM_ATINTERRUPT()) return;
  888.     
  889.     GrafPtr savePort;
  890.     ::GetPort(&savePort);
  891.     
  892.     WindowPtr macWindow = m_pSite->GetWindow() ? (WindowPtr)m_pSite->GetWindow()->window : NULL;
  893.     if (CHXMacSite::zm_bFullScreenActive)
  894.     {
  895. CHXMacSite* pMacSite = (CHXMacSite*)m_pSite;
  896. if (pMacSite->m_pHXxFullScreenWindow)
  897. {
  898.     macWindow = (WindowPtr)pMacSite->m_pHXxFullScreenWindow->window;
  899. }
  900.     }
  901.     HX_ASSERT(macWindow);
  902.     
  903.     if (!macWindow) return;
  904.     
  905. #if defined(_CARBON) || defined(_MAC_UNIX)
  906.     ::SetPort( GetWindowPort( macWindow ) );
  907. #else
  908.     ::SetPort(macWindow);
  909. #endif
  910.     
  911.     RgnHandle theClippedVisRgn = ::NewRgn();
  912. #if defined(_CARBON) || defined(_MAC_UNIX)
  913.     RgnHandle visRgn = ::NewRgn();
  914.     ::GetPortVisibleRegion( GetWindowPort(macWindow), visRgn );
  915.     RgnHandle clipRgn = ::NewRgn();
  916.     ::GetPortClipRegion( GetWindowPort(macWindow), clipRgn );
  917.     ::SectRgn( visRgn, clipRgn, theClippedVisRgn );
  918.     ::DisposeRgn( clipRgn );
  919.     ::DisposeRgn( visRgn );
  920. #else
  921.     ::SectRgn( macWindow->visRgn, macWindow->clipRgn, theClippedVisRgn );
  922. #endif
  923.     
  924.     // first, dispose and null out m_LastVisRgn if necessary (or forced)
  925.     if ( m_LastVisRgn && ( bForceItToUpdate || !::EqualRgn(theClippedVisRgn, m_LastVisRgn) ) )
  926.     {
  927. ::DisposeRgn(m_LastVisRgn);
  928. m_LastVisRgn = NULL;
  929.     }
  930.     
  931.     if (!m_LastVisRgn)
  932.     {
  933. m_LastVisRgn = ::NewRgn();
  934. ::CopyRgn(theClippedVisRgn, m_LastVisRgn);
  935. RgnHandle interimRgn = ::NewRgn();
  936. ::RectRgn(interimRgn, &boundingRect);
  937. ::SectRgn(m_LastVisRgn, interimRgn, interimRgn);
  938. while (m_pVisRgnRects->GetCount())
  939. {
  940.     Rect* r = (Rect*)m_pVisRgnRects->RemoveHead();
  941.     delete r;
  942. }
  943. CheckRectRgn(boundingRect, interimRgn, globalOffset);
  944. // RegionToRectsByNoodlingThroughRegion(interimRgn, globalOffset, m_VisRgnRects);
  945. ::DisposeRgn(interimRgn);
  946.     }
  947.     
  948.     ::DisposeRgn(theClippedVisRgn);
  949.     
  950.     ::SetPort(savePort);
  951. #endif
  952. }
  953. /************************************************************************
  954.  *  Method:
  955.  *    CMacRootSurface::_PreFlightBlt
  956.  *
  957.  *    This is called AFTER the current sub-rectangle has been determined,
  958.  *    but BEFORE any assumptions about screen depth or anything have been
  959.  *    made. Basically this is where I can hijack the cross-platform code's
  960.  *    assumptions and surreptitiously slide in an appropriate
  961.  *    m_pCompositionSurface and other variables.
  962.  *
  963.  */
  964. void
  965. CMacRootSurface::_PreFlightBlt(HXxRect& dst)
  966. {
  967.     if (!m_bItsOKToDoAnInterruptBlit) return;
  968.     
  969.     m_pCompositionSurface = nil;
  970.     m_nBlitDepthEnum = -1;
  971.     
  972.     Rect r;
  973.     r.left = dst.left + m_LocalToGlobalCoords.h;
  974.     r.top = dst.top + m_LocalToGlobalCoords.v;
  975.     r.right = dst.right + m_LocalToGlobalCoords.h;
  976.     r.bottom = dst.bottom + m_LocalToGlobalCoords.v;
  977.     
  978. #ifdef USE_LOW_LEVEL_QT_API
  979.     int i = zm_uNumberOfAttachedDevices;
  980. #else
  981.     for (int i = 0; i < zm_uNumberOfAttachedDevices; i++)
  982. #endif
  983.     {
  984. Rect intersectionRect;
  985. if ((i == zm_uNumberOfAttachedDevices) || (::SectRect(&r, &(**zm_AttachedDevice[i]).gdRect, &intersectionRect)))
  986. {
  987.     // now figure out which GWorld we need to use.
  988.     
  989.     // XXXbobclark I'm starting out with a copy-n-paste of
  990.     // _CreateCompositionSurface(). Ewww. But the problem is that
  991.     // we don't know -- until now -- which depths and therefore
  992.     // which GWorlds we need. Dayum. ...And what makes it worse is
  993.     // that it might be interrupt time before stuff's created. That
  994.     // will be a weird circumstance -- and one where the blit won't
  995.     // actually succeed -- but it might screw things up in the
  996.     // meantime, like if it tries to blit into the NULL composition
  997.     // surface. Crash. So maybe if it fails everywhere else I'll
  998.     // force the composition surface to be the 32-bit one that's
  999.     // created in _CreateCompositionSurface just so the color
  1000.     // converter has SOMETHING to blit into even though it will
  1001.     // subsequently get ignored. Shee-it.
  1002.     
  1003.     // All (potentially three) offscreens will be full-sized. This
  1004.     // could be a "waste" of memory, but solving it is excruciatingly
  1005.     // subtle and has many tendrils, such as telling the color converter
  1006.     // to convert into non 0,0-based rectangles, yeesh. The good news
  1007.     // -- and an improvement over the older site code -- is that it
  1008.     // only color-converts into the parts of the offscreen that
  1009.     // eventually gets blitted to screen. So there's not a lot of
  1010.     // wasted color conversion.
  1011.     
  1012.     PixMapHandle thePMH = NULL;
  1013.     int pixelSize = 0;
  1014.     INT32 whichDepth;
  1015.     
  1016. #ifdef USE_LOW_LEVEL_QT_API
  1017.     if (i == zm_uNumberOfAttachedDevices)
  1018.     {
  1019. whichDepth = kYUVDepth;
  1020.     }
  1021.     else
  1022. #endif
  1023.     {
  1024. thePMH = (**zm_AttachedDevice[i]).gdPMap;
  1025. pixelSize = (**thePMH).pixelSize;
  1026. whichDepth = DepthToDepthEnum(pixelSize);
  1027.     }
  1028.     if (m_RootSurfaceGWorld[whichDepth])
  1029.     {
  1030. // now see if it needs to be reinitialized.
  1031. Rect thePortRect;
  1032. #if defined(_CARBON) || defined(_MAC_UNIX)
  1033. GetPortBounds(m_RootSurfaceGWorld[whichDepth], &thePortRect);
  1034. #else
  1035. thePortRect = m_RootSurfaceGWorld[whichDepth]->portRect;
  1036. #endif
  1037. BOOL bNeedToRecreate = FALSE;
  1038. if (m_compositionSize.cx > thePortRect.right - thePortRect.left) bNeedToRecreate = TRUE;
  1039. if (m_compositionSize.cy > thePortRect.bottom - thePortRect.top) bNeedToRecreate = TRUE;
  1040. #ifdef USE_LOW_LEVEL_QT_API
  1041. if (whichDepth == kYUVDepth)
  1042. {
  1043.     // xxxbobclark if it's using YUV then the QT calls assume that the whole
  1044.     // GWorld is being used, so using just the upper-left portion
  1045.     // doesn't work.
  1046.     if (m_compositionSize.cx != thePortRect.right-thePortRect.left) bNeedToRecreate = TRUE;
  1047.     if (m_compositionSize.cy != thePortRect.bottom-thePortRect.top) bNeedToRecreate = TRUE;
  1048. }
  1049. #endif
  1050. if (bNeedToRecreate)
  1051. {
  1052.     ::UnlockPixels(m_RootGWorldPixMap[whichDepth]);
  1053.     ::DisposeGWorld(m_RootSurfaceGWorld[whichDepth]);
  1054.     m_RootSurfaceGWorld[whichDepth] = nil;
  1055.     m_RootGWorldPixMap[whichDepth] = nil;
  1056. }
  1057.     }
  1058.     
  1059.     if (!m_RootSurfaceGWorld[whichDepth])
  1060.     {
  1061. // need to (re)create it
  1062. Rect r;
  1063. ::SetRect(&r, 0, 0, m_compositionSize.cx, m_compositionSize.cy);
  1064. #ifdef USE_LOW_LEVEL_QT_API
  1065. if (whichDepth == kYUVDepth)
  1066. {
  1067.     ::QTNewGWorld(&m_RootSurfaceGWorld[whichDepth], 'yuvs', &r, nil, nil, useTempMem | 16 | 32);
  1068.     if (!m_RootSurfaceGWorld[whichDepth])
  1069.     {
  1070. ::QTNewGWorld(&m_RootSurfaceGWorld[whichDepth], 'yuvs', &r, nil, nil, useTempMem | 32);
  1071.     }
  1072.     if (!m_RootSurfaceGWorld[whichDepth])
  1073.     {
  1074. ::QTNewGWorld(&m_RootSurfaceGWorld[whichDepth], 'yuvs', &r, nil, nil, useTempMem | 16);
  1075.     }
  1076.     if (!m_RootSurfaceGWorld[whichDepth])
  1077.     {
  1078. ::QTNewGWorld(&m_RootSurfaceGWorld[whichDepth], 'yuvs', &r, nil, nil, 16 | 32);
  1079.     }
  1080.     if (!m_RootSurfaceGWorld[whichDepth])
  1081.     {
  1082. ::QTNewGWorld(&m_RootSurfaceGWorld[whichDepth], 'yuvs', &r, nil, nil, 32);
  1083.     }
  1084.     if (!m_RootSurfaceGWorld[whichDepth])
  1085.     {
  1086. ::QTNewGWorld(&m_RootSurfaceGWorld[whichDepth], 'yuvs', &r, nil, nil, 16);
  1087.     }
  1088.     if (!m_RootSurfaceGWorld[whichDepth])
  1089.     {
  1090. ::QTNewGWorld(&m_RootSurfaceGWorld[whichDepth], 'yuvs', &r, nil, nil, useTempMem);
  1091.     }
  1092.     if (!m_RootSurfaceGWorld[whichDepth])
  1093.     {
  1094. return;
  1095.     }
  1096. }
  1097. else
  1098. #endif
  1099. {
  1100.     ::NewGWorld(&m_RootSurfaceGWorld[whichDepth], pixelSize, &r, nil, nil, useTempMem);
  1101.     if (!m_RootSurfaceGWorld[whichDepth])
  1102.     {
  1103. ::NewGWorld(&m_RootSurfaceGWorld[whichDepth], pixelSize, &r, nil, nil, 0);
  1104. if (!m_RootSurfaceGWorld[whichDepth]) return;
  1105.     }
  1106. }
  1107. #if defined(_CARBON) || defined(_MAC_UNIX)
  1108. m_RootGWorldPixMap[whichDepth] = GetPortPixMap(m_RootSurfaceGWorld[whichDepth]);
  1109. #else
  1110. m_RootGWorldPixMap[whichDepth] = m_RootSurfaceGWorld[whichDepth]->portPixMap;
  1111. #endif
  1112. ::LockPixels(m_RootGWorldPixMap[whichDepth]);
  1113.     }
  1114.     
  1115.     // OK now the offscreen stuff should all be reinitialized if
  1116.     // it came to that... in any case we're now ready to do the
  1117.     // actual work? nah... kludgey? nah... surreptitious! stuff.
  1118.     
  1119.     if (m_RootSurfaceGWorld[whichDepth] && m_RootGWorldPixMap[whichDepth])
  1120.     {
  1121. m_pCompositionSurface = (unsigned char*)::GetPixBaseAddr(m_RootGWorldPixMap[whichDepth]);
  1122. m_nBlitDepthEnum = whichDepth;
  1123. Rect hold;
  1124. #if defined(_CARBON) || defined(_MAC_UNIX)
  1125. GetPortBounds(m_RootSurfaceGWorld[whichDepth], &hold);
  1126. #else
  1127. hold = m_RootSurfaceGWorld[whichDepth]->portRect;
  1128. #endif
  1129. m_allocatedCompositionSize.cx = hold.right-hold.left;
  1130. m_allocatedCompositionSize.cy = hold.bottom-hold.top;
  1131. m_nCompositionPitch = (**m_RootGWorldPixMap[whichDepth]).rowBytes & 0x3fff;
  1132. m_boundsRect.left = 0;
  1133. m_boundsRect.top = 0;
  1134. m_boundsRect.right = m_allocatedCompositionSize.cx;
  1135. m_boundsRect.bottom = m_allocatedCompositionSize.cy;
  1136. switch (whichDepth)
  1137. {
  1138.     case kThirtyTwoBitDepth:
  1139. m_nCompositionSurfaceCID = CID_RGB32;
  1140. break;
  1141.     case kSixteenBitDepth:
  1142. m_nCompositionSurfaceCID = CID_RGB555;
  1143. break;
  1144. #ifdef USE_LOW_LEVEL_QT_API
  1145.     case kYUVDepth:
  1146. m_nCompositionSurfaceCID = CID_YUY2;
  1147. break;
  1148. #endif
  1149.     default:
  1150. m_nCompositionSurfaceCID = CID_RGB8;
  1151. break;
  1152. }
  1153.     }
  1154. }
  1155.     }
  1156.     
  1157.     if (!m_pCompositionSurface)
  1158.     {
  1159. // this is possible if we're at interrupt time and we're trying to
  1160. // blit to bad places.
  1161. if (m_RootSurfaceGWorld[kThirtyTwoBitDepth] && m_RootGWorldPixMap[kThirtyTwoBitDepth])
  1162. {
  1163.     m_pCompositionSurface = (unsigned char*)GetPixBaseAddr(m_RootGWorldPixMap[kThirtyTwoBitDepth]);
  1164.     m_nBlitDepthEnum = kThirtyTwoBitDepth;
  1165.     m_nCompositionPitch = (**m_RootGWorldPixMap[kThirtyTwoBitDepth]).rowBytes & 0x3fff;
  1166.     m_boundsRect.left = 0;
  1167.     m_boundsRect.top = 0;
  1168.     m_boundsRect.right = m_compositionSize.cx;
  1169.     m_boundsRect.bottom = m_compositionSize.cy;
  1170.     m_nCompositionSurfaceCID = CID_RGB32;
  1171.     
  1172. }
  1173.     }
  1174. }
  1175. /************************************************************************
  1176.  *  Method:
  1177.  *    CMacRootSurface::_GetNumberOfMonitors
  1178.  *
  1179.  */
  1180. UINT32 CMacRootSurface::_GetNumberOfMonitors()
  1181. {
  1182.     return zm_uNumberOfAttachedDevices;
  1183. }
  1184. /************************************************************************
  1185.  *  Method:
  1186.  *    CMacRootSurface::_RectOnNthMonitor
  1187.  *
  1188.  */
  1189. BOOL CMacRootSurface::_RectOnNthMonitor(HXxRect rect, UINT32 uMonitor, HXxRect& intersectRect)
  1190. {
  1191.     HX_ASSERT(uMonitor < zm_uNumberOfAttachedDevices);
  1192.     
  1193.     if (/*It's using an overlay*/1)
  1194.     {
  1195. if (uMonitor == 0)
  1196. {
  1197.     intersectRect = rect;
  1198.     return TRUE;
  1199. }
  1200. else
  1201. {
  1202.     return FALSE;
  1203. }
  1204.     }
  1205.     
  1206.     if (!m_bItsOKToDoAnInterruptBlit)
  1207.     {
  1208. // XXXbobclark well, um, the thing is, if it's at interrupt time
  1209. // we'll bail out this instant; if it's at system time that means
  1210. // we can probably pass through a (possibly bogus) rectangle so
  1211. // the code in _MinimalBlt() catches it and can set m_bItsOKToAn-
  1212. // InterruptBlit to true.
  1213. intersectRect = rect;
  1214. return TRUE;
  1215.     }
  1216.     
  1217.     Rect r;
  1218.     r.left = rect.left + m_LocalToGlobalCoords.h;
  1219.     r.top = rect.top + m_LocalToGlobalCoords.v;
  1220.     r.right = rect.right + m_LocalToGlobalCoords.h;
  1221.     r.bottom = rect.bottom + m_LocalToGlobalCoords.v;
  1222.     
  1223.     Rect intR;
  1224.     if (::SectRect(&r, &(**zm_AttachedDevice[uMonitor]).gdRect, &intR))
  1225.     {
  1226. intersectRect.left = intR.left - m_LocalToGlobalCoords.h;
  1227. intersectRect.top = intR.top - m_LocalToGlobalCoords.v;
  1228. intersectRect.right = intR.right - m_LocalToGlobalCoords.h;
  1229. intersectRect.bottom = intR.bottom - m_LocalToGlobalCoords.v;
  1230. return TRUE;
  1231.     }
  1232.     return FALSE;
  1233. }