home *** CD-ROM | disk | FTP | other *** search
- (*---------------------------------------------------------------------------
- :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.
-