📄 macsite.cpp
字号:
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
// remember old origin
#if defined(_CARBON) || defined(_MAC_UNIX)
Rect portRect;
GetPortBounds( GetWindowPort( w ), &portRect );
m_RememberMacOrigin.h = portRect.left;
m_RememberMacOrigin.v = portRect.top;
#else
m_RememberMacOrigin.h = w->portRect.left;
m_RememberMacOrigin.v = w->portRect.top;
#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;
}
// set new origin
// xxxbobclark
// Sheesh. OK, so the clip region is relative to the current
// origin, but it is NOT magically shifted when you call
// SetOrigin. So whenever you call SetOrigin, you're also
// "secretly" changing which actual pixels of the window are
// within the clip region.
// That's why this utility function was written
SetOriginAndMaintainClipRgn(-offset.x, -offset.y);
}
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)
{
// restore old origin
SetOriginAndMaintainClipRgn(m_RememberMacOrigin.h, m_RememberMacOrigin.v);
::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(¤tPSN);
::GetFrontProcess(&frontPSN);
Boolean bCurrentIsFront = TRUE;
::SameProcess(¤tPSN, &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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -