📄 bltpatch.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 ***** */
#if TARGET_CPU_68K && !TARGET_RT_MAC_CFM
#error Sorry Can't do that
#endif
#include <MixedMode.h>
#include <Appearance.h>
#include <SpeechSynthesis.h>
#include <Traps.h>
#include "macintosh.h"
#include "bltpatch.h"
//#include "../dcondev/dcon.h"
/*
xxxbobclark
Reasons for patches:
Blitting at interrupt time and avoiding menus accounts for the
following trap patches:
- CopyBits (to see where the menus are)
- MenuSelect (to see when the menu is down)
- PopupMenuSelect
Seeing when we switch out of the application accounts for the
following trap patch:
- WaitNextEvent (to watch for osEvt switching in/out)
Ensuring that the current visRgn is what we're using
for the visRgn -- ie, things where we wait for a system-time
call to update our version of the visRgn...
- MoveWindow
- CloseWindow
- SelectWindow
- PaintBehind (like when the app quits)
- BringToFront (deprecated because SelectWindow is better but
apparently the fine folks at Netscape didn't hear that.)
- SendBehind (also used by Netscape and apparently nobody else)
Note: I think that with the PaintBehind trap being patched, it
makes the CloseWindow patch redundant. At least until code
is added that blits over the last "XORed" part of the dragged
window frame.
Note: Menus popped up from the Control Strip are being blasted
over. ControlStripDispatch is a likely candidate to patch to
turn on the theMenuIsDown boolean, but I'm gonna
procrastinate on that.
*/
#ifdef _CARBON
BlittingPatchInfoStruct gBlitInfo;
bool gRecentUpdateEvent = false;
BOOL gInterruptBlitPatchesInstalled = FALSE;
pascal void PatchBlitSupport(void)
{
}
pascal void UnpatchBlitSupport( void )
{
}
#else
// enums for routinedescriptor
enum {
upp_CopyBitsProcInfo = kPascalStackBased
| STACK_ROUTINE_PARAMETER(1,kFourByteCode)
| STACK_ROUTINE_PARAMETER(2,kFourByteCode)
| STACK_ROUTINE_PARAMETER(3,kFourByteCode)
| STACK_ROUTINE_PARAMETER(4,kFourByteCode)
| STACK_ROUTINE_PARAMETER(5,kTwoByteCode)
| STACK_ROUTINE_PARAMETER(6,kFourByteCode),
upp_MenuSelectProcInfo = kPascalStackBased
| RESULT_SIZE(kFourByteCode)
| STACK_ROUTINE_PARAMETER(1,kFourByteCode),
upp_PopupMenuSelectProcInfo = kPascalStackBased
| RESULT_SIZE(kFourByteCode)
| STACK_ROUTINE_PARAMETER(1,kFourByteCode)
| STACK_ROUTINE_PARAMETER(2,kTwoByteCode)
| STACK_ROUTINE_PARAMETER(3,kTwoByteCode)
| STACK_ROUTINE_PARAMETER(4,kTwoByteCode),
upp_MoveWindowProcInfo = kPascalStackBased
| STACK_ROUTINE_PARAMETER(1,kFourByteCode)
| STACK_ROUTINE_PARAMETER(2,kTwoByteCode)
| STACK_ROUTINE_PARAMETER(3,kTwoByteCode)
| STACK_ROUTINE_PARAMETER(4,kOneByteCode),
upp_WaitNextEventProcInfo = kPascalStackBased
| RESULT_SIZE(kOneByteCode)
| STACK_ROUTINE_PARAMETER(1,kTwoByteCode)
| STACK_ROUTINE_PARAMETER(2,kFourByteCode)
| STACK_ROUTINE_PARAMETER(3,kFourByteCode)
| STACK_ROUTINE_PARAMETER(4,kFourByteCode),
upp_CloseWindowProcInfo = kPascalStackBased
| STACK_ROUTINE_PARAMETER(1,kFourByteCode),
upp_SelectWindowProcInfo = kPascalStackBased
| STACK_ROUTINE_PARAMETER(1,kFourByteCode),
upp_PaintBehindProcInfo = kPascalStackBased
| STACK_ROUTINE_PARAMETER(1,kFourByteCode)
| STACK_ROUTINE_PARAMETER(2,kFourByteCode),
upp_BringToFrontProcInfo = kPascalStackBased
| STACK_ROUTINE_PARAMETER(1,kFourByteCode),
upp_SendBehindProcInfo = kPascalStackBased
| STACK_ROUTINE_PARAMETER(1,kFourByteCode)
| STACK_ROUTINE_PARAMETER(2,kFourByteCode),
uppPatcExtraInfo
};
// Function Prototypes
extern pascal void my_CopyBitsPatch(long param1, long param2, long param3, long param4, short param5, long param6);
extern pascal long my_MenuSelectPatch(long param1);
extern pascal long my_PopupMenuSelectPatch(long param1, short param2, short param3, short param4);
extern pascal void my_MoveWindowPatch(long param1, short param2, short param3, Boolean param4);
extern pascal Boolean my_WaitNextEventPatch(short param1, long param2, long param3, long param4);
extern pascal void my_CloseWindowPatch(long param1);
extern pascal void my_SelectWindowPatch(long param1);
extern pascal void my_PaintBehindPatch(long param1, long param2);
extern pascal void my_BringToFrontPatch(long param1);
extern pascal void my_SendBehindPatch(long param1, long param2);
// Globals to hold original routine descriptors
RoutineDescriptorPtr gOriginal_CopyBits = nil;
RoutineDescriptorPtr gOriginal_MenuSelect = nil;
RoutineDescriptorPtr gOriginal_PopupMenuSelect = nil;
RoutineDescriptorPtr gOriginal_MoveWindow = nil;
RoutineDescriptorPtr gOriginal_WaitNextEvent = nil;
RoutineDescriptorPtr gOriginal_CloseWindow = nil;
RoutineDescriptorPtr gOriginal_SelectWindow = nil;
RoutineDescriptorPtr gOriginal_PaintBehind = nil;
RoutineDescriptorPtr gOriginal_BringToFront = nil;
RoutineDescriptorPtr gOriginal_SendBehind = nil;
#define kMaxMenuRects 20
typedef pascal void (*MenuCallbackProc)( Rect* theRectToRestore );
typedef pascal void (*VisRgnChangedCallbackProc)(void);
BlittingPatchInfoStruct gBlitInfo;
bool gRecentUpdateEvent = false;
BOOL gInterruptBlitPatchesInstalled = FALSE;
// Tell MetroWerks the procInfo for main
ProcInfoType __procinfo = kPascalStackBased;
pascal void PatchBlitSupport(void)
{
RoutineDescriptorPtr originaldesc, newdesc, unImplimentedTrapAddr;
UInt32 size;
UInt16 index;
THz theZone;
int i;
// detach ourselves
//DetachResource(Get1Resource('INIT', 0)); Are we *trying* to crash?
// if the gestalt selector is installed and
// the interruptblit bit (low bit) is clear, bail
SInt32 gestResult;
const OSType kHXCoreGestaltSelector = 'RNc\0';
const UINT32 kInterruptBlitBit = 0; // if lowest bit set, we blit at interrupt time
if (Gestalt(kHXCoreGestaltSelector, &gestResult) == noErr
&& (gestResult & (1L << kInterruptBlitBit)) == 0)
{
gInterruptBlitPatchesInstalled = FALSE;
// DebugStr("\p Bypassing patch installation");
return;
}
gInterruptBlitPatchesInstalled = TRUE;
// make sure we are in the system heap
theZone = GetZone();
SetZone(SystemZone());
unImplimentedTrapAddr = NGetTrapAddress(_Unimplemented, (_Unimplemented & 0x0800) ? ToolTrap : OSTrap);
originaldesc = NGetTrapAddress(_CopyBits, (_CopyBits & 0x0800) ? ToolTrap : OSTrap);
if (originaldesc != unImplimentedTrapAddr) {
if (originaldesc->goMixedModeTrap != _MixedModeMagic) {
// Trap is 68K
size = sizeof(RoutineDescriptor) + (sizeof(RoutineRecord) * 0);
// allocate new descriptor
newdesc = (RoutineDescriptorPtr) NewPtrSys(size);
if (!newdesc) {
return;
}
// set fields of routine decscriptor
newdesc->goMixedModeTrap = _MixedModeMagic;
newdesc->version = 7;
newdesc->routineDescriptorFlags = 0;
newdesc->reserved1 = 0;
newdesc->reserved2 = 0;
newdesc->selectorInfo = 0;
newdesc->routineCount = 0;
index = 0;
gOriginal_CopyBits = originaldesc;
newdesc->routineRecords[index].procInfo = upp_CopyBitsProcInfo;
newdesc->routineRecords[index].reserved1 = 0;
newdesc->routineRecords[index].ISA = GetCurrentArchitecture();
newdesc->routineRecords[index].routineFlags = 4;
newdesc->routineRecords[index].procDescriptor = (ProcPtr)my_CopyBitsPatch;
newdesc->routineRecords[index].reserved2 = 0;
newdesc->routineRecords[index].selector = 0;
}
else {
// Trap is PPC
size = sizeof(RoutineDescriptor) + (sizeof(RoutineRecord) * originaldesc->routineCount);
newdesc = (RoutineDescriptorPtr) NewPtrSys(size);
if (!newdesc) {
return;
}
BlockMoveData(originaldesc, newdesc, size);
gOriginal_CopyBits = originaldesc;
index = 0;
newdesc->routineRecords[index].procDescriptor = (ProcPtr)my_CopyBitsPatch;
newdesc->routineRecords[index].ISA = GetCurrentArchitecture();
}
NSetTrapAddress((UniversalProcPtr) newdesc, _CopyBits, (_CopyBits & 0x0800) ? ToolTrap : OSTrap);
}
originaldesc = NGetTrapAddress(_MenuSelect, (_MenuSelect & 0x0800) ? ToolTrap : OSTrap);
if (originaldesc != unImplimentedTrapAddr) {
if (originaldesc->goMixedModeTrap != _MixedModeMagic) {
// Trap is 68K
size = sizeof(RoutineDescriptor) + (sizeof(RoutineRecord) * 0);
// allocate new descriptor
newdesc = (RoutineDescriptorPtr) NewPtrSys(size);
if (!newdesc) {
return;
}
// set fields of routine decscriptor
newdesc->goMixedModeTrap = _MixedModeMagic;
newdesc->version = 7;
newdesc->routineDescriptorFlags = 0;
newdesc->reserved1 = 0;
newdesc->reserved2 = 0;
newdesc->selectorInfo = 0;
newdesc->routineCount = 0;
index = 0;
gOriginal_MenuSelect = originaldesc;
newdesc->routineRecords[index].procInfo = upp_MenuSelectProcInfo;
newdesc->routineRecords[index].reserved1 = 0;
newdesc->routineRecords[index].ISA = GetCurrentArchitecture();
newdesc->routineRecords[index].routineFlags = 4;
newdesc->routineRecords[index].procDescriptor = (ProcPtr)my_MenuSelectPatch;
newdesc->routineRecords[index].reserved2 = 0;
newdesc->routineRecords[index].selector = 0;
}
else {
// Trap is PPC
size = sizeof(RoutineDescriptor) + (sizeof(RoutineRecord) * originaldesc->routineCount);
newdesc = (RoutineDescriptorPtr) NewPtrSys(size);
if (!newdesc) {
return;
}
BlockMoveData(originaldesc, newdesc, size);
gOriginal_MenuSelect = originaldesc;
index = 0;
newdesc->routineRecords[index].procDescriptor = (ProcPtr)my_MenuSelectPatch;
newdesc->routineRecords[index].ISA = GetCurrentArchitecture();
}
NSetTrapAddress((UniversalProcPtr) newdesc, _MenuSelect, (_MenuSelect & 0x0800) ? ToolTrap : OSTrap);
}
originaldesc = NGetTrapAddress(_PopUpMenuSelect, (_PopUpMenuSelect & 0x0800) ? ToolTrap : OSTrap);
if (originaldesc != unImplimentedTrapAddr) {
if (originaldesc->goMixedModeTrap != _MixedModeMagic) {
// Trap is 68K
size = sizeof(RoutineDescriptor) + (sizeof(RoutineRecord) * 0);
// allocate new descriptor
newdesc = (RoutineDescriptorPtr) NewPtrSys(size);
if (!newdesc) {
return;
}
// set fields of routine decscriptor
newdesc->goMixedModeTrap = _MixedModeMagic;
newdesc->version = 7;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -