supermario/base/SuperMarioProj.1994-02-09/Toolbox/AppleEventMgr/AEHandlerTable.inc1.p
2019-06-29 23:17:50 +08:00

363 lines
13 KiB
OpenEdge ABL

{
File: AEHandlerTable.inc1.p
Contains: xxx put contents here xxx
Written by: xxx put writers here xxx
Copyright: © 1990 by Apple Computer, Inc., all rights reserved.
This file is used in these builds: BigBang
Change History (most recent first):
<3> 1/11/91 Lai Revert change 2 now that NewHashTable has been fixed
<2> 12/18/90 Lai Chagne initial size of hash table from 8 to 7 to get around bug
in NewHashTable
<1> 12/13/90 Lai first checked in
To Do:
}
{ Copyright © 1984-1990 by Apple Computer Inc. All rights reserved. }
{--------------------------------------------------------------------------------}
FUNCTION AE_InstallEventHandler(theAEEventClass: AEEventClass;
theAEEventID: AEEventID;
theHandler: ProcPtr;
handlerRefcon: LONGINT;
isSysHandler: Boolean): OSErr;
EXTERNAL;
FUNCTION AE_RemoveEventHandler(theAEEventClass: AEEventClass;
theAEEventID: AEEventID;
theHandler: ProcPtr;
isSysHandler: Boolean): OSErr;
EXTERNAL;
FUNCTION AE_InstallCoercionHandler(fromType: DescType;
toType: DescType;
theHandler: ProcPtr;
handlerRefcon: LONGINT;
fromTypeAsDesc: Boolean;
isSysHandler: Boolean): OSErr;
EXTERNAL;
FUNCTION AE_RemoveCoercionHandler(fromType: DescType;
toType: DescType;
theHandler: ProcPtr;
isSysHandler: Boolean): OSErr;
EXTERNAL;
FUNCTION AE_GetCoercionHandler(fromType: DescType;
toType: DescType;
VAR theHandler: ProcPtr;
VAR handlerRefcon: LONGINT;
VAR fromTypeAsDesc: Boolean;
isSysHandler: Boolean): OSErr;
EXTERNAL;
FUNCTION GetSpecialProcOffset(functionClass: AEKeyWord): LONGINT;
EXTERNAL;
{--------------------------------------------------------------------------------}
FUNCTION GetHashTable(isEventHandler: Boolean;
isSysHandler: Boolean;
VAR theHashTable: HHand): OSErr; FORWARD;
{--------------------------------------------------------------------------------}
{ add a handler to the table, it may either be event handler or coercion handler }
{ system wide or application specific, and use odd value for special handler }
FUNCTION AddToTable(key1, key2: OSType; { --> search keys }
theHandler: ProcPtr; { --> the handler }
handlerRefcon: LONGINT; { --> the refcon }
isSysHandler: Boolean; { --> system or application }
isSpecialHandler: Boolean; { --> type of handler }
isEventHandler: Boolean { --> eventhandler or coercion }
): OSErr;
VAR
offset: LONGINT;
err: OSErr;
theHashTable: HHand;
theHandlerRec: HandlerRec;
BEGIN
IF (theHandler = NIL) OR BTst(ord(theHandler), 0) THEN
err := paramErr
ELSE
BEGIN
WITH theHandlerRec DO
BEGIN
theRefCon := handlerRefcon;
theProc := theHandler;
IF isSpecialHandler THEN { special handler is mark as odd }
theProc := ProcPtr(ord(theProc) + 1);
END;
err := GetHashTable(isEventHandler, isSysHandler, theHashTable); { get the hash table }
IF (err = noErr) THEN
BEGIN
{ since on the stack it is refcon, theHandler, key2, key1 }
{ this means we should point to key as the key and refcon as the value }
{ this means that this goes into the table in key2 key 1 order }
err := ReplaceEntry(theHashTable, NIL, @key2, @theHandlerRec);
END;
END;
AddToTable := err;
END;
{--------------------------------------------------------------------------------}
FUNCTION AE_GetEventHandler(theAEEventClass: AEEventClass;
theAEEventID: AEEventID;
VAR theHandler: ProcPtr;
VAR handlerRefcon: LONGINT;
isSysHandler: Boolean): OSErr;
VAR
isSpecialHandler: Boolean;
BEGIN
{ just get it by calling GetEventHandler }
{ we can ignore the isSpecialHandler flag because we don't use it for now }
AE_GetEventHandler := GetEventHandler(theAEEventClass, theAEEventID, theHandler,
handlerRefcon, isSpecialHandler, isSysHandler, TRUE);
END;
{--------------------------------------------------------------------------------}
FUNCTION AE_GetSpecialHandler(functionClass: AEKeyWord;
VAR handler: ProcPtr;
isSysHandler: BOOLEAN): OSErr;
VAR
offset: LONGINT;
aGlobalRef: GlobalRecHandle;
BEGIN
handler := NIL;
offset := GetSpecialProcOffset(functionClass);
IF offset > 0 THEN
BEGIN
AE_GetSpecialHandler := MustHaveGlobal(isSysHandler, aGlobalRef);
IF aGlobalRef <> NIL THEN
handler := ProcPtr(LONGINTPtr(ord(aGlobalRef^) + offset)^);
END;
IF handler = NIL THEN
AE_GetSpecialHandler := errAENotASpecialFunction
ELSE
AE_GetSpecialHandler := noErr;
END;
{--------------------------------------------------------------------------------}
FUNCTION AE_InstallSpecialHandler(functionClass: AEKeyWord;
handler: ProcPtr;
isSysHandler: BOOLEAN): OSErr;
VAR
offset: LONGINT;
aGlobalRef: GlobalRecHandle;
aLongPtr: LONGINTPtr;
err: OSErr;
BEGIN
offset := GetSpecialProcOffset(functionClass); { get the offset }
IF offset > 0 THEN
BEGIN
{ must have global intialized before installing }
err := MustHaveGlobal(isSysHandler, aGlobalRef);
IF err = noErr THEN
BEGIN
IF (handler = NIL) OR BTst(ord(handler), 0) THEN
err := paramErr
ELSE
BEGIN
aLongPtr := LONGINTPtr(ord(aGlobalRef^) + offset);
aLongPtr^ := ord(handler);
END;
END;
END
ELSE
err := errAENotASpecialFunction;
AE_InstallSpecialHandler := err;
END;
{--------------------------------------------------------------------------------}
FUNCTION AE_RemoveSpecialHandler(functionClass: AEKeyWord;
handler: ProcPtr;
isSysHandler: BOOLEAN): OSErr;
VAR
offset: LONGINT;
aGlobalRef: GlobalRecHandle;
aLongPtr: LONGINTPtr;
BEGIN
offset := GetSpecialProcOffset(functionClass);
IF offset > 0 THEN
BEGIN
AE_RemoveSpecialHandler := MustHaveGlobal(isSysHandler, aGlobalRef);
IF aGlobalRef <> NIL THEN
BEGIN
aLongPtr := LONGINTPtr(ord(aGlobalRef^) + offset);
IF (aLongPtr^ = ord(handler)) OR (ord(handler) = 0) THEN aLongPtr^ := 0;
END;
END
ELSE
AE_RemoveSpecialHandler := errAENotASpecialFunction;
END;
{--------------------------------------------------------------------------------}
FUNCTION GetEventHandler(key1, key2: OSType; { --> key }
VAR theHandler: ProcPtr; { <-- return the procPtr }
VAR handlerRefcon: LONGINT; { <-- return the refcon }
VAR isSpecialHandler: Boolean; { <-- is it special handler ? }
isSysHandler: Boolean; { --> application or system ? }
isEventHandler: Boolean { --> event or coerecion ? }
): OSErr;
VAR
theHashTable: HHand;
theHandlerRec: HandlerRec;
BEGIN
GetEventHandler := errAEHandlerNotFound;
IF GetHashTable(isEventHandler, isSysHandler, theHashTable) = noErr THEN { get the hash
table }
BEGIN { no need to look unless global is initialized }
IF GetKeyValue(theHashTable, NIL, @key2, @theHandlerRec) = NoErr THEN
BEGIN
WITH theHandlerRec DO
BEGIN
theHandler := theProc;
handlerRefcon := theRefCon;
IF BTst(ord(theHandler), 0) THEN
BEGIN { odd means special handler }
theHandler := ProcPtr(ord(theHandler) - 1);
isSpecialHandler := TRUE;
END
ELSE
isSpecialHandler := FALSE;
GetEventHandler := noErr;
END;
END;
END;
END;
{--------------------------------------------------------------------------------}
{ get the particular hash table }
FUNCTION GetHashTable(isEventHandler: Boolean;
isSysHandler: Boolean;
VAR theHashTable: HHand): OSErr;
VAR
err: OSErr;
aGlobalRef: GlobalRecHandle;
BEGIN
err := MustHaveGlobal(isSysHandler, aGlobalRef); { get the global }
IF (err = noErr) THEN
BEGIN
WITH aGlobalRef^^ DO
BEGIN { get different table for different handler }
IF isEventHandler THEN
theHashTable := aeHashTable
ELSE
theHashTable := coercionHashTable;
END;
IF theHashTable = NIL THEN
BEGIN
err := NewHashTable(8, SizeOf(KeyRec), SizeOf(handlerRec), NIL, isSysHandler,
theHashTable);
IF err = noERR THEN
WITH aGlobalRef^^ DO { we must dereference again }
BEGIN
IF isEventHandler THEN
aeHashTable := theHashTable
ELSE
coercionHashTable := theHashTable;
END;
END;
END;
GetHashTable := err;
END;
{--------------------------------------------------------------------------------}
{ find the handler and refcon for the corresponding key, wildcard is used }
FUNCTION GetTableInfo(theTable: HHand; { --> handle to table }
key1, key2: OSType; { --> search these keys }
VAR theHandlerRec: HandlerRec { <-- return this ProcPtr record }
): BOOLEAN; { return true if found }
VAR
theKeyRec: KeyRec;
BEGIN
GetTableInfo := TRUE;
WITH theKeyRec DO
BEGIN
firstKey := key1;
secondKey := key2;
END;
IF GetKeyValue(theTable, NIL, @theKeyRec, @theHandlerRec) <> NoErr THEN
BEGIN
theKeyRec.firstKey := typeWildCard;
IF GetKeyValue(theTable, NIL, @theKeyRec, @theHandlerRec) <> NoErr THEN
BEGIN
WITH theKeyRec DO
BEGIN
firstKey := key1;
secondKey := typeWildCard;
END;
IF GetKeyValue(theTable, NIL, @theKeyRec, @theHandlerRec) <> NoErr THEN
BEGIN
theKeyRec.firstKey := typeWildCard;
IF GetKeyValue(theTable, NIL, @theKeyRec, @theHandlerRec) <> NoErr THEN
GetTableInfo := FALSE;
END;
END;
END;
END;
{--------------------------------------------------------------------------------}
{ remove an entry from the table }
FUNCTION RemoveFromTable(key1, key2: OSType;
theHandler: ProcPtr;
isSysHandler: Boolean;
isEventHandler: Boolean): OSErr;
VAR
curHandler: ProcPtr;
refcon: LONGINT;
dummy: Boolean;
err: OSErr;
theHashTable: HHand;
BEGIN
err := errAEHandlerNotFound;
IF GetHashTable(isEventHandler, isSysHandler, theHashTable) = noErr THEN { get the hash
table }
BEGIN { no need to look unless global is initialized }
err := GetEventHandler(key1, key2, curHandler, refcon, dummy, isSysHandler,
isEventHandler);
IF err = NoErr THEN
IF (curHandler = theHandler) OR (theHandler = NIL) THEN
err := RemoveKeyEntry(theHashTable, NIL, @key2);
END;
RemoveFromTable := err;
END;
{--------------------------------------------------------------------------------}