(*-------------------------------------------------------------------------*)
(*                                                                         *)
(*  Amiga Oberon Library Module: Mouse                Date: 02-Nov-92      *)
(*                                                                         *)
(*   © 1991 by Fridtjof Siebert                                            *)
(*                                                                         *)
(*-------------------------------------------------------------------------*)

MODULE Mouse;

IMPORT es  := ExecSupport,
       e   := Exec,
       ie  := InputEvent,
       in  := Input,
       ol  := OberonLib,
       sys := SYSTEM;

(*------  which Mousebutton is selected:  ------*)

VAR
  leftButton  - : BOOLEAN;
  rightButton - : BOOLEAN;
  midButton   - : BOOLEAN;

(*------  internal stuff:  ------*)

  IDevPort: e.MsgPortPtr;
  IReqBlock: e.IOStdReqPtr;
  HandlerStuff: e.Interrupt;
  HandlerActive,InputOpen: BOOLEAN;
  Me: e.TaskPtr;
  MySig: LONGINT;
  waitLeft,waitRight: BOOLEAN;


(*------  Wait for Left Button:  ------*)


PROCEDURE WaitLMB*;
BEGIN
  waitLeft := TRUE;
  REPEAT UNTIL MySig IN e.Wait(LONGSET{MySig});
END WaitLMB;


(*------  Wait for Right Button:  ------*)


PROCEDURE WaitRMB*;
BEGIN
  waitRight := TRUE;
  REPEAT UNTIL MySig IN e.Wait(LONGSET{MySig});
END WaitRMB;


(*-------------------------------------------------------------------------*)


PROCEDURE * Handler(); (* $StackChk- $SaveRegs+ *)

VAR Ev,ev: ie.InputEventPtr;

BEGIN
  sys.SETREG(13,sys.REG(9));   (* Varbase *)
  Ev := sys.REG(8);
  ev := Ev;
  WHILE ev#NIL DO
    IF ev.class=ie.rawmouse THEN
      midButton   := ie.  midButton IN ev.qualifier;
      leftButton  := ie. leftButton IN ev.qualifier;
      rightButton := ie.rightButton IN ev.qualifier;
      IF waitLeft  & leftButton  THEN waitLeft  := FALSE; e.Signal(Me,LONGSET{MySig}) END;
      IF waitRight & rightButton THEN waitRight := FALSE; e.Signal(Me,LONGSET{MySig}) END;
    END;
    ev := ev.nextEvent;
  END;
  sys.SETREG(0,Ev);
END Handler; (* $StackChk= *)


BEGIN

  MySig := -1;
  Me := sys.VAL(e.TaskPtr,ol.Me);

(*------  Open everything we need:  ------*)

  MySig     := e.AllocSignal(-1);        IF MySig<0       THEN HALT(20) END;
  IDevPort  := es.CreatePort("",0);      IF IDevPort=NIL  THEN HALT(20) END;
  IReqBlock := es.CreateStdIO(IDevPort); IF IReqBlock=NIL THEN HALT(20) END;
  IF e.OpenDevice("input.device",0,IReqBlock,LONGSET{})#0 THEN HALT(20) END;
  InputOpen := TRUE;

  HandlerStuff.data     := sys.REG(13);  (* Varbase *)
  HandlerStuff.node.pri := 51;
  HandlerStuff.code     := Handler;
  IReqBlock.command := in.addHandler;
  IReqBlock.data    := sys.ADR(HandlerStuff);
  IF e.DoIO(IReqBlock)=0 THEN END;

  HandlerActive := TRUE;

CLOSE

  IF HandlerActive         THEN
    IReqBlock.command := in.remHandler;
    IReqBlock.data := sys.ADR(HandlerStuff);
    IF e.DoIO(IReqBlock)=0 THEN END;
  END;
  IF InputOpen     THEN e.CloseDevice (IReqBlock) END;
  IF IDevPort#NIL  THEN es.DeletePort (IDevPort)  END;
  IF IReqBlock#NIL THEN es.DeleteStdIO(IReqBlock) END;
  IF MySig>=0      THEN e.FreeSignal  (MySig)     END;

END Mouse.

