(*---------------------------------------------------------------------------
  :Program.    MultiNotify
  :Author.     Thomas Igracki
  :Address.    Obstallee 45, 1000 Berlin 20, W-Germany
  :E-Mail.     T.IGRACKI@BAMP.ZER
  :Version.    V1.0
  :Date.       08-Apr-92
  :Copyright.  Me
  :Language.   Oberon
  :Translator. Amiga Oberon 2.13d
  :Contents.   Modul zur Unterstützung von _mehreren_ Notifies.
  :Usage.      IMPORT MultiNotify
  :Remark.     OS2.0 Only!
---------------------------------------------------------------------------*)

MODULE MultiNotify;
IMPORT
  s: SYSTEM, d: Dos, e: Exec, l: Lists;
TYPE
(* NotifyRequest nochmal definiert, da sie in Dos.mod falsch definiert ist! *)
  NotifyRequest * = STRUCT
    name * : e.STRPTR;
    fullName * : e.STRPTR;           (* set by dos - don't touch *)
    userData * : LONGINT;            (* for applications use *)
    flags * : LONGSET;

    (* port * : e.MsgPortPtr; das war der Fehler! *)

    task * : e.TaskPtr;              (* could also be: port * : e.MsgPortPtr *)
    signalNum * : SHORTINT;
    pad1,pad2,pad3: SHORTINT;

    reserved * : ARRAY 4 OF LONGINT; (* leave 0 for now *)

    (* internal use by handlers *)
    msgCount * : LONGINT;            (* # of outstanding msgs *)
    handler  * : e.MsgPortPtr;       (* handler sent to (for EndNotify) *)
  END;

  NotifyNode = RECORD(l.Node) not: NotifyRequest END;
  NotifyNodePtr = POINTER TO NotifyNode;
VAR
   dos       : d.DosLibraryPtr;
   NotifyList: l.List;
   NodePtr   : l.NodePtr;

PROCEDURE DosStartNotify {dos,-888}(VAR notify{1}: NotifyRequest): BOOLEAN;
PROCEDURE DosEndNotify   {dos,-894}(VAR notify{1}: NotifyRequest);

(* Das Signal wird zurückgegeben, oder -1 wenn was falsch lief *)
PROCEDURE StartNotify* (name: ARRAY OF CHAR): SHORTINT;
VAR nn: NotifyNodePtr;
BEGIN
     NEW(nn); IF nn = NIL THEN RETURN -1 END;
     nn.not.name := s.ADR(name); nn.not.flags := LONGSET{d.sendSignal};
     nn.not.task := e.exec.thisTask; nn.not.signalNum := e.AllocSignal(-1);
     IF nn.not.signalNum = -1 THEN RETURN -1 END;
     IF DosStartNotify (nn.not) THEN
	l.AddTail (NotifyList,nn); RETURN nn.not.signalNum
     ELSE
        RETURN -1
     END
END StartNotify;

BEGIN
     dos := d.dos; l.Init (NotifyList)

CLOSE (* Notify-Liste löschen und Notifier beenden, DISPOSEd wird automatisch *)

     WHILE ~l.Empty (NotifyList) DO
	NodePtr := l.RemHead (NotifyList);
	e.FreeSignal (NodePtr(NotifyNodePtr).not.signalNum);
	DosEndNotify (NodePtr(NotifyNodePtr).not);
     END;
END MultiNotify.
