(******************************************************************************
*                                                                             *
*    Programmname:  InputHandler                                              *
*                                                                             *
*    Stand:         29.12.89                            Uhrzeit:  18:03:20    *
*                                                                             *
*    Bearbeitet mit dem MODULETool V1.12        (©) by  Thomas Stolze 1989    *
*                                                                             *
******************************************************************************)

(* $R- *) (* $V- *) (* $S- *) (* $N- *) (* $F- *)
IMPLEMENTATION MODULE InputHandler;

IMPORT Exec;

FROM Arts        IMPORT Assert;
FROM Exec        IMPORT CloseDevice,Disable,DoIO,Enable,Forbid,IOStdReq,
                        MsgPortPtr,OpenDevice,Permit,PutMsg;
FROM ExecSupport IMPORT CreateExtIO,CreatePort,DeleteExtIO,DeletePort;
FROM Input       IMPORT addHandler,inputName,remHandler;
FROM InputEvent  IMPORT InputEvent,InputEventPtr,Qualifiers;
FROM Intuition   IMPORT ActivateWindow,DisplayBeep,IDCMPFlags,IDCMPFlagSet,
                        IntuiMessage;
FROM SYSTEM      IMPORT ADDRESS,ADR,CAST,LONGSET,REG,SETREG;
FROM m2Maker     IMPORT F1,F5,window;

CONST space = 40H;

VAR readPortPtr : MsgPortPtr;

PROCEDURE Handler;
VAR  a0,a1    : ADDRESS;
     eventptr : InputEventPtr;
BEGIN
 a0:=REG(8); a1:=REG(9);

 eventptr:=CAST(InputEventPtr,a0);
 IF (control IN eventptr^.qualifier) AND (lShift IN eventptr^.qualifier) THEN
    IF ((eventptr^.code >= F1) AND (eventptr^.code <= F5)) OR
                                      (eventptr^.code = space) THEN
       inMessage.event.code:=eventptr^.code;
       inMessage.event.class:=IDCMPFlagSet{rawKey};
       inMessage.event.qualifier:=eventptr^.qualifier;
       inMessage.event.iAddress:=NIL;
       inMessage.event.seconds:=eventptr^.timeStamp.secs;
       inMessage.event.micros:=eventptr^.timeStamp.micro;
       inMessage.event.idcmpWindow:=window;
       inMessage.event.specialLink:=NIL;

       inMessage.nachricht.node.type:=Exec.message;
       inMessage.nachricht.length:=SIZE(IntuiMessage);

       a0:=NIL;
         ActivateWindow(window); DisplayBeep(NIL);
         PutMsg(window^.userPort,ADR(inMessage));
    END;
 END;

 SETREG(8,a0); SETREG(9,a1);
END Handler;

PROCEDURE InstallHandler(adrdata : ADDRESS);
BEGIN
  interrupted.data:=adrdata;
  interrupted.code:=ADR(Handler);
  interrupted.node.pri:=52;

  readIOPtr^.data:=ADR(interrupted);
  readIOPtr^.command:=addHandler;
  readIOPtr^.length:=SIZE(InputEvent);

  DoIO(readIOPtr);
    Assert(readIOPtr^.error = 0,ADR("I/O Fehler"));

END InstallHandler;

PROCEDURE InputRead(command : CARDINAL; len : LONGCARD; adr : ADDRESS);
BEGIN
  readIOPtr^.command:=command;
  readIOPtr^.length:=len;
  readIOPtr^.data:=adr;
  DoIO(readIOPtr);
    Assert(readIOPtr^.error = 0,ADR("I/O Fehler"));
END InputRead;

PROCEDURE Wache;
VAR event    : InputEvent;
    code     : CARDINAL;
    inputmsg : inputMessagePtr;
    erfolg   : BOOLEAN;
BEGIN
  readPortPtr:=CreatePort(NIL,0);
    Assert(readPortPtr # NIL,ADR("MsgPort nicht allokiert"));
  readIOPtr:=CreateExtIO(readPortPtr,SIZE(IOStdReq));
    Assert(readIOPtr # NIL,ADR("IOStdReq nicht allokiert"));

  OpenDevice(ADR(inputName),0,readIOPtr,LONGSET{});

  InstallHandler(NIL);

END Wache;

PROCEDURE CleanupHandler;
BEGIN
 Forbid(); Disable();

  IF (interrupted.code # NIL) THEN
     InputRead(remHandler,0,ADR(interrupted));
     interrupted.code:=NIL;
     CloseDevice(readIOPtr);
  END;
  IF (readIOPtr # NIL) THEN
     DeleteExtIO(readIOPtr); readIOPtr:=NIL;
  END;
  IF (readPortPtr # NIL) THEN
     DeletePort(readPortPtr); readPortPtr:=NIL;
  END;

 Permit(); Enable();
END CleanupHandler;

BEGIN
END InputHandler.

