📄 bltpatch.cpp
字号:
index = 0;
newdesc->routineRecords[index].procDescriptor = (ProcPtr)my_SendBehindPatch;
newdesc->routineRecords[index].ISA = GetCurrentArchitecture();
}
NSetTrapAddress((UniversalProcPtr) newdesc, _SendBehind, (_SendBehind & 0x0800) ? ToolTrap : OSTrap);
}
gBlitInfo.theMenuIsDown = false;
gBlitInfo.thisApplicationIsFrontmost = true;
gBlitInfo.clientPSN.highLongOfPSN = 0;
gBlitInfo.clientPSN.lowLongOfPSN = 0;
gBlitInfo.MenuUpCallback = nil;
gBlitInfo.VisRgnChangedCallback = nil;
for ( i = 0; i < kMaxMenuRects; i++ )
{
gBlitInfo.theMenuRects[i].left = 0;
gBlitInfo.theMenuRects[i].top = 0;
gBlitInfo.theMenuRects[i].right = 0;
gBlitInfo.theMenuRects[i].bottom = 0;
}
// restore to original heap
SetZone(theZone);
}
pascal void UnpatchBlitSupport( void )
{
if (!gInterruptBlitPatchesInstalled) return;
NSetTrapAddress(gOriginal_CopyBits, _CopyBits, (_CopyBits & 0x0800) ? ToolTrap : OSTrap);
NSetTrapAddress(gOriginal_MenuSelect, _MenuSelect, (_MenuSelect & 0x0800) ? ToolTrap : OSTrap);
NSetTrapAddress(gOriginal_PopupMenuSelect, _PopUpMenuSelect, (_PopUpMenuSelect & 0x0800) ? ToolTrap : OSTrap);
NSetTrapAddress(gOriginal_MoveWindow, _MoveWindow, (_MoveWindow & 0x0800) ? ToolTrap : OSTrap);
NSetTrapAddress(gOriginal_WaitNextEvent, _WaitNextEvent, (_WaitNextEvent & 0x0800) ? ToolTrap : OSTrap);
NSetTrapAddress(gOriginal_CloseWindow, _CloseWindow, (_CloseWindow & 0x0800) ? ToolTrap : OSTrap);
NSetTrapAddress(gOriginal_SelectWindow, _SelectWindow, (_SelectWindow & 0x0800) ? ToolTrap : OSTrap);
NSetTrapAddress(gOriginal_PaintBehind, _PaintBehind, (_PaintBehind & 0x0800) ? ToolTrap : OSTrap);
NSetTrapAddress(gOriginal_BringToFront, _BringToFront, (_BringToFront & 0x0800) ? ToolTrap : OSTrap);
NSetTrapAddress(gOriginal_SendBehind, _SendBehind, (_SendBehind & 0x0800) ? ToolTrap : OSTrap);
gInterruptBlitPatchesInstalled = FALSE;
}
pascal void my_CopyBitsPatch(long param1, long param2, long param3, long param4, short param5, long param6)
{
int i;
if ( gBlitInfo.theMenuIsDown )
{
Rect r = *(Rect*)param3; // source rect
PixMap* pmp = (PixMap*)param1; // source pixmap
// I THINK that if it's blitting FROM anywhere with a non-zero y coordinate,
// that it's sucking it from the screen. How safe is this assumption?
// I further think that if it's blitting TO a location (0,0) with the same
// width and height as the "from" rectangle, that it's definitely saving
// the screen beneath where it's gonna put the menu.
Rect srcR = *(Rect*)param3;
Rect dstR = *(Rect*)param4;
if ( srcR.top > 0 && dstR.left == 0 && dstR.top == 0 && dstR.right == (srcR.right - srcR.left) && dstR.bottom == (srcR.bottom - srcR.top) )
{
// Basically, if it's blitting FROM a non-zero y coordinate then
// it's pulling it from the screen. So if that's the case then add
// to this list of rectangles.
Boolean bDealtWith = false;
// OK, first, ensure that this rectangle isn't totally enclosed by
// an already-existing rectangle. If so we don't need to remember THIS
// one.
for ( i = 0; i < kMaxMenuRects; i++ )
{
if ( gBlitInfo.theMenuRects[i].left <= srcR.left &&
gBlitInfo.theMenuRects[i].top <= srcR.top &&
gBlitInfo.theMenuRects[i].right >= srcR.right &&
gBlitInfo.theMenuRects[i].bottom >= srcR.bottom )
{
bDealtWith = true;
}
}
i = 0;
while ( !bDealtWith )
{
if ( gBlitInfo.theMenuRects[i].left == 0 &&
gBlitInfo.theMenuRects[i].top == 0 &&
gBlitInfo.theMenuRects[i].right == 0 &&
gBlitInfo.theMenuRects[i].bottom == 0 )
{
bDealtWith = true;
gBlitInfo.theMenuRects[i] = srcR;
}
i++;
if ( i >= kMaxMenuRects ) bDealtWith = true;
}
}
r = *(Rect*)param4; // destination rect
pmp = (PixMap*)param2;
}
CALL_SIX_PARAMETER_UPP( gOriginal_CopyBits, upp_CopyBitsProcInfo, param1, param2, param3, param4, param5, param6);
// Now check to see if it's blitting BACK TO the screen -- ie, a menu is going
// away. If it equals one of the menu rectangles that's currently saved and
// remove it from the list if so.
if ( gBlitInfo.theMenuIsDown )
{
Rect dstR = *(Rect*)param4;
for ( i = 0; i < kMaxMenuRects; i++ )
{
if ( gBlitInfo.theMenuRects[i].left != 0 ||
gBlitInfo.theMenuRects[i].top != 0 ||
gBlitInfo.theMenuRects[i].right != 0 ||
gBlitInfo.theMenuRects[i].bottom != 0 )
{
if ( dstR.left == gBlitInfo.theMenuRects[i].left &&
dstR.top == gBlitInfo.theMenuRects[i].top &&
dstR.right == gBlitInfo.theMenuRects[i].right &&
dstR.bottom == gBlitInfo.theMenuRects[i].bottom )
{
// Hmmm, so it directly matches...
gBlitInfo.theMenuRects[i].left = 0;
gBlitInfo.theMenuRects[i].top = 0;
gBlitInfo.theMenuRects[i].right = 0;
gBlitInfo.theMenuRects[i].bottom = 0;
if ( gBlitInfo.MenuUpCallback != nil )
{
// call back that callback, passing in that surface object
((MenuCallbackProc)gBlitInfo.MenuUpCallback)( &dstR );
}
}
}
}
}
}
pascal long my_MenuSelectPatch(long param1)
{
long result;
int i;
gBlitInfo.theMenuIsDown = true;
for ( i = 0; i < kMaxMenuRects; i++ )
{
gBlitInfo.theMenuRects[i].left = 0;
gBlitInfo.theMenuRects[i].top = 0;
gBlitInfo.theMenuRects[i].right = 0;
gBlitInfo.theMenuRects[i].bottom = 0;
}
result = CALL_ONE_PARAMETER_UPP( gOriginal_MenuSelect, upp_MenuSelectProcInfo, param1);
for ( i = 0; i < kMaxMenuRects; i++ )
{
gBlitInfo.theMenuRects[i].left = 0;
gBlitInfo.theMenuRects[i].top = 0;
gBlitInfo.theMenuRects[i].right = 0;
gBlitInfo.theMenuRects[i].bottom = 0;
}
gBlitInfo.theMenuIsDown = false;
return result;
}
pascal long my_PopupMenuSelectPatch(long param1, short param2, short param3, short param4)
{
long result;
int i;
gBlitInfo.theMenuIsDown = true;
for ( i = 0; i < kMaxMenuRects; i++ )
{
gBlitInfo.theMenuRects[i].left = 0;
gBlitInfo.theMenuRects[i].top = 0;
gBlitInfo.theMenuRects[i].right = 0;
gBlitInfo.theMenuRects[i].bottom = 0;
}
result = CALL_FOUR_PARAMETER_UPP( gOriginal_PopupMenuSelect, upp_PopupMenuSelectProcInfo, param1, param2, param3, param4);
for ( i = 0; i < kMaxMenuRects; i++ )
{
gBlitInfo.theMenuRects[i].left = 0;
gBlitInfo.theMenuRects[i].top = 0;
gBlitInfo.theMenuRects[i].right = 0;
gBlitInfo.theMenuRects[i].bottom = 0;
}
gBlitInfo.theMenuIsDown = false;
return result;
}
pascal void my_MoveWindowPatch(long param1, short param2, short param3, Boolean param4)
{
Boolean sameProcess = false;
ProcessSerialNumber currentPSN;
GetCurrentProcess( ¤tPSN );
SameProcess( ¤tPSN, &gBlitInfo.clientPSN, &sameProcess );
if ( sameProcess && gBlitInfo.VisRgnChangedCallback )
{
((VisRgnChangedCallbackProc)gBlitInfo.VisRgnChangedCallback)();
}
CALL_FOUR_PARAMETER_UPP( gOriginal_MoveWindow, upp_MoveWindowProcInfo, param1, param2, param3, param4);
}
pascal Boolean my_WaitNextEventPatch(short param1, long param2, long param3, long param4)
{
Boolean result;
BOOL bEventFilterAdjustedToSeeOSEvents = FALSE;
if (!(param1 & osMask))
{
bEventFilterAdjustedToSeeOSEvents = TRUE;
param1 |= osMask;
}
result = CALL_FOUR_PARAMETER_UPP( gOriginal_WaitNextEvent, upp_WaitNextEventProcInfo, param1, param2, param3, param4);
BOOL bProcessedOSEvt = FALSE;
{
EventRecord* event = (EventRecord*)param2;
if ( event->what == osEvt )
{
bProcessedOSEvt = TRUE;
if ( event->message & 0x01000000 ) // suspend/resume
{
if ( event->message & 0x00000001 ) // resume
{
gBlitInfo.thisApplicationIsFrontmost = true;
}
else
{
gBlitInfo.thisApplicationIsFrontmost = false;
}
}
if (bEventFilterAdjustedToSeeOSEvents)
{
// XXXbobclark: since they deliberately filtered out OS events, we won't
// give them any.
result = false;
event->what = nullEvent;
// XXXbobclark: I think that's the only field in the event record that I need to worry about.
}
}
if ( event->what == updateEvt || event->what == activateEvt )
{
gRecentUpdateEvent = true;
}
}
return result;
}
pascal void my_CloseWindowPatch(long param1)
{
if ( gBlitInfo.VisRgnChangedCallback )
{
((VisRgnChangedCallbackProc)gBlitInfo.VisRgnChangedCallback)();
}
CALL_ONE_PARAMETER_UPP( gOriginal_CloseWindow, upp_CloseWindowProcInfo, param1);
}
pascal void my_SelectWindowPatch(long param1)
{
if ( gBlitInfo.VisRgnChangedCallback )
{
((VisRgnChangedCallbackProc)gBlitInfo.VisRgnChangedCallback)();
}
CALL_ONE_PARAMETER_UPP( gOriginal_SelectWindow, upp_SelectWindowProcInfo, param1);
}
pascal void my_BringToFrontPatch(long param1)
{
if ( gBlitInfo.VisRgnChangedCallback )
{
((VisRgnChangedCallbackProc)gBlitInfo.VisRgnChangedCallback)();
}
CALL_ONE_PARAMETER_UPP( gOriginal_BringToFront, upp_BringToFrontProcInfo, param1);
}
pascal void my_SendBehindPatch(long param1, long param2)
{
if ( gBlitInfo.VisRgnChangedCallback )
{
((VisRgnChangedCallbackProc)gBlitInfo.VisRgnChangedCallback)();
}
CALL_TWO_PARAMETER_UPP( gOriginal_SendBehind, upp_SendBehindProcInfo, param1, param2);
}
pascal void my_PaintBehindPatch(long param1, long param2)
{
if ( gBlitInfo.VisRgnChangedCallback )
{
((VisRgnChangedCallbackProc)gBlitInfo.VisRgnChangedCallback)();
}
CALL_TWO_PARAMETER_UPP( gOriginal_PaintBehind, upp_PaintBehindProcInfo, param1, param2);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -