macroot.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:43k
源码类别:

Symbian

开发平台:

C/C++

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