📄 macsite.cpp
字号:
/* ***** BEGIN LICENSE BLOCK *****
* Version: RCSL 1.0/RPSL 1.0
*
* Portions Copyright (c) 1995-2002 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
* Version 1.0 (the "RPSL") available at
* http://www.helixcommunity.org/content/rpsl unless you have licensed
* the file under the RealNetworks Community Source License Version 1.0
* (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.
*
* 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_RememberMacOrigin.h = 0;
m_RememberMacOrigin.v = 0;
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
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -