home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
200-299
/
ff253.lzh
/
KeyMac
/
KeyMac.mod
< prev
next >
Wrap
Text File
|
1989-10-19
|
10KB
|
358 lines
(*---------------------------------------------------------------------------
:Program. KeyMac
:Author. Fridtjof Björn Siebert
:Address. Nobileweg 67, D-7-Stgt-40
:Shortcut. [fbs]
:Version. 0.1
:Date. 17-May-89
:Copyright. PD
:Language. MODULA-II
:Translator. M2Amiga v3.2d
:History. This is based on RecordInput [fbs] of AMOK#3.
:Usage. KeyMac [MacKey [saAc] [PlayKey [saAc]]
:Contents. Program to create Keyboard macros. You can specify a
:Contents. Macro Key (default alt+HELP). To create a macro just press this
:Contents. key and start typing your macro. Then press the macro key again
:Contents. to finish your macro. Now you can play the macro by pressing
:Contents. the Play Key (default HELP).
---------------------------------------------------------------------------*)
MODULE KeyMac;
FROM SYSTEM IMPORT ADR, ADDRESS, LONGSET;
FROM Arts IMPORT Assert, TermProcedure, Terminate;
FROM Arguments IMPORT NumArgs, GetArg;
FROM Exec IMPORT MsgPortPtr, Interrupt, Forbid, Permit, IOStdReqPtr,
OpenDevice, CloseDevice, DoIO, IORequest, FindPort,
DevicePtr,IOFlagSet, WaitPort, GetMsg, ReplyMsg,
MessagePtr, Wait, FindTask, AllocSignal, NodeType,
FreeSignal, Signal, TaskPtr, Message, PutMsg;
FROM ExecSupport IMPORT CreatePort, DeletePort, CreateStdIO, DeleteStdIO;
FROM Input IMPORT inputName, addHandler, remHandler, writeEvent;
FROM InputEvent IMPORT InputEventPtr, Class, QualifierSet;
FROM Intuition IMPORT DisplayBeep;
IMPORT InputEvent;
(*------------------------- Variablen: ----------------------------------*)
CONST
oom = "Out of Memory!";
usage = "KeyMac [Mac [saAc] [Play [saAc]]";
PortName = "KeyMac.Port";
ReplyName = "KeyMac.ReplyPort";
err = MAX(CARDINAL);
MaxRecords = 100;
CopyRight = "© 1989 by Fridtjof Siebert / AMOK";
TYPE
KeyQualis = (shift,alt,ctrl,amiga);
KeyQualiSet = SET OF KeyQualis;
VAR
InputDevPort: MsgPortPtr;
InputRequestBlock: IOStdReqPtr;
HandlerStuff: Interrupt;
HandlerActive,InputOpen: BOOLEAN;
PuffEvent,SendEvent: InputEvent.InputEvent;
count: INTEGER;
MacKey, PlayKey: CARDINAL;
MacQual, PlayQual: KeyQualiSet;
MySig: INTEGER;
SigSet: LONGSET;
Me: TaskPtr;
Argument: ARRAY[0..79] OF CHAR;
State: (wait,waitrel,record,recordrel,play);
Records: ARRAY[0..MaxRecords-1] OF RECORD key: CARDINAL; qual: QualifierSet END;
TraceEv: InputEventPtr;
Size: INTEGER;
l: INTEGER;
args: INTEGER;
MyMsg: Message;
QuitMessage: MessagePtr;
MyPort, OldPort: MsgPortPtr;
(*--------------------- Check Qualifier: --------------------------------*)
PROCEDURE CheckQuali(Quali: QualifierSet; Qual: KeyQualiSet): BOOLEAN;
(* this checks the specified Keys in Qual (SHIFT,ALT,CTRL,AMIGA) whether *)
(* they are in Quali (left or right is unimportent) or not. *)
BEGIN
RETURN ((shift IN Qual) = ((InputEvent.lShift IN Quali) OR (InputEvent.rShift IN Quali)))
AND ((alt IN Qual) = ((InputEvent.lAlt IN Quali) OR (InputEvent.rAlt IN Quali)))
AND ((amiga IN Qual) = ((InputEvent.lCommand IN Quali) OR (InputEvent.rCommand IN Quali)))
AND ((ctrl IN Qual) = (InputEvent.control IN Quali));
END CheckQuali;
(*-------------------- Initialize Input.device: -------------------------*)
PROCEDURE OpenInput();
BEGIN
InputDevPort := CreatePort(NIL,0);
Assert(InputDevPort#NIL,ADR(oom));
InputRequestBlock := CreateStdIO(InputDevPort);
Assert(InputRequestBlock#NIL,ADR(oom));
WITH HandlerStuff DO
data := NIL;
node.pri := 51;
END;
OpenDevice(ADR(inputName),0,InputRequestBlock,LONGSET{});
Assert(InputRequestBlock^.error=0,ADR("Can't open InputDevice!"));
InputOpen := TRUE;
END OpenInput;
(*--------------------- Close Input-Device: -----------------------------*)
PROCEDURE CloseInput();
BEGIN
IF InputOpen THEN CloseDevice(InputRequestBlock) END;
IF InputDevPort#NIL THEN DeletePort(InputDevPort) END;
IF InputRequestBlock#NIL THEN DeleteStdIO(InputRequestBlock) END;
END CloseInput;
(*--------------------------- AddHandler: -------------------------------*)
PROCEDURE AddHandler(Handler: ADDRESS);
BEGIN
HandlerStuff.code := Handler;
WITH InputRequestBlock^ DO
command := addHandler;
data := ADR(HandlerStuff);
END;
DoIO(InputRequestBlock);
END AddHandler;
(*--------------------------- RemHandler: -------------------------------*)
PROCEDURE RemHandler();
BEGIN
WITH InputRequestBlock^ DO
command := remHandler;
data := ADR(HandlerStuff);
END;
DoIO(InputRequestBlock);
END RemHandler;
(*------------------------ Write InputEvent: ----------------------------*)
PROCEDURE WriteEvent(Event: InputEventPtr);
BEGIN
WITH InputRequestBlock^ DO
command := writeEvent;
flags := IOFlagSet{};
length := SIZE(InputEvent.InputEvent);
data := Event;
END;
DoIO(InputRequestBlock);
END WriteEvent;
(*------------------------ InputHandler: --------------------------------*)
PROCEDURE RecordHandler(Ev{8}: InputEventPtr): InputEventPtr; (* $S- *)
BEGIN
TraceEv := Ev;
WHILE TraceEv#NIL DO
WITH TraceEv^ DO
IF class=rawkey THEN
IF (code=MacKey) AND CheckQuali(qualifier,MacQual) OR
(code=PlayKey) AND CheckQuali(qualifier,PlayQual) THEN
class := null
END;
CASE State OF
waitrel:
IF (code=MacKey+80H) THEN
State := wait; class := null;
END |
wait:
IF (code=MacKey) AND CheckQuali(qualifier,MacQual) THEN
State := recordrel;
ELSIF (code=PlayKey) AND CheckQuali(qualifier,PlayQual) THEN
State := play;
PuffEvent := TraceEv^;
Signal(Me,SigSet);
END |
recordrel:
IF (code=MacKey+80H) AND CheckQuali(qualifier,MacQual) THEN
State := record; Size := 0; class := null;
Signal(Me,SigSet);
END |
record:
Signal(Me,SigSet);
IF (code=MacKey) AND CheckQuali(qualifier,MacQual) THEN
State := waitrel;
Signal(Me,SigSet);
ELSIF Size<MaxRecords THEN
Records[Size].key := code;
Records[Size].qual := qualifier;
INC(Size);
END |
play:
IF (code=PlayKey) AND CheckQuali(qualifier,PlayQual) THEN
PuffEvent := TraceEv^;
Signal(Me,SigSet);
ELSIF (code=PlayKey+80H) THEN
class := null;
State := wait;
END |
END;
END;
END;
TraceEv := TraceEv^.nextEvent;
END;
RETURN Ev;
END RecordHandler; (* $S+ *)
(*-------------------------------------------------------------------------*)
PROCEDURE GetQuali(VAR q: KeyQualiSet);
VAR i: INTEGER;
BEGIN
i := 0; q := KeyQualiSet{};
LOOP
CASE Argument[i] OF
0C: EXIT |
"s": INCL(q,shift) |
"a": INCL(q,alt) |
"A": INCL(q,amiga) |
"c": INCL(q,ctrl) |
ELSE Assert(FALSE,ADR(usage)) END;
INC(i);
END;
END GetQuali;
PROCEDURE StrToCard(s: ARRAY OF CHAR): CARDINAL;
VAR i,j: CARDINAL;
BEGIN
i := 0; j := 0;
LOOP
CASE s[j] OF
0C: RETURN i |
"0".."9": i := 10*i+CARDINAL(s[j])-CARDINAL("0") |
ELSE RETURN err END;
INC(j);
END;
END StrToCard;
(*------------------------- TermProcedure: ------------------------------*)
PROCEDURE CleanUp();
BEGIN
IF HandlerActive THEN RemHandler() END;
CloseInput();
IF MySig#-1 THEN FreeSignal(MySig) END;
IF MyPort#NIL THEN
Forbid();
IF QuitMessage=NIL THEN QuitMessage := GetMsg(MyPort) END;
WHILE QuitMessage#NIL DO
ReplyMsg(QuitMessage);
QuitMessage := GetMsg(MyPort);
END;
DeletePort(MyPort);
Permit();
END;
END CleanUp;
(*------------------------ Intialisation: -------------------------------*)
BEGIN
HandlerActive := FALSE; InputOpen := FALSE; MySig := -1; Size := 0;
InputDevPort := NIL; InputRequestBlock := NIL; State := wait; MyPort := NIL;
TermProcedure(CleanUp);
MacKey := 5FH; MacQual := KeyQualiSet{alt};
PlayKey:= 5FH; PlayQual:= KeyQualiSet{};
(*------ Have we already been started? ------*)
OldPort := FindPort(ADR(PortName));
IF OldPort#NIL THEN
MyPort := CreatePort(ADR(ReplyName),0);
Assert(MyPort#NIL,ADR(oom));
MyMsg.node.type := message;
MyMsg.replyPort := MyPort;
PutMsg(OldPort,ADR(MyMsg));
WaitPort(MyPort);
DeletePort(MyPort);
MyPort := NIL;
Terminate(0);
END;
MyPort := CreatePort(ADR(PortName),0);
Assert(MyPort#NIL,ADR(oom));
(*------ Open everything we need: ------*)
OpenInput();
AddHandler(ADR(RecordHandler));
HandlerActive := TRUE;
Me := FindTask(NIL);
MySig := AllocSignal(-1);
Assert(MySig#-1,ADR("No more Signals!"));
SigSet := LONGSET{MySig};
(*------ Arguments: ------*)
count := 1;
args := NumArgs();
IF 0<args THEN
GetArg(1,Argument,l);
MacKey := StrToCard(Argument);
Assert(MacKey#err,ADR(usage));
MacQual := KeyQualiSet{};
INC(count);
IF 1<args THEN
GetArg(2,Argument,l);
IF StrToCard(Argument)=err THEN
GetQuali(MacQual);
INC(count);
END;
IF count<=args THEN
GetArg(count,Argument,l);
PlayKey := StrToCard(Argument);
Assert(PlayKey#err,ADR(usage));
PlayQual := KeyQualiSet{};
INC(count);
IF count<=args THEN
GetArg(count,Argument,l);
GetQuali(PlayQual);
END;
END;
END;
END;
(*------ Main Loop: ------*)
LOOP
IF MyPort^.sigBit IN Wait(LONGSET{MyPort^.sigBit,MySig}) THEN
EXIT
ELSE
CASE State OF
play,wait:
count := 0;
Forbid(); SendEvent := PuffEvent; Permit();
SendEvent.class := rawkey;
SendEvent.nextEvent := NIL;
WHILE count<Size DO
SendEvent.code := Records[count].key;
SendEvent.qualifier := Records[count].qual;
WriteEvent(ADR(SendEvent));
INC(count);
END |
record,waitrel:
DisplayBeep(NIL) |
ELSE END;
END;
END;
END KeyMac.