Logo Search packages:      
Sourcecode: helix-player version File versions

macsite.cpp

/* ***** BEGIN LICENSE BLOCK *****
 * Source last modified: $Id: macsite.cpp,v 1.9.20.3 2004/07/09 01:59:02 hubbe Exp $
 * 
 * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
 * 
 * The contents of this file, and the files included with this file,
 * are subject to the current version of the RealNetworks Public
 * Source License (the "RPSL") available at
 * http://www.helixcommunity.org/content/rpsl unless you have licensed
 * the file under the current version of the RealNetworks Community
 * Source License (the "RCSL") available at
 * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
 * will apply. You may also obtain the license terms directly from
 * RealNetworks.  You may not use this file except in compliance with
 * the RPSL or, if you have a valid RCSL with RealNetworks applicable
 * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
 * the rights, obligations and limitations governing use of the
 * contents of the file.
 * 
 * Alternatively, the contents of this file may be used under the
 * terms of the GNU General Public License Version 2 or later (the
 * "GPL") in which case the provisions of the GPL are applicable
 * instead of those above. If you wish to allow use of your version of
 * this file only under the terms of the GPL, and not to allow others
 * to use your version of this file under the terms of either the RPSL
 * or RCSL, indicate your decision by deleting the provisions above
 * and replace them with the notice and other provisions required by
 * the GPL. If you do not delete the provisions above, a recipient may
 * use your version of this file under the terms of any one of the
 * RPSL, the RCSL or the GPL.
 * 
 * This file is part of the Helix DNA Technology. RealNetworks is the
 * developer of the Original Code and owns the copyrights in the
 * portions it created.
 * 
 * This file, and the files included with this file, is distributed
 * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
 * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
 * ENJOYMENT OR NON-INFRINGEMENT.
 * 
 * Technology Compatibility Kit Test Suite(s) Location:
 *    http://www.helixcommunity.org/content/tck
 * 
 * Contributor(s):
 * 
 * ***** END LICENSE BLOCK ***** */

#ifndef _MACINTOSH
#ifndef _MAC_UNIX
#error This is the Macintosh platform specific implementation.
#endif
#endif

#include "hxcom.h"

#include "hxtypes.h"
#include "hxwintyp.h"
#include "hxmap.h"
#include "hxslist.h"
#include "ihxpckts.h"
#include "hxwin.h"
#include "hxengin.h"
#include "hxsite2.h"
#include "chxxtype.h"
#include "hxvctrl.h"
#include "hxvsurf.h"
#include "hxcodec.h"
#include "surface.h"
#include "vidosurf.h"
#include "sitetext.h"
#include "chxpckts.h"
#include "hxevent.h"
#include "bltpatch.h"
#include "hxprefs.h"

#include "hxevent.h"
#include "hxcore.h"

#include "platform/mac/macsite.h"
#include "platform/mac/macsurf.h"
#include "platform/mac/macroot.h"

#ifdef _CARBON
#ifndef _MAC_MACHO
#include <ControlDefinitions.h>
#endif
#endif

#include "platform/mac/hx_moreprocesses.h"

//#include "../dcondev/dcon.h"

#include "basesurf.h"

#include "hxtick.h"
#include "hxvimlog.h"
#include "hxheap.h"
#ifdef _DEBUG
#undef HX_THIS_FILE           
static const char HX_THIS_FILE[] = __FILE__;
#endif

#define SCROLL_BAR_WIDTH 16

CHXSimpleList CHXMacSite::zm_ListOfMacSites;
BOOL CHXMacSite::zm_bFullScreenActive = FALSE;
Ptr CHXMacSite::zm_pRememberFullScreenInformation = nil;

extern "C" void MacSiteHandleAllEvents(HXxEvent* pEvent);



/*
 *
 *    SetOriginAndMaintainClipRgn is designed to replace
 *    SetOrigin(). It will internally call SetOrigin
 *    if necessary, and it will also adjust the clip
 *    region in order to maintain the parts of the
 *    screen that the clip region refers to. This
 *    is necessary because, sadly, SetOrigin() in
 *    the Mac Toolbox does NOT change the values in
 *    the clipRgn so it suddenly refers to a different
 *    part of the screen!
 *
 */
void SetOriginAndMaintainClipRgn(short horizOffset, short vertOffset)
{
    // SetOriginMaintainClip, like SetOrigin(), assumes
    // that the port is set correctly.
    GrafPtr curPort;
    ::GetPort( &curPort );

    Rect portBounds;
    
#if defined(_CARBON) || defined(_MAC_UNIX)
    ::GetPortBounds( curPort, &portBounds );
#else
    portBounds = curPort->portRect;
#endif

    if ( ( horizOffset == portBounds.left ) && ( vertOffset == portBounds.top ) )
    {
      return; // everything is already (presumably) set up correctly.
    }
    
    RgnHandle clipRgn = ::NewRgn();
    
    ::GetClip( clipRgn );
    
    Rect clipRgnBounds;
#if defined(_CARBON) || defined(_MAC_UNIX)
    ::GetRegionBounds(clipRgn, &clipRgnBounds);
#else
    clipRgnBounds = (**clipRgn).rgnBBox;
#endif
    
    // if the clip region goes too close to -32768 or 32767, we run the
    // risk of rolling over those values when we do an OffsetRgn(). Sadly,
    // OffsetRgn does NOT internally check for rollovers, but blithely
    // slams those rolled-over values into the region, resulting in a
    // meaningless region. To avoid that we're trimming the region to
    // noticeable values. (i.e. if we see regions with a width or height
    // of 44444, we can use that as a magic cookie type signature.)
    if (clipRgnBounds.left < -25252
      || clipRgnBounds.top < -25252
      || clipRgnBounds.right > 25252
      || clipRgnBounds.bottom > 25252
      )
    {
      RgnHandle soonToBeSectedRgnCopy = ::NewRgn();
      ::SetRectRgn( soonToBeSectedRgnCopy, -22222, -22222, 22222, 22222 );

      ::SectRgn( clipRgn, soonToBeSectedRgnCopy, clipRgn );

      ::DisposeRgn( soonToBeSectedRgnCopy );
    }
    ::OffsetRgn( clipRgn, horizOffset - portBounds.left, vertOffset - portBounds.top );
    
    ::SetOrigin( horizOffset, vertOffset );
    ::SetClip( clipRgn );
    ::DisposeRgn( clipRgn );
}



/************************************************************************
 *  Method:
 *    CHXMacSite constructor
 */
CHXMacSite::CHXMacSite(IUnknown* pContext, IUnknown* pUnkOuter, INT32 lZOrder)
  : CHXBaseSite(pContext, pUnkOuter, lZOrder)
  , m_hHScrollBar(NULL)
  , m_hVScrollBar(NULL)
  , m_ScrollBarActionProc(NULL)
  , m_nHorizPageSize(1)
  , m_nVertPageSize(1)
  , m_bCreatedOSWindow(FALSE)
  , m_pHXxFullScreenWindow(NULL)
  , m_fStretchMultiple(0.0)
  , m_RememberMacPort(nil)
  , m_bInternalResizeOnFullscreen(TRUE)
  , m_pMacSiteRedrawCallback(NULL)
#ifdef THREADS_SUPPORTED

#ifdef USE_CARBON_TIMER
#ifdef _MAC_MACHO
  , m_RedrawCFTimerRef(NULL)
#else
  , m_RedrawCarbonTimerRef(NULL)
  , m_RedrawCarbonTimerUPP(NULL)
#endif
#endif

  , m_pIHXCoreMutex(NULL)
  , m_pClientEngine(NULL)
#endif
{
    m_MostRecentConvertedMouseLoc.x = 0;
    m_MostRecentConvertedMouseLoc.y = 0;
    
    m_RememberNonFullscreenSize.cx = 0;
    m_RememberNonFullscreenSize.cy = 0;
    m_RememberNonFullscreenPosition.x = 0;
    m_RememberNonFullscreenPosition.y = 0;
    
    IHXPreferences* pPreferences = NULL;
    IHXBuffer* pBuffer = NULL;
    
    if (HXR_OK == m_pContext->QueryInterface(IID_IHXPreferences, (void**)&pPreferences))
    {
      if (pPreferences->ReadPref("MacFullscreenInternalResize", pBuffer) == HXR_OK)
      {
          m_bInternalResizeOnFullscreen = ::atoi((char*)pBuffer->GetBuffer()) == 1;
          HX_RELEASE(pBuffer);
      }
      HX_RELEASE(pPreferences);
    }
    
    zm_ListOfMacSites.AddTail(this);
    
    m_pMacSiteRedrawCallback = new MacSiteRedrawCallback(this);
    m_pMacSiteRedrawCallback->AddRef();

#ifdef THREADS_SUPPORTED
    // xxxzach - TEMP - installing the event loop timer when running in the embedded player
    //                  results in a crash when loading a 2nd page. 
    //                  appears to call the timer proc after ~CHXMacSite has been called
    //                  so don't install timer if running as embedded player
    const OSType kPlayerSignature = 'PNst';
#ifdef USE_CARBON_TIMER
#ifdef _MAC_MACHO
    memset(&m_RedrawCFTimerContext, 0, sizeof(CFRunLoopTimerContext));
    
    m_RedrawCFTimerContext.info = (void*)this; // info is what's passed into the timer function
    
    m_RedrawCFTimerRef = ::CFRunLoopTimerCreate(
                kCFAllocatorDefault,
                ::CFAbsoluteTimeGetCurrent() + 31536000.0, // a year from now
                31536000.0, // every year
                0, //CFOptionFlags
                0, //CFIndexOrder
                CHXMacSite::RedrawCFTimer,
                &m_RedrawCFTimerContext);
    
    ::CFRunLoopAddTimer(
                ::CFRunLoopGetCurrent(),
                m_RedrawCFTimerRef,
                kCFRunLoopCommonModes
                );
#else
    m_RedrawCarbonTimerUPP = ::NewEventLoopTimerUPP(
            (EventLoopTimerProcPtr)CHXMacSite::RedrawCarbonTimer);

    OSStatus osStatus = ::InstallEventLoopTimer(
            GetMainEventLoop(), kEventDurationForever, kEventDurationForever,
            m_RedrawCarbonTimerUPP, this, &m_RedrawCarbonTimerRef);
    HX_ASSERT(osStatus == noErr);
#endif
#endif
          
    m_pContext->QueryInterface(IID_IHXCoreMutex, (void**)&m_pIHXCoreMutex);
    HX_ASSERT(m_pIHXCoreMutex);
    
    m_pContext->QueryInterface(IID_IHXClientEngine, (void**)&m_pClientEngine);
#endif
}

/************************************************************************
 *  Method:
 *    CHXMacSite destructor
 */
CHXMacSite::~CHXMacSite()
{
#ifdef THREADS_SUPPORTED
    HX_RELEASE(m_pIHXCoreMutex);
    HX_RELEASE(m_pClientEngine);
    
#ifdef USE_CARBON_TIMER
#ifdef _MAC_MACHO
    ::CFRunLoopRemoveTimer(
                ::CFRunLoopGetCurrent(),
                m_RedrawCFTimerRef,
                kCFRunLoopCommonModes
                );
    
    m_RedrawCFTimerRef = NULL;
    memset(&m_RedrawCFTimerContext, 0, sizeof(CFRunLoopTimerContext));
#else
    ::RemoveEventLoopTimer(m_RedrawCarbonTimerRef);
    m_RedrawCarbonTimerRef = NULL;

    ::DisposeEventLoopTimerUPP(m_RedrawCarbonTimerUPP);
    m_RedrawCarbonTimerUPP = NULL;
#endif
#endif

#endif
    _DestroySliders();
    
    if (m_pMacSiteRedrawCallback &&
      m_pMacSiteRedrawCallback->m_ulMacSiteRedrawCallbackPendingID &&
      m_pScheduler)
    {
      m_pScheduler->Remove(m_pMacSiteRedrawCallback->m_ulMacSiteRedrawCallbackPendingID);
      m_pMacSiteRedrawCallback->m_ulMacSiteRedrawCallbackPendingID = 0;
    }
    HX_RELEASE(m_pMacSiteRedrawCallback);
    
    LISTPOSITION pos = zm_ListOfMacSites.Find(this);
    zm_ListOfMacSites.RemoveAt(pos);
}

/************************************************************************
 *  Method:
 *    CHXMacSite::GetWindow
 */
STDMETHODIMP_(HXxWindow*) CHXMacSite::GetWindow() 
{
    if (zm_bFullScreenActive)
    {
      if (m_pHXxFullScreenWindow) return m_pHXxFullScreenWindow;
      if (m_pParentSite) return m_pParentSite->GetWindow();
      
      HX_ASSERT(!"shouldn't get here");
    }
    return CHXBaseSite::GetWindow();


    if (zm_bFullScreenActive && m_pHXxFullScreenWindow) return m_pHXxFullScreenWindow;
    
return m_pWindow;
    return CHXBaseSite::GetWindow();
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_NeedWindowedSite
 */
void
CHXMacSite::_NeedWindowedSite()
{
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_AttachWindow
 */
void
CHXMacSite::_AttachWindow()
{
    m_pHXxFullScreenWindow = new HXxWindow;
    if (m_pTopLevelSite == this)
    {
      Rect r = {0,0,0,0};
      m_pHXxFullScreenWindow->window = ::NewCWindow(nil, &r, "\p", false, plainDBox, nil, false, 0);
      
      // if we created the mac window we need to update the HXxWindow parameters
      // so we're not clipped out later
      if (m_bCreatedOSWindow)
      {
          HX_ASSERT(m_pWindow);
          
          WindowPtr w = (WindowPtr)m_pWindow->window;
          
          HX_ASSERT(w);
          
          m_pWindow->x = 0;
          m_pWindow->y = 0;
          
          Rect bounds;
          ::GetPortBounds(::GetWindowPort(w), &bounds);
          
          m_pWindow->width = bounds.right-bounds.left;
          m_pWindow->height = bounds.bottom-bounds.top;
          
          m_pWindow->clipRect.left = 0;
          m_pWindow->clipRect.top = 0;
          m_pWindow->clipRect.right = m_pWindow->width;
          m_pWindow->clipRect.bottom = m_pWindow->height;
      }
    }
    else
    {
      CHXMacSite* pMacParentSite = (CHXMacSite*)m_pParentSite; // XXXbobclark Ewwww! (Can we use RTTI ya think?)
      m_pHXxFullScreenWindow->window = pMacParentSite->m_pHXxFullScreenWindow->window;
    }
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_DetachWindow
 */
void
CHXMacSite::_DetachWindow()
{
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_Create
 */
void*
CHXMacSite::_Create(void* ParentWindow, UINT32 style)
{
    if (!ParentWindow)
    {
      Rect r = {200,400,40,40};
      WindowPtr w = ::NewCWindow(nil, &r, "\p", true, documentProc, (WindowPtr)-1L, false, 0);
      
      if (w)
      {
          m_bCreatedOSWindow = TRUE;
          return w;
      }
    }
    
    m_bCreatedOSWindow = FALSE;
    return ParentWindow;
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_Destroy
 */
void
CHXMacSite::_Destroy(HXxWindow* pWindow)
{
    if (CMacSurface::zm_pOverlaySurface == (CMacSurface*)m_pVideoSurface)
    {
      CMacSurface::CleanUpOverlay();
      CMacSurface::zm_pOverlaySurface = nil;
    }
    
    if (pWindow && m_bCreatedOSWindow)
    {
      WindowPtr w = (WindowPtr)pWindow->window;
      if (w)
      {
          ::DisposeWindow(w);
      }
      m_bCreatedOSWindow = FALSE;
    }
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_SetSize
 */
void
CHXMacSite::_SetSize(HXxSize size)
{
    if (m_bCreatedOSWindow && m_pWindow && m_pWindow->window)
    {
      WindowPtr w = (WindowPtr)m_pWindow->window;
      ::SizeWindow(w, size.cx, size.cy, true);
      
      m_pWindow->x = 0;
      m_pWindow->y = 0;

      Rect bounds;
      ::GetPortBounds(::GetWindowPort(w), &bounds);

      m_pWindow->width = bounds.right-bounds.left;
      m_pWindow->height = bounds.bottom-bounds.top;

      m_pWindow->clipRect.left = 0;
      m_pWindow->clipRect.top = 0;
      m_pWindow->clipRect.right = m_pWindow->width;
      m_pWindow->clipRect.bottom = m_pWindow->height;
    }
    // delete the scroll bars so it recreates them in the right spot
    _DestroySliders();
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_SetPosition
 */
void
CHXMacSite::_SetPosition(HXxPoint position)
{
    if (m_bCreatedOSWindow && m_pWindow && m_pWindow->window)
    {
      WindowPtr w = (WindowPtr)m_pWindow->window;
      ::MoveWindow(w, position.x, position.y, false);
    }
    else
    {
      m_screenOffset = position;
    }
    // delete the scroll bars so it recreates them in the right spot.
    _DestroySliders();
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_DamageRect
 */
void
CHXMacSite::_DamageRect(HXxRect rect)
{
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_DamageRect
 */
void
CHXMacSite::_DamageRegion(HXxRegion rgn)
{
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_ShouldEnterForceRedraw
 */
BOOL
CHXMacSite::_ShouldEnterForceRedraw()
{
    if (InterlockedIncrement(&m_lBltEntryCount) > 1)
    {
        InterlockedDecrement(&m_lBltEntryCount);
        return FALSE; 
    }

#ifdef THREADS_SUPPORTED
#ifdef USE_CARBON_TIMER
    if (!IsMacInCooperativeThread())
    {
      // we need to schedule a Carbon Timer callback
      // to access ourselves at system time.
      
      // XXXMEH 06/17/2002 - we moved this InterlockDecrement()
      // to BEFORE the SetEventLoopTimerNextFireTime(). The reason
      // is that sometimes, you actually get an IMMEDIATE callback
      // on the main thread before you have decremented m_lBltEntryCount.
      // When this happened while the decrement was AFTER SetEventLoopTimerNextFireTime(),
      // then the ForceRedraw() would bail out early at the
      // if(InterlockedIncrement(&m_lBltEntryCount) > 1) at the
      // top of this method and the blt would never happen.
        InterlockedDecrement(&m_lBltEntryCount);
#ifdef _MAC_MACHO
      HX_ASSERT(m_RedrawCFTimerRef);
        ::CFRunLoopTimerSetNextFireDate(
                        m_RedrawCFTimerRef,
                        ::CFAbsoluteTimeGetCurrent() // immediately!
                        );
#else
      HX_ASSERT(m_RedrawCarbonTimerRef);
      ::SetEventLoopTimerNextFireTime(m_RedrawCarbonTimerRef, kEventDurationNoWait);
#endif
        // XXXMEH 06/17/2002 - We USED to decrement m_lBltEntryCount here - 
        // now we have moved it before SetEventLoopTimerNextFireTime()
      return FALSE;
    }
#endif
#endif

    HXxWindow* topWindow = GetWindow();
    if (_AtSystemTime() && topWindow && topWindow->window)
    {
      ::GetPort(&m_RememberMacPort);
      WindowPtr w = (WindowPtr)topWindow->window;
#if defined(_CARBON) || defined(_MAC_UNIX)
      ::SetPort( GetWindowPort( w ) );
#else
      ::SetPort(w);
#endif
      
      // get new origin

      HXxPoint offset;
      offset.x = 0;
      offset.y = 0;
      GetMacContentAreaOffset(offset);

      // see if the clip region overlaps where we know we're supposed to be.
      
      Rect siteRect = { 0, 0, topWindow->height, topWindow->width };
      OffsetRect( &siteRect, topWindow->x, topWindow->y );
      
      BOOL bSiteClippedOutSoRedrawNecessary = FALSE;
      
      RgnHandle clippedSiteRgn = ::NewRgn();
      RgnHandle siteRgn = ::NewRgn();
      
      ::RectRgn(siteRgn, &siteRect);
      
#if defined(_CARBON) || defined(_MAC_UNIX)
      RgnHandle clipRgn = ::NewRgn();
      ::GetPortClipRegion( GetWindowPort( w ), clipRgn );
      ::SectRgn( siteRgn, clipRgn, clippedSiteRgn );
      ::DisposeRgn( clipRgn );
#else
      ::SectRgn(siteRgn, w->clipRgn, clippedSiteRgn);
#endif
      
      if (::EmptyRgn(clippedSiteRgn))
      {
          bSiteClippedOutSoRedrawNecessary = TRUE;
      }
      
      DisposeRgn(siteRgn);
      DisposeRgn(clippedSiteRgn);
      
      if (bSiteClippedOutSoRedrawNecessary)
      {
          // D'oh, doesn't intersect! So let's just draw next time around.

          // we need to schedule a redraw if one ain't there already.
          if (!m_pMacSiteRedrawCallback->m_ulMacSiteRedrawCallbackPendingID
            && m_pScheduler)
          {
            m_pMacSiteRedrawCallback->m_ulMacSiteRedrawCallbackPendingID =
                  m_pScheduler->RelativeEnter(m_pMacSiteRedrawCallback, 1);
          }

          goto returnfalse;
      }
    }
    
    return TRUE;

returnfalse:
    // xxxbobclark I needed to move this code around because CWPro 7's compiler
    // was running out of local variable space. Odd.
    
    ::SetPort(m_RememberMacPort);
    // decrement count since it won't execute ForceRedraw.
    InterlockedDecrement(&m_lBltEntryCount);
    return FALSE;

}

/************************************************************************
 *  Method:
 *    CHXMacSite::_ExitForceRedraw
 */
void
CHXMacSite::_ExitForceRedraw()
{
    HXxWindow* topWindow = GetParentWindow();
    if (_AtSystemTime() && topWindow && topWindow->window)
    {
      ::SetPort(m_RememberMacPort);
      m_RememberMacPort = nil;
    }
    
    InterlockedDecrement(&m_lBltEntryCount);
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_SendOSUpdateMessage
 */
void
CHXMacSite::_SendOSUpdateMessage()
{
#if 0
    ASSERT(GetOSWindow());
    
    if (GetOSWindow())
    {
      GrafPtr savePort;
      ::GetPort(&savePort);
      
      WindowPtr w = (WindowPtr)GetOSWindow();
      ::SetPort(w);
      // XXXbobclark
      // I still haven't fully grokked how to avoid loops: _HandleOSEvent on an
      // update event can call _ForceRedraw(), which in turn calls _SendOSUpdateMessage,
      // where InvalRect() can generate an update event.... And we need this to function
      // properly, so things like paused movies will redraw if they're obscured then shown.

//    ::InvalRect(&w->portRect);
      ::SetPort(savePort);
    }
#endif
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_ShowSite
 */
void
CHXMacSite::_ShowSite(BOOL bShow)
{
    if (m_pWindow && m_pWindow->window)
    {
      // XXXbobclark I think that the cross-platform stuff should take care of this...
    }
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_AtSystemTime
 */
BOOL
CHXMacSite::_AtSystemTime()
{
    return IsMacInCooperativeThread();
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_EventOccurred
 */
HX_RESULT
CHXMacSite::_EventOccurred(HXxEvent* pEvent)
{
    return HXR_OK;
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_GetDeviceCaps
 */
void
CHXMacSite::_GetDeviceCaps(void* hdc, UINT16& uBytesPerPixel, UINT16& uHorizRes,
      UINT16& uVertRes)
{
    static UINT16 sBytesPerPixel = 4;
    static UINT16 sHorizRes = 640;
    static UINT16 sVertRes = 480;
    static BOOL sInited = FALSE;
    
    if (!sInited && _AtSystemTime())
    {
      GDHandle mainGD = ::GetMainDevice();
      sHorizRes = (**mainGD).gdRect.right - (**mainGD).gdRect.left;
      sVertRes = (**mainGD).gdRect.bottom - (**mainGD).gdRect.top;
      PixMapHandle pmh = (**mainGD).gdPMap;
      if (pmh)
      {
          sBytesPerPixel = (**pmh).pixelSize;
      }
    }
    
    uBytesPerPixel = sBytesPerPixel;
    uHorizRes = sHorizRes;
    uVertRes = sVertRes;
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_GetWindowRect
 */
void
CHXMacSite::_GetWindowRect(HXxRect* destRect)
{
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_DestroySliders
 */
void
CHXMacSite::_DestroySliders()
{
    if (m_hHScrollBar)
    {
      ::DisposeControl(m_hHScrollBar);
      m_hHScrollBar = NULL;
    }
    if (m_hVScrollBar)
    {
      ::DisposeControl(m_hVScrollBar);
      m_hVScrollBar = NULL;
    }
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_HandleOSEvents
 */
BOOL
CHXMacSite::_HandleOSEvents(HXxEvent* pEvent)
{
    BOOL handled = FALSE;
    {
      EventRecord* macEvent = (EventRecord*) pEvent->param1;

      // if we switch out while in full-screen, unfortunately we need
      // to turn off full-screen.
      
      if (zm_bFullScreenActive && macEvent->what == nullEvent)
      {
          ProcessSerialNumber currentPSN;
          ProcessSerialNumber frontPSN;
          
          ::GetCurrentProcess(&currentPSN);
          ::GetFrontProcess(&frontPSN);
          
          Boolean bCurrentIsFront = TRUE;
          ::SameProcess(&currentPSN, &frontPSN, &bCurrentIsFront);
          
          if (!bCurrentIsFront)
          {

            ExitFullScreen();
            
            HXxWindow* pWindow = GetWindow();
            if (pWindow && pWindow->window)
            {
                GrafPtr savePort;
                ::GetPort(&savePort);
                WindowPtr w = (WindowPtr)pWindow->window;
                ::SetPort(::GetWindowPort(w));
                Rect windowBounds;
                ::GetPortBounds(::GetWindowPort(w), &windowBounds);
                ::InvalWindowRect(w, &windowBounds);
                ::SetPort(savePort);
            }

            handled = TRUE;
          }
      }
      
      if (macEvent->what == keyDown)
      {
          char theKey = macEvent->message & 0x000000ff;
          
          if (CHXMacSite::zm_bFullScreenActive && theKey == 0x1b)
          {
            ExitFullScreen();
          }
          else
          {
            if (m_pUser)
                m_pUser->HandleEvent(pEvent);
            
            handled = pEvent->handled;
          }
      }
      
      if (macEvent->what == updateEvt || macEvent->what == activateEvt)
      {
          HX_ASSERT(_AtSystemTime());
          
          WindowPtr w = (WindowPtr)macEvent->message;

          if (w)
          {
            if (zm_bFullScreenActive && m_pHXxFullScreenWindow && m_pHXxFullScreenWindow->window
                  && m_pHXxFullScreenWindow->window == w)
            {
                GrafPtr savePort;
                ::GetPort(&savePort);
#if defined(_CARBON) || defined(_MAC_UNIX)
                ::SetPort( GetWindowPort( w ) );
#else
                ::SetPort(w);
#endif
                RGBColor holdRGB;
                RGBColor theRGB = {0x0000, 0x0000, 0x0000};
                ::GetBackColor(&holdRGB);
                ::RGBBackColor(&theRGB);
#if defined(_CARBON) || defined(_MAC_UNIX)
                Rect portRect;
                GetPortBounds( GetWindowPort( w ), &portRect );
                ::EraseRect( &portRect );
#else
                ::EraseRect(&w->portRect);
#endif
                ::RGBBackColor(&holdRGB);
                ::SetPort(savePort);
            }

            m_pTopLevelSite->RecomputeClip();

            // see if overlay is active... if so, then we might just need
            // to fill with a color key!
            if (CMacSurface::zm_pOverlaySurface)
            {
                CMacSurface* pMacSurface = (CMacSurface*)m_pVideoSurface;
                if (pMacSurface == CMacSurface::zm_pOverlaySurface)
                {
                  // aha! THIS site's surface is in fact the overlay surface.
                  m_pVideoSurface->FillColorKey();
                }
            }
            HXxRect siteRectToDamage;
            siteRectToDamage.left = 0;
            siteRectToDamage.top = 0;
            siteRectToDamage.right = m_size.cx;
            siteRectToDamage.bottom = m_size.cy;
            DamageRect(siteRectToDamage);
            InternalForceRedraw();
          }

          HXxWindow* pWindow = GetWindow();
          if (pWindow && pWindow->window == (WindowPtr)macEvent->message)
          {
            // XXXbobclark commented out 'cause it's already done for "honest"
            // update events. I don't wanna do this for fake update events.
//          m_pTopLevelSite->RecomputeClip();
//          ForceRedraw();
            if (pEvent->param2 && _AtSystemTime())
            {
                // for update events, param2 may contain a RgnHandle into
                // which we add the area that we are handling updates in,
                // so the TLC knows it doesn't have to draw there.
                
                if (m_bBltHasBeenCalled)
                {
                  if (!m_bThisOrAChildHasBlitted)
                  {
                      CHXMacSite* pMacSite = this;
                      while (pMacSite)
                      {
                        pMacSite->m_bThisOrAChildHasBlitted = TRUE;
                        pMacSite = (CHXMacSite*)pMacSite->m_pParentSite;
                      }
                  }
                }
                
                if (m_bThisOrAChildHasBlitted)
                {
                  RgnHandle handledRgn = ::NewRgn();
                  RgnHandle passedInRgn = (RgnHandle)pEvent->param2;

                  HXxPoint ptSiteOrigin;
                  GetMacContentAreaOffset(ptSiteOrigin);

                  Rect myRect = { ptSiteOrigin.y, ptSiteOrigin.x,
                        ptSiteOrigin.y + m_size.cy,
                        ptSiteOrigin.x + m_size.cx };

                  ::RectRgn(handledRgn, &myRect);
                  ::UnionRgn(passedInRgn, handledRgn, passedInRgn);
                  ::DisposeRgn(handledRgn);
                }
            }
          }
          
          if (m_hHScrollBar || m_hVScrollBar)
          {
            Point oldOrigin;
            Rect portRect;
            GetPortBounds(GetWindowPort(w), &portRect);
            oldOrigin.h = portRect.left;
            oldOrigin.v = portRect.top;
            
            if (m_hHScrollBar)
            {
                ::Draw1Control(m_hHScrollBar);
                handled = TRUE;
            }
            if (m_hVScrollBar)
            {
                ::Draw1Control(m_hVScrollBar);
                handled = TRUE;
            }
          }
      }
      
      if (macEvent->what == mouseDown || macEvent->what == mouseUp)
      {
          WindowPtr w = nil;

          ControlHandle theControl = NULL;
          
          HXxWindow* pWindow = GetWindow();
          
          if (pWindow && pWindow->window)
          {
            w = (WindowPtr)pWindow->window;
          }
          
          HX_ASSERT(w);
          
          if (!w) return HXR_FAIL;

          GrafPtr savePort;
          ::GetPort(&savePort);
          ::SetPort(::GetWindowPort(w));
          
          Point oldOrigin;
          Rect portRect;
          ::GetPortBounds(::GetWindowPort(w), &portRect);
          oldOrigin.h = portRect.left;
          oldOrigin.v = portRect.top;
          
          SetOriginAndMaintainClipRgn(0,0); // origin must be at 0,0 for scroll bar maintenence
          
          Point localPt = macEvent->where;
          ::GlobalToLocal(&localPt);
          
          short thePart = 0;
          theControl = ::FindControlUnderMouse(localPt, w, &thePart);
          
          if (theControl && ((theControl == m_hHScrollBar) || (theControl == m_hVScrollBar)))
          {
            short trackedPart = ::TrackControl(theControl, localPt, m_ScrollBarActionProc);
                // xxxbobclark Carbon Porting Notes: TrackControl is deprecated, use HandleControlClick.
            
            long pageSize;
            
            if (theControl == m_hHScrollBar)
            {
                pageSize = m_nHorizPageSize;
            }
            else
            {
                pageSize = m_nVertPageSize;
            }
            
            switch (trackedPart)
            {
                case kControlUpButtonPart:
                  ::SetControl32BitValue(theControl, ::GetControl32BitValue(theControl)-1);
                  break;
                case kControlDownButtonPart:
                  ::SetControl32BitValue(theControl, ::GetControl32BitValue(theControl)+1);
                  break;
                case kControlPageUpPart:
                  ::SetControl32BitValue(theControl, ::GetControl32BitValue(theControl)-pageSize);
                  break;
                case kControlPageDownPart:
                  ::SetControl32BitValue(theControl, ::GetControl32BitValue(theControl)+pageSize);
                  break;
            }
            
            if (theControl == m_hHScrollBar)
            {
                m_XSliderPos = ::GetControl32BitValue(theControl);
            }
            if (theControl == m_hVScrollBar)
            {
                m_YSliderPos = ::GetControl32BitValue(theControl);
            }
            
            HXxPoint ptSiteOrigin;
            GetMacContentAreaOffset(ptSiteOrigin);
            Rect invalRect;
            invalRect.left = ptSiteOrigin.x;
            invalRect.top = ptSiteOrigin.y;
            
            if (m_hHScrollBar)
            {
                Rect controlRect;
                ::GetControlBounds(m_hHScrollBar, &controlRect);
                invalRect.right = controlRect.right;
                invalRect.bottom = controlRect.top;
            }
            if (m_hVScrollBar)
            {
                Rect controlRect;
                ::GetControlBounds(m_hVScrollBar, &controlRect);
                invalRect.right = controlRect.left;
                invalRect.bottom = controlRect.bottom;
            }
            
            ::InvalWindowRect(w, &invalRect);
            handled = TRUE;
          }
          
          if (!handled)
          {
            HXxWindow* pWindow = GetWindow();
            if (pWindow && pWindow->window)
            {
                // see if it's in this site

                SetOriginAndMaintainClipRgn(-pWindow->x, -pWindow->y);
                Point p = macEvent->where;
                ::GlobalToLocal(&p);
                HXxPoint loc;
                loc.x = p.h;
                loc.y = p.v;
                
                HX_ASSERT(m_RegionForMouse);
                if (IsPointInClippingRegion(&loc))
                {
                  HXxPoint offset = {0,0};
                  GetMacContentAreaOffset(offset);

//                UDrawingUtils::SetOriginAndMaintainClipRgn(-offset.x, -offset.y);


                        if (m_pUser)
                        {
//                            m_pUser->HandleEvent(pEvent);
//                            handled = pEvent->handled;
                        }
                }
                
                SetOriginAndMaintainClipRgn(oldOrigin.h, oldOrigin.v);
                
                ::SetPort(savePort);
            }
            
          }
      }
    }
    return handled;
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_HandleAllOSEvents
 */
/* static */
void CHXMacSite::_HandleAllOSEvents(HXxEvent* pEvent)
{
    EventRecord* macEvent = (EventRecord*) pEvent->param1;
    
    CHXSimpleList::Iterator ndx = zm_ListOfMacSites.Begin();
    for ( ; ndx != zm_ListOfMacSites.End(); ++ndx)
    {
      CHXMacSite* pMacSite = (CHXMacSite*)(*ndx);
      
      HX_ASSERT( pMacSite );
      
      pMacSite->_HandleOSEvents(pEvent);
    }
    
/*
    if (gRecentUpdateEvent)
    {
      EventRecord* macEvent = (EventRecord*)pEvent->param1;
      if (macEvent->what == updateEvt)
      {
          // XXXbobclark
          // clearly we're handling the recent update event and since we've
          // just done it let's clear that puppy out.
          gRecentUpdateEvent = false;
      }
    }
*/
}


/************************************************************************
 *  Method:
 *    CHXMacSite::_ConvertRegionToMacRegion
 *    utility function to convert between the RealNetworks
 *    regions that the site classes use and Mac-specific
 *    RgnHandle's.
 */
/* static */
RgnHandle
CHXMacSite::_ConvertRegionToMacRegion( HXREGION* pRegion )
{
    HX_ASSERT(IsMacInCooperativeThread());
    if ( !IsMacInCooperativeThread() ) return nil; // Hoo-boy would this ever suck

    RgnHandle rgn = ::NewRgn();
    
    if ( rgn )
    {
      ::OpenRgn();
      
      for ( long i = 0; i < pRegion->numRects; i++ )
      {
          Rect r;
          r.left = pRegion->rects[i].x1;
          r.top = pRegion->rects[i].y1;
          r.right = pRegion->rects[i].x2;
          r.bottom = pRegion->rects[i].y2;
          
          ::FrameRect( &r );
      }
      
      ::CloseRgn( rgn );
    }

    return rgn;
}



/************************************************************************
 *  Method:
 *    CHXMacSite::_ConvertToHXEvent
 */
BOOL
CHXMacSite::_ConvertToHXEvent( HXxEvent* pEvent )
{
    if (pEvent->event == mouseDown || pEvent->event == mouseUp)
    {
      HXxWindow* pWindow = GetWindow();
      if (pWindow && pWindow->window)
      {
          GrafPtr savePort;
          GetPort(&savePort);

          WindowPtr w = (WindowPtr)pWindow->window;
          
          Point oldOrigin;
#if defined(_CARBON) || defined(_MAC_UNIX)
          SetPort( GetWindowPort(w) );
          Rect portRect;
          GetPortBounds( GetWindowPort(w), &portRect );
          oldOrigin.h = portRect.left;
          oldOrigin.v = portRect.top;
#else
          SetPort( w );
          oldOrigin.h = w->portRect.left;
          oldOrigin.v = w->portRect.top;
#endif
          static HXxPoint realPt = {0,0};
          
          EventRecord* macEvent = (EventRecord*)pEvent->param1;
          Point localPoint = macEvent->where;

          GlobalToLocal( &localPoint );

          realPt.x = localPoint.h;
          realPt.y = localPoint.v;

          UINT32 flags = 0;
          if (macEvent->modifiers & shiftKey) flags |= HX_SHIFT_KEY;
          if (macEvent->modifiers & controlKey) flags |= HX_CTRL_KEY;
          if (macEvent->modifiers & cmdKey) flags |= HX_ALT_COMMAND_KEY;
          
          if (flags & HX_CTRL_KEY)
          {
            pEvent->event = pEvent->event == mouseDown ?
                  HX_CONTEXT_BUTTON_DOWN : HX_CONTEXT_BUTTON_UP;
          }
          else
          {
            pEvent->event = pEvent->event == mouseDown ?
                  HX_PRIMARY_BUTTON_DOWN : HX_PRIMARY_BUTTON_UP;
          }
          pEvent->param1 = (void*)&realPt;
          pEvent->param2 = (void*)flags;

          SetPort(savePort);

          return FALSE;
      }
    }
    if (pEvent->event == nullEvent && _AtSystemTime())
    {
      EventRecord* macEvent = (EventRecord*)pEvent->param1;
      
      HXxWindow* pWindow = GetWindow();
      if (pWindow && pWindow->window)
      {
          WindowPtr w = (WindowPtr)pWindow->window;
          if (w == ::FrontWindow())
          {
            GrafPtr savePort;
            ::GetPort(&savePort);
#if defined(_CARBON) || defined(_MAC_UNIX)
            ::SetPort( GetWindowPort(w) );
#else
            ::SetPort(w);
#endif

            Point oldOrigin;

#if defined(_CARBON) || defined(_MAC_UNIX)
            Rect portRect;
            GetPortBounds( GetWindowPort( w ), &portRect );
            oldOrigin.h = portRect.left;
            oldOrigin.v = portRect.top;
#else
            oldOrigin.h = w->portRect.left;
            oldOrigin.v = w->portRect.top;
#endif
            
            // see if it's in this site

            Point p = macEvent->where;
            ::GlobalToLocal(&p);
            HXxPoint loc;
            loc.x = p.h;
            loc.y = p.v;
            
            HX_ASSERT(m_RegionForMouse);
            if (m_RegionForMouse && IsPointInClippingRegion(&loc))
            {
                static Point sLastGlobalLocation = {0,0};

                if (macEvent->where.h != sLastGlobalLocation.h || macEvent->where.v != sLastGlobalLocation.v)
                {
                  sLastGlobalLocation = macEvent->where;
                  Point localPt = sLastGlobalLocation;
                  ::GlobalToLocal(&localPt);

                  m_MostRecentConvertedMouseLoc.x = localPt.h;
                  m_MostRecentConvertedMouseLoc.y = localPt.v;

                  UINT32 flags = 0;
                  if (macEvent->modifiers & shiftKey) flags += HX_SHIFT_KEY;
                  if (macEvent->modifiers & controlKey) flags += HX_CTRL_KEY;
                  if (macEvent->modifiers & cmdKey) flags += HX_ALT_COMMAND_KEY;

                  // don't change the event until we're done looking at it!
                  // (the pre-converted version that is.)

                  pEvent->event = HX_MOUSE_MOVE;
                  pEvent->param1 = (void*)&m_MostRecentConvertedMouseLoc;
                  pEvent->param2 = (void*)flags;

                  // This will eventually be handled by the base site.
                  // It's possible that the base site will need to translate
                  // this into HX_MOUSE_ENTER and HX_MOUSE_LEAVE first,
                  // though, which is why we don't simply handle it here.
                }
            }
            else
            {
                if (m_pTopLevelSite->m_pMouseInSite == this)
                {
                  m_pTopLevelSite->GenerateMouseLeaveMessage();
                }
            }
            
            
            ::SetPort(savePort);
          }
      }
    }
    return FALSE; //pEvent->handled;
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_GenerateOSEvent
 */
void
CHXMacSite::_GenerateOSEvent(HXxEvent* pEvent, HXxEvent* pEvent2)
{
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_GenerateSetCursorEvent
 */
void
CHXMacSite::_GenerateSetCursorEvent()
{
    Point oldOrigin;

    HXxWindow* pWindow = GetWindow();
    if (!pWindow || !pWindow->window)
    {
      return;
    }

    WindowPtr w = (WindowPtr)pWindow->window;

    GrafPtr savePort;
    ::GetPort(&savePort);

#if defined(_CARBON) || defined(_MAC_UNIX)
    ::SetPort(::GetWindowPort(w));
#else
    ::SetPort(w);
#endif

#if defined(_CARBON) || defined(_MAC_UNIX)
    Rect portRect;
    GetPortBounds( GetWindowPort( w ), &portRect );
    oldOrigin.h = portRect.left;
    oldOrigin.v = portRect.top;
#else
    oldOrigin.h = w->portRect.left;
    oldOrigin.v = w->portRect.top;
#endif

    SetOriginAndMaintainClipRgn(-pWindow->x, -pWindow->y);

    HXxPoint offset = {0,0};
    GetMacContentAreaOffset(offset);

    SetOriginAndMaintainClipRgn(-offset.x, -offset.y);
    
    Point location;
    GetMouse(&location);

    HXxEvent theEvent;
    memset(&theEvent, 0, sizeof(theEvent));

    theEvent.event = HX_MOUSE_MOVE;
    
    HXxPoint mouseLoc;
    mouseLoc.x = location.h;
    mouseLoc.y = location.v;
    theEvent.param1 = (void*)&mouseLoc;
    
    SetOriginAndMaintainClipRgn(oldOrigin.h, oldOrigin.v);

    if (m_pUser)
      m_pUser->HandleEvent(&theEvent);

    ::SetPort(savePort);
}


void
CHXMacSite::_ScaleFullScreen(HXxWindow* pWindow)
{
    if (m_pParentSite != nil)
    {
      CHXMacSite* pParentSite = (CHXMacSite*)m_pParentSite;
      m_fStretchMultiple = pParentSite->m_fStretchMultiple;
      m_pHXxFullScreenWindow->window = pParentSite->m_pHXxFullScreenWindow->window;
      
      if (0 /*pParentSite->m_pStatusSite == this*/)
      {
      }
      else
      {
          if (m_pWindow) pWindow = m_pWindow;
          
          m_pHXxFullScreenWindow->x = (long)((double)pWindow->x * m_fStretchMultiple);
          m_pHXxFullScreenWindow->y = (long)((double)pWindow->y * m_fStretchMultiple);
          m_pHXxFullScreenWindow->width = (long)((double)pWindow->width * m_fStretchMultiple);
          m_pHXxFullScreenWindow->height = (long)((double)pWindow->height * m_fStretchMultiple);
          
          m_pHXxFullScreenWindow->clipRect.left = (long)((double)pWindow->clipRect.left * m_fStretchMultiple);
          m_pHXxFullScreenWindow->clipRect.top = (long)((double)pWindow->clipRect.top * m_fStretchMultiple);
          m_pHXxFullScreenWindow->clipRect.right = (long)((double)pWindow->clipRect.right * m_fStretchMultiple);
          m_pHXxFullScreenWindow->clipRect.bottom = (long)((double)pWindow->clipRect.bottom * m_fStretchMultiple);
      }
    }


    CHXMapPtrToPtr::Iterator i = m_ChildrenMap.Begin();
    for ( ; i != m_ChildrenMap.End(); ++i)
    {
      CHXBaseSite* pSite = (CHXBaseSite*) *i;
      
      CHXMacSite* pMacSite = (CHXMacSite*)pSite;
      pMacSite->_ScaleFullScreen(pWindow);
    }
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_EnterFullScreen
 */
HX_RESULT
CHXMacSite::_EnterFullScreen()
{
    if (zm_bFullScreenActive)
    {
      return HXR_UNEXPECTED;
    }
    
    zm_bFullScreenActive = TRUE;
    
    if (m_pTopLevelSite == this)
    {
      short desiredWidth, desiredHeight;
      
      GDHandle aGD = ::GetMainDevice();
      
      // Check the UseOverlay preference here, since _OverlayAvailable() doesn't update its
      // value on Preference changes.
      BOOL bDoScreenResSwitch = FALSE;
      IHXPreferences* pPreferences = NULL;
      if (m_pContext && (HXR_OK == m_pContext->QueryInterface(IID_IHXPreferences, (void**)&pPreferences)))
      {
          IHXBuffer* pBuffer = NULL;
          if (pPreferences->ReadPref("UseOverlay", pBuffer) == HXR_OK)
          {
            bDoScreenResSwitch = ::atoi((char*)pBuffer->GetBuffer()) != 1;
          }
          HX_RELEASE(pBuffer);
      }
      HX_RELEASE(pPreferences);
      
      if (!bDoScreenResSwitch)
      {
          // if an overlay exists then let's assume we don't have
          // to switch resolutions.
          desiredWidth = (**aGD).gdRect.right - (**aGD).gdRect.left;
          desiredHeight = (**aGD).gdRect.bottom - (**aGD).gdRect.top;
      }
      else
      {
          desiredWidth = m_size.cx;
          desiredHeight = m_size.cy;
      }
      
      ::BeginFullScreen(
            &zm_pRememberFullScreenInformation,
            ::GetMainDevice(),
            &desiredWidth,
            &desiredHeight,
            nil,
            nil,
            fullScreenAllowEvents );
      
      _DestroySliders();
      
      CMacRootSurface::VisRgnChangedCallback();
      
      GDHandle mainGD = ::GetMainDevice();
      Rect bounds = (**mainGD).gdRect;
      
      if (m_pHXxFullScreenWindow && m_pHXxFullScreenWindow->window)
      {
          WindowPtr w = (WindowPtr)m_pHXxFullScreenWindow->window;
          ::ShowWindow(w);
          ::SizeWindow(w, bounds.right-bounds.left, bounds.bottom-bounds.top, true);
          ::MoveWindow(w, bounds.left, bounds.top, true);
          
          HXxPoint newPosition;
          newPosition.x = bounds.left;
          newPosition.y = bounds.top;
          
          HXxSize newSize;
          newSize.cx = bounds.right-bounds.left;
          newSize.cy = bounds.bottom-bounds.top;
          
          double theXZoomFactor = (double)newSize.cx / (double)m_pWindow->width;
          double theYZoomFactor = (double)newSize.cy / (double)m_pWindow->height;
          
          if (theXZoomFactor < theYZoomFactor)
          {
            theYZoomFactor = theXZoomFactor;
            newSize.cy = (long)((double)m_pWindow->height * theYZoomFactor);
            
            newPosition.y += ((bounds.bottom-bounds.top)-newSize.cy)/2;
          }
          else
          {
            theXZoomFactor = theYZoomFactor;
            newSize.cx = (long)((double)m_pWindow->width * theXZoomFactor);
            
            newPosition.x += ((bounds.right-bounds.left)-newSize.cx)/2;
          }
          m_fStretchMultiple = theXZoomFactor;
          
          m_pHXxFullScreenWindow->x = newPosition.x;
          m_pHXxFullScreenWindow->y = newPosition.y;
          
          m_pHXxFullScreenWindow->width = newSize.cx;
          m_pHXxFullScreenWindow->height = newSize.cy;
          
          m_pHXxFullScreenWindow->clipRect.left = newPosition.x;
          m_pHXxFullScreenWindow->clipRect.top = newPosition.y;
          m_pHXxFullScreenWindow->clipRect.right = newPosition.x + newSize.cx;
          m_pHXxFullScreenWindow->clipRect.bottom = newPosition.y + newSize.cy;
          
#if defined(_CARBON) || defined(_MAC_UNIX)
          ::SetPort( GetWindowPort( (WindowPtr)m_pHXxFullScreenWindow->window ) );
#else
          ::SetPort((WindowPtr)m_pHXxFullScreenWindow->window);
#endif
          RGBColor holdRGB;
          RGBColor theRGB = {0x0000, 0x0000, 0x0000};
          ::GetBackColor(&holdRGB);
          ::RGBBackColor(&theRGB);
          ::EraseRect(&bounds);
          ::RGBBackColor(&holdRGB);
          
          if (m_bInternalResizeOnFullscreen)
          {
            GetSize(m_RememberNonFullscreenSize);
            GetPosition(m_RememberNonFullscreenPosition);
            m_pTopLevelSite->m_bDisableForceRedraw = TRUE;
            SetSize(newSize);
            m_pTopLevelSite->m_bDisableForceRedraw = FALSE;
            SetPosition(newPosition);
          }
          else
          {
            _ScaleFullScreen(m_pWindow);
          }

          SetOriginAndMaintainClipRgn(-m_pHXxFullScreenWindow->x, -m_pHXxFullScreenWindow->y);
      }
      m_bInFullScreen = TRUE;
    }
    
    return HXR_OK;
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_ExitFullScreen
 */
HX_RESULT
CHXMacSite::_ExitFullScreen()
{
    CMacRootSurface::VisRgnChangedCallback();
    if (m_pTopLevelSite == this)
    {
      m_bInFullScreen = FALSE;
      _DestroySliders();
      
      if (m_pHXxFullScreenWindow && m_pHXxFullScreenWindow->window)
      {
          WindowPtr w = (WindowPtr)m_pHXxFullScreenWindow->window;
          GrafPtr savePort;
          ::GetPort(&savePort);
          ::SetPort(::GetWindowPort(w));
          // we need to restore the origin for the next time we may
          // enter fullscreen mode. xxxbobclark
          SetOriginAndMaintainClipRgn(0,0);
          ::HideWindow(w);
          ::SetPort(savePort);
      }

      if (!m_bInternalResizeOnFullscreen)
      {
          HXxSize fullscreenSize;

          fullscreenSize.cx = m_pHXxFullScreenWindow->width;
          fullscreenSize.cy = m_pHXxFullScreenWindow->height;

          HXxSize nonfullscreenSize;

          nonfullscreenSize.cx = (long)((double)fullscreenSize.cx / m_fStretchMultiple);
          nonfullscreenSize.cy = (long)((double)fullscreenSize.cy / m_fStretchMultiple);

          if (m_pWatcher)
          {
            HRESULT hres = m_pWatcher->ChangingSize(fullscreenSize, nonfullscreenSize);
          }
      }
      
      ::EndFullScreen(zm_pRememberFullScreenInformation, nil);
      
    }
    
    if (CMacSurface::zm_pOverlaySurface == (CMacSurface*)m_pVideoSurface)
    {
      CMacSurface::CleanUpOverlay();
      CMacSurface::zm_pOverlaySurface = nil;
    }
    zm_bFullScreenActive = FALSE;

    if (m_pTopLevelSite == this)
    {
      if (m_bInternalResizeOnFullscreen)
      {
          m_pTopLevelSite->m_bDisableForceRedraw = TRUE;
          SetSize(m_RememberNonFullscreenSize);
          m_pTopLevelSite->m_bDisableForceRedraw = FALSE;
          SetPosition(m_RememberNonFullscreenPosition);
      }
    }
    
    return HXR_OK;
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_TestFullScreen
 */
HX_RESULT
CHXMacSite::_TestFullScreen(void* hTestBitmap, const char* pszStatusText)
{
    return HXR_OK;
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_TryCreateXSlider
 */
void
CHXMacSite::_TryCreateXSlider()
{
    if (!IsSiteVisible())
    {
      return;
    }
    
    HXxWindow* pWindow = GetWindow();
    if (!pWindow || !pWindow->window)
    {
      return;
    }
    
    WindowPtr w = (WindowPtr)pWindow->window;
    
    GrafPtr savePort;
    ::GetPort(&savePort);
    ::SetPort(::GetWindowPort(w));
    
    Point oldOrigin;
    Rect portRect;
    ::GetPortBounds(::GetWindowPort(w), &portRect);
    oldOrigin.h = portRect.left;
    oldOrigin.v = portRect.top;
    
    SetOriginAndMaintainClipRgn(0,0); // scroll bar maintenance requires origin at 0,0.
    
    HXxPoint offset = {0,0};
    GetMacContentAreaOffset(offset);
    
    HXxPoint position;
    HXxSize size;
    
    HX_ASSERT(GetParentSite());
    
    if (GetParentSite())
    {
      GetParentSite()->GetSize(size);
      position.x = 0;
      position.y = 0;
    }
    
    Rect controlRect;
    controlRect.left = position.x + offset.x;
    controlRect.top = position.y + offset.y + size.cy - SCROLL_BAR_WIDTH;
    controlRect.right = controlRect.left + size.cx;
    controlRect.bottom = controlRect.top + SCROLL_BAR_WIDTH;
    
    if (m_hHScrollBar && ::GetControlOwner(m_hHScrollBar) != w)
    {
      ::DisposeControl(m_hHScrollBar);
      m_hHScrollBar = NULL;
      m_XSliderPos = 0;
    }
    
    if (m_hHScrollBar)
    {
      // if it already exists, then we may simply need to
      // move it...
      Rect oldControlRect;
      ::GetControlBounds(m_hHScrollBar, &oldControlRect);
      
      if (!::EqualRect(&oldControlRect, &controlRect))
      {
          ::SetControlBounds(m_hHScrollBar, &controlRect);
          ::InvalWindowRect(w, &oldControlRect);
      }
    }
    else
    {
      ::CreateScrollBarControl(w, &controlRect, 0, 0, 2, 1, false, NULL, &m_hHScrollBar);
      ::SetControlReference(m_hHScrollBar, 0);
    }
    
    // invaling the rect seems to ameliorate this problem where extra scrollbars
    // were being spuriously displayed.
    ::InvalWindowRect(w, &controlRect);
    
    SetOriginAndMaintainClipRgn(oldOrigin.h, oldOrigin.v);
    ::SetPort(savePort);
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_SetXSliderValues
 */
void
CHXMacSite::_SetXSliderValues(INT32 range, INT32 pageSize)
{
    HXxWindow* pWindow = GetWindow();
    if (!pWindow || !pWindow->window)
    {
      return;
    }
    
    WindowPtr w = (WindowPtr)pWindow->window;
    
    Point oldOrigin;
    Rect portRect;
    ::GetPortBounds(::GetWindowPort(w), &portRect);
    oldOrigin.h = portRect.left;
    oldOrigin.v = portRect.top;
    
    SetOriginAndMaintainClipRgn(0,0);
    
    ::SetControl32BitMinimum(m_hHScrollBar, 0);
    ::SetControl32BitMaximum(m_hHScrollBar, range - pageSize);
    ::SetControlViewSize(m_hHScrollBar, pageSize);
    
    ::SetControl32BitValue(m_hHScrollBar, m_XSliderPos);
    
    m_nHorizPageSize = pageSize / 2;
    
    SetOriginAndMaintainClipRgn(oldOrigin.h, oldOrigin.v);
    SetMacControlRange(m_hHScrollBar, range);
    
    m_nHorizPageSize = pageSize;
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_TryCreateYSlider
 */
void
CHXMacSite::_TryCreateYSlider()
{
    if (!IsSiteVisible())
    {
      return;
    }
    
    HXxWindow* pWindow = GetWindow();
    if (!pWindow || !pWindow->window)
    {
      return;
    }
    
    WindowPtr w = (WindowPtr)pWindow->window;
    
    GrafPtr savePort;
    ::GetPort(&savePort);
    ::SetPort(::GetWindowPort(w));
    
    Point oldOrigin;
    Rect portRect;
    ::GetPortBounds(::GetWindowPort(w), &portRect);
    oldOrigin.h = portRect.left;
    oldOrigin.v = portRect.top;
    
    HXxPoint offset = {0,0};
    GetMacContentAreaOffset(offset);
    
    SetOriginAndMaintainClipRgn(0,0);
    
    HXxPoint position;
    HXxSize size;
    
    HX_ASSERT(GetParentSite());
    
    if (GetParentSite())
    {
      GetParentSite()->GetSize(size);
      
      position.x = 0;
      position.y = 0;
    }
    
    Rect controlRect;
    controlRect.left = position.x + offset.x + size.cx - SCROLL_BAR_WIDTH;
    controlRect.top = position.y + offset.y;
    controlRect.right = controlRect.left + SCROLL_BAR_WIDTH;
    controlRect.bottom = controlRect.top + size.cy;
    
    if (_DoesXSliderExist())
    {
      controlRect.bottom -= SCROLL_BAR_WIDTH; // ensure that both scroll bars don't overlap at the bottom right corner
    }
    
    if (m_hVScrollBar && ::GetControlOwner(m_hVScrollBar) != w)
    {
      ::DisposeControl(m_hVScrollBar);
      m_hVScrollBar = NULL;
      m_YSliderPos = 0;
    }
    
    if (m_hVScrollBar)
    {
      Rect oldControlRect;
      ::GetControlBounds(m_hVScrollBar, &oldControlRect);
      
      if (!::EqualRect(&oldControlRect, &controlRect))
      {
          ::SetControlBounds(m_hVScrollBar, &controlRect);
          ::InvalWindowRect(w, &oldControlRect);
      }
    }
    else
    {
      ::CreateScrollBarControl(w, &controlRect, 0, 0, 2, 1, false, NULL, &m_hVScrollBar);
      ::SetControlReference(m_hVScrollBar, 0);
    }
    
    ::InvalWindowRect(w, &controlRect);
    
    SetOriginAndMaintainClipRgn(oldOrigin.h, oldOrigin.v);
    ::SetPort(savePort);
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_SetYSliderValues
 */
void
CHXMacSite::_SetYSliderValues(INT32 range, INT32 pageSize)
{
    HXxWindow* pWindow = GetWindow();
    if (!pWindow || !pWindow->window)
    {
      return;
    }
    
    WindowPtr w = (WindowPtr)pWindow->window;
    
    Point oldOrigin;
    Rect portRect;
    ::GetPortBounds(::GetWindowPort(w), &portRect);
    oldOrigin.h = portRect.left;
    oldOrigin.v = portRect.top;
    
    SetOriginAndMaintainClipRgn(0,0);
    
    ::SetControl32BitMinimum(m_hVScrollBar, 0);
    ::SetControl32BitMaximum(m_hVScrollBar, range-pageSize);
    ::SetControlViewSize(m_hVScrollBar, pageSize);
    
    ::SetControl32BitValue(m_hVScrollBar, m_YSliderPos);
    
    m_nVertPageSize = pageSize / 2;
    
    SetOriginAndMaintainClipRgn(oldOrigin.h, oldOrigin.v);
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_GetSystemSizeOfSliders
 */
void
CHXMacSite::_GetSystemSizeOfSliders(INT32* pWidth, INT32* pHeight)
{
    if (pWidth) *pWidth = SCROLL_BAR_WIDTH;
    if (pHeight) *pHeight = SCROLL_BAR_WIDTH;
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_IsWindowVisible
 */
BOOL
CHXMacSite::_IsWindowVisible()
{
    return TRUE;
}

/************************************************************************
 *  Method:
 *    CHXMacSite::ShowMacControl
 */
void
CHXMacSite::ShowMacControl(ControlHandle theControl, BOOL bShow)
{
    if (theControl)
    {
      if (bShow)
      {
          ::ShowControl(theControl);
      }
      else
      {
          ::HideControl(theControl);
      }
    }
}

/************************************************************************
 *  Method:
 *    CHXMacSite::SetMacControlRectangle
 */
void
CHXMacSite::SetMacControlRectangle(ControlHandle theControl,
            INT32 left, INT32 top, INT32 right, INT32 bottom )
{
    if (theControl)
    {
      ::SizeControl(theControl, right-left, bottom-top);
      ::MoveControl(theControl, left, top);
    }
}

void
CHXMacSite::SetMacControlRange(ControlHandle theControl, INT32 controlMax)
{
    if (theControl)
    {
        ::SetControl32BitMinimum(theControl, 0);
        ::SetControl32BitMaximum(theControl, controlMax);
    }
}


/************************************************************************
 *  Method:
 *    CHXMacSite::_ShowXSlider
 */
void
CHXMacSite::_ShowXSlider(BOOL bShow)
{
    HXxWindow* pWindow = GetWindow();
    if (!pWindow || !pWindow->window)
    {
      return;
    }
    WindowPtr w = (WindowPtr)pWindow->window;
    Point oldOrigin;
    Rect portRect;
    ::GetPortBounds( ::GetWindowPort(w), &portRect);
    oldOrigin.h = portRect.left;
    oldOrigin.v = portRect.top;
    
    SetOriginAndMaintainClipRgn(0,0);
    
    ShowMacControl(m_hHScrollBar, bShow);
    
    SetOriginAndMaintainClipRgn(oldOrigin.h, oldOrigin.v);
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_MoveXSlider
 */
void
CHXMacSite::_MoveXSlider(INT32 left, INT32 top, INT32 right, INT32 bottom, BOOL bRedraw)
{
    // xxxbobclark do nothing right now
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_ShowYSlider
 */
void
CHXMacSite::_ShowYSlider(BOOL bShow)
{
    HXxWindow* pWindow = GetWindow();
    if (!pWindow || !pWindow->window)
    {
      return;
    }
    WindowPtr w = (WindowPtr)pWindow->window;
    Point oldOrigin;
    Rect portRect;
    ::GetPortBounds(::GetWindowPort(w), &portRect);
    oldOrigin.h = portRect.left;
    oldOrigin.v = portRect.top;
    
    SetOriginAndMaintainClipRgn(0,0);
    
    ShowMacControl(m_hVScrollBar, bShow);
    
    SetOriginAndMaintainClipRgn(oldOrigin.h, oldOrigin.v);
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_MoveYSlider
 */
void
CHXMacSite::_MoveYSlider(INT32 left, INT32 top, INT32 right, INT32 bottom, BOOL bRedraw)
{
    // xxxbobclark don't do anything right now
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_DoesXSliderExist
 */
BOOL
CHXMacSite::_DoesXSliderExist()
{
    if (m_hHScrollBar) return TRUE;
    return FALSE;
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_GetContainingWindow
 */
void*
CHXMacSite::_GetContainingWindow()
{
    if (m_pParentSite) return m_pParentSite->_GetContainingWindow();
    return NULL;
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_GetCursorPos
 */
void
CHXMacSite::_GetCursorPos(HXxPoint* pPoint)
{
    // this will return in global coordinates. (???)

    HX_ASSERT(_AtSystemTime());
    if (!_AtSystemTime()) return;
    
    HX_ASSERT(pPoint);
    if (!pPoint) return;
    
    Point pt;
    ::GetMouse(&pt);
    // pt is in local coordinates
    
    ::LocalToGlobal(&pt);
    
    pPoint->x = pt.h;
    pPoint->y = pt.v;
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_MapPointToOSWindow
 */
void
CHXMacSite::_MapPointToOSWindow(HXxPoint* pPt, void** pWindowHandle)
{
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_GetWindowWithCursor
 */
void*
CHXMacSite::_GetWindowWithCursor()
{
    return NULL;
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_ReInitPrimarySurface
 */
void
CHXMacSite::_ReInitPrimarySurface()
{
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_MoveWindow
 */
BOOL
CHXMacSite::_MoveWindow(void* window, INT32 X, INT32 Y, INT32 nWidth, INT32 nHeight, BOOL bRepaint)
{
    return TRUE;
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_UpdateWindow
 */
BOOL
CHXMacSite::_UpdateWindow(void* hWnd)
{
    return TRUE;
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_ShowWindow
 */
BOOL
CHXMacSite::_ShowWindow(void* hWnd, INT32 nCmdShow)
{
    return TRUE;
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_SetWindowPos
 */
BOOL
CHXMacSite::_SetWindowPos(void* hWnd, void* hWndInsertAfter, INT32 X, INT32 Y, INT32 cx, INT32 cy, INT32 uFlags)
{
    return TRUE;
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_SetWindowRgn
 */
BOOL
CHXMacSite::_SetWindowRgn(void* hWnd, HXREGION* hRgn, BOOL bRedraw)
{
    return TRUE;
}

/************************************************************************
 *  Method:
 *    CHXMacSite::_SetFocus
 */
void
CHXMacSite::_SetFocus(void* pWindow)
{
}


/************************************************************************
 *  Method:
 *    CHXMacSite::GetMacContentAreaOffset
 */
void
CHXMacSite::GetMacContentAreaOffset(REF(HXxPoint)offset)
{
    offset.x = m_topleft.x;
    offset.y = m_topleft.y;
    
    HXxWindow* pWindow = GetWindow();
    
    if (pWindow)
    {
      offset.x += pWindow->x;
      offset.y += pWindow->y;
    }
    
    return;
}


#pragma export on

extern "C" void MacSiteHandleAllEvents(HXxEvent* pEvent)
{
    CHXMacSite::_HandleAllOSEvents(pEvent);
}

#pragma export off


/************************************************************************
 *  Callback implementation
 */

/************************************************************************
 *  Method:
 *    CHXMacSite::MacSiteRedrawCallback ctor
 */

CHXMacSite::MacSiteRedrawCallback::MacSiteRedrawCallback(CHXMacSite* pMacSite)
 : m_lRefCount(0)
 , m_ulMacSiteRedrawCallbackPendingID(0)
 , m_pMacSite(pMacSite)
{
}

/************************************************************************
 *  Method:
 *    CHXMacSite::MacSiteRedrawCallback dtor
 */

CHXMacSite::MacSiteRedrawCallback::~MacSiteRedrawCallback()
{
}

/************************************************************************
 *  Method:
 *    CHXMacSite::MacSiteRedrawCallback::QueryInterface
 */

STDMETHODIMP
CHXMacSite::MacSiteRedrawCallback::QueryInterface(REFIID riid, void** ppvObj)
{
    if (IsEqualIID(riid, IID_IHXCallback))
    {
      AddRef();
      *ppvObj = (IHXCallback*)this;
      return HXR_OK;
    }
    else if (IsEqualIID(riid, IID_IUnknown))
    {
        AddRef();
        *ppvObj = this;
        return HXR_OK;
    }

    *ppvObj = NULL;
    return HXR_NOINTERFACE;
}

/************************************************************************
 *  Method:
 *    CHXMacSite::MacSiteRedrawCallback::AddRef
 */

STDMETHODIMP_(ULONG32)
CHXMacSite::MacSiteRedrawCallback::AddRef()
{
    return InterlockedIncrement( &m_lRefCount );
}

/************************************************************************
 *  Method:
 *    CHXMacSite::MacSiteRedrawCallback::Release
 */

STDMETHODIMP_(ULONG32)
CHXMacSite::MacSiteRedrawCallback::Release()
{
    if ( InterlockedDecrement( &m_lRefCount ) > 0 )
    {
      return m_lRefCount;
    }
    
    delete this;
    return 0;
}

/************************************************************************
 *  Method:
 *    CHXMacSite::MacSiteRedrawCallback::Func
 */

STDMETHODIMP
CHXMacSite::MacSiteRedrawCallback::Func()
{
    m_pMacSite->_TLSLock();
    
    m_ulMacSiteRedrawCallbackPendingID = NULL;
    m_pMacSite->ForceRedraw();
    
    m_pMacSite->_TLSUnlock();
    
    return HXR_OK;
}


#ifdef THREADS_SUPPORTED

#ifdef USE_CARBON_TIMER
/************************************************************************
 *  Method:
 *    CHXMacSite::Redraw(something)Timer
 */

/*static*/
#ifdef _MAC_MACHO
void CHXMacSite::RedrawCFTimer(CFRunLoopTimerRef, CHXMacSite* pMacSite)
#else
void CHXMacSite::RedrawCarbonTimer(EventLoopTimerRef, CHXMacSite* pMacSite)
#endif
{
    // XXXMEH
    MLOG_BLT(NULL,
             "%lu\t----macsite.cpp--- RedrawCarbonTimer()\n",
             HX_GET_BETTERTICKCOUNT());
    HX_ASSERT( pMacSite );

    HX_ASSERT(IsMacInCooperativeThread());

    if (pMacSite->m_pIHXCoreMutex) pMacSite->m_pIHXCoreMutex->LockCoreMutex();
    
    // this huge block of code is adapted from the base site's implementation of
    // InternalScheduleUpgrade, where it needs to match up an IHXPlayer with this
    // site. In this case, we're protecting ourselves against rug-pulling, i.e.
    // if a stream has ended and stuff has been deleted, it's still possible (due
    // to the Carbon Timer's behavior of delaying redraws) that there's a pending
    // ForceRedraw() that wants to happen. If there's no player for this site, or
    // if the player is done, then we'll omit the blit.
    
    // On a one-gigahertz processor, this checking function is taking
    // between 20 and 30 microseconds; it may be worthwhile to save the
    // player in a member variable.
    
    bool bPlayerStillRunning = false;
    
    IHXPreferences* pPreferences = NULL;
    IHXBuffer* pBuffer = NULL;
    
    IHXClientEngine* pClientEngine = NULL;
    if (HXR_OK == pMacSite->m_pContext->QueryInterface(IID_IHXClientEngine, (void**)&pClientEngine))
    {
        UINT16 nPlayerCount = pClientEngine->GetPlayerCount();
        IUnknown* pUnknown = NULL;
        
        if (nPlayerCount == 1)
        {
            // wow, this was easy -- this is the only player then.
            pClientEngine->GetPlayer(0, pUnknown);
        }
        else
        {
            IHXSite* pThisSite = NULL;
            
            pMacSite->QueryInterface(IID_IHXSite, (void**)&pThisSite);
            HX_ASSERT(pThisSite);
            
            UINT16 index;
            for (index = 0; index < nPlayerCount; index++)
            {
                IHXSiteManager2* pSiteMgr2 = NULL;
                IUnknown* pUnknownPlayer = NULL;
                
                pClientEngine->GetPlayer(index, pUnknownPlayer);
                HX_ASSERT(pUnknownPlayer);
                
                pUnknownPlayer->QueryInterface(IID_IHXSiteManager2, (void**)&pSiteMgr2);
                if (pSiteMgr2)
                {
                    UINT32 nNumSites;
                    pSiteMgr2->GetNumberOfSites(nNumSites);
                    UINT32 index2;
                    for (index2 = 0; index2 < nNumSites; index2++)
                    {
                        IHXSite* pIterationSite = NULL;
                        pSiteMgr2->GetSiteAt(index2, pIterationSite);
                        if (pThisSite == pIterationSite)
                        {
                            // it matches!
                            HX_ASSERT(pUnknown == NULL);
                            pUnknown = pUnknownPlayer;
                            pUnknown->AddRef();
                        }
                    }
                    HX_RELEASE(pSiteMgr2);
                }
                HX_RELEASE(pUnknownPlayer);
            }
            
            HX_RELEASE(pThisSite);
        }
        
        if (pUnknown)
        {
            IHXPlayer* pPlayer;
            
            pUnknown->QueryInterface(IID_IHXPlayer, (void**)&pPlayer);
            if (pPlayer)
            {
                if (!pPlayer->IsDone())
                {
                    bPlayerStillRunning = true;
                }
                HX_RELEASE(pPlayer);
            }
            HX_RELEASE(pUnknown);
        }
        
        HX_RELEASE(pClientEngine);
    }
    
    if (bPlayerStillRunning)
    {
        pMacSite->ForceRedraw();
    }
    
    if (pMacSite->m_pIHXCoreMutex) pMacSite->m_pIHXCoreMutex->UnlockCoreMutex();
}
#endif
#endif

Generated by  Doxygen 1.6.0   Back to index