зеркало из https://github.com/mozilla/gecko-dev.git
added Jump instruction for safe removal. this is a dead-end, because update events can't be gotten reliably.
This commit is contained in:
Родитель
7684bc079c
Коммит
3ea5b551a6
|
@ -27,41 +27,106 @@
|
||||||
#include "jGNE.h"
|
#include "jGNE.h"
|
||||||
|
|
||||||
#include <MixedMode.h>
|
#include <MixedMode.h>
|
||||||
|
#include <Memory.h>
|
||||||
#include <LowMem.h>
|
#include <LowMem.h>
|
||||||
|
#include <TextUtils.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A 68K jump vector.
|
||||||
|
*/
|
||||||
|
#pragma options align=mac68k
|
||||||
|
|
||||||
|
struct Jump {
|
||||||
|
unsigned short jmp;
|
||||||
|
UniversalProcPtr addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma options align=reset
|
||||||
|
|
||||||
static void GNEFilter(EventRecord *event, Boolean* result);
|
static void GNEFilter(EventRecord *event, Boolean* result);
|
||||||
|
|
||||||
static RoutineDescriptor theGNEFilterUPP = BUILD_ROUTINE_DESCRIPTOR(uppGetNextEventFilterProcInfo, GNEFilter);
|
static RoutineDescriptor theGNEFilterDescriptor = BUILD_ROUTINE_DESCRIPTOR(uppGetNextEventFilterProcInfo, GNEFilter);
|
||||||
static GetNextEventFilterUPP theGetNextEventFilterUPP = NULL;
|
static Jump* theGNEFilterJump;
|
||||||
|
static GetNextEventFilterUPP theOldGNEFilterUPP = NULL;
|
||||||
static EventFilterProcPtr theEventFilter = NULL;
|
static EventFilterProcPtr theEventFilter = NULL;
|
||||||
|
|
||||||
|
static Str63 theAppName;
|
||||||
|
|
||||||
OSStatus InstallEventFilter(EventFilterProcPtr filter)
|
OSStatus InstallEventFilter(EventFilterProcPtr filter)
|
||||||
{
|
{
|
||||||
theEventFilter = filter;
|
if (theEventFilter == NULL) {
|
||||||
|
theEventFilter = filter;
|
||||||
|
|
||||||
// get previous event filter routine.
|
// record the current application's name.
|
||||||
theGetNextEventFilterUPP = LMGetGNEFilter();
|
StringPtr currentAppName = LMGetCurApName();
|
||||||
LMSetGNEFilter(&theGNEFilterUPP);
|
::BlockMoveData(currentAppName, theAppName, 1 + currentAppName[0]);
|
||||||
|
|
||||||
return noErr;
|
// allocate a jump vector in the System heap, so it will be retained after termination.
|
||||||
|
if (theGNEFilterJump == NULL) {
|
||||||
|
theGNEFilterJump = (Jump*) NewPtrSys(sizeof(Jump));
|
||||||
|
if (theGNEFilterJump == NULL)
|
||||||
|
return MemError();
|
||||||
|
|
||||||
|
theGNEFilterJump->jmp = 0x4EF9;
|
||||||
|
theGNEFilterJump->addr = &theGNEFilterDescriptor;
|
||||||
|
|
||||||
|
// get previous event filter routine.
|
||||||
|
theOldGNEFilterUPP = LMGetGNEFilter();
|
||||||
|
LMSetGNEFilter(GetNextEventFilterUPP(theGNEFilterJump));
|
||||||
|
} else {
|
||||||
|
// our previously allocated Jump is still installed, use it.
|
||||||
|
theOldGNEFilterUPP = theGNEFilterJump->addr;
|
||||||
|
theGNEFilterJump->addr = &theGNEFilterDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
return noErr;
|
||||||
|
}
|
||||||
|
return paramErr;
|
||||||
}
|
}
|
||||||
|
|
||||||
OSStatus RemoveEventFilter()
|
OSStatus RemoveEventFilter()
|
||||||
{
|
{
|
||||||
// should really check to see if somebody else has installed a filter proc as well.
|
if (theEventFilter != NULL) {
|
||||||
LMSetGNEFilter(theGetNextEventFilterUPP);
|
// It's only truly safe to remove our filter, if nobody else installed one after us.
|
||||||
theGetNextEventFilterUPP = NULL;
|
if (LMGetGNEFilter() == GetNextEventFilterUPP(theGNEFilterJump)) {
|
||||||
theEventFilter = NULL;
|
// can safely restore the old filter.
|
||||||
return noErr;
|
LMSetGNEFilter(theOldGNEFilterUPP);
|
||||||
|
DisposePtr(Ptr(theGNEFilterJump));
|
||||||
|
theGNEFilterJump = NULL;
|
||||||
|
} else {
|
||||||
|
// modify the jump instruction to point to the previous filter.
|
||||||
|
theGNEFilterJump->addr = theOldGNEFilterUPP;
|
||||||
|
}
|
||||||
|
theOldGNEFilterUPP = NULL;
|
||||||
|
theEventFilter = NULL;
|
||||||
|
return noErr;
|
||||||
|
}
|
||||||
|
return paramErr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GNEFilter(EventRecord *event, Boolean* result)
|
static void GNEFilter(EventRecord *event, Boolean* result)
|
||||||
{
|
{
|
||||||
// call next filter in chain first.
|
// call next filter in chain first.
|
||||||
if (theGetNextEventFilterUPP)
|
if (theOldGNEFilterUPP != NULL)
|
||||||
CallGetNextEventFilterProc(theGetNextEventFilterUPP, event, result);
|
CallGetNextEventFilterProc(theOldGNEFilterUPP, event, result);
|
||||||
|
|
||||||
// now, let the filter proc have a crack at the event.
|
// now, let the filter proc have a crack at the event.
|
||||||
if (*result)
|
if (*result) {
|
||||||
*result = !theEventFilter(event);
|
// only call the filter if called in the current application's context.
|
||||||
|
/* if (::EqualString(theAppName, LMGetCurApName(), true, true)) */
|
||||||
|
{
|
||||||
|
// prevent recursive calls to the filter.
|
||||||
|
static Boolean inFilter = false;
|
||||||
|
if (! inFilter) {
|
||||||
|
inFilter = true;
|
||||||
|
Boolean filteredEvent = theEventFilter(event);
|
||||||
|
if (filteredEvent) {
|
||||||
|
// consume the event by making it a nullEvent.
|
||||||
|
event->what = nullEvent;
|
||||||
|
*result = false;
|
||||||
|
}
|
||||||
|
inFilter = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче