-- TJaMGraphicsInfoImpl.mesa
-- Last change by Bill Paxton, 2-Feb-82 12:50:27
-- Last changed by Rick Beach, July 1, 1982 11:29 am
-- Last changed by Ken Pier, March 22, 1983 4:36 pm
-- Last Edited by: Stone, April 19, 1983 2:03 pm


DIRECTORY
Graphics, TJaMGraphicsInfo, TJaMGraphicsContexts;

TJaMGraphicsInfoImpl: MONITOR
IMPORTS
EXPORTS TJaMGraphicsInfo, TJaMGraphicsContexts =
BEGIN OPEN TJaMGraphicsInfo, TDC: TJaMGraphicsContexts;

InfoList: TYPE = REF InfoListRec;
InfoListRec: TYPE = RECORD [info: Info, rest: InfoList];
list: InfoList;

NotFound: PUBLIC SIGNAL = CODE;
CreateInfo: PUBLIC ENTRY PROC [frame: Frame] RETURNS [info: Info] = {
ENABLE UNWIND => NULL;
 info ← NEW[InfoRec];
 info.frame ← frame;
FOR l:InfoList ← list, l.rest UNTIL l=NIL DO
  IF l.info.frame=frame THEN ERROR;
  ENDLOOP;
 list ← NEW[InfoListRec ← [info,list]] };

ForgetInfo: PUBLIC ENTRY PROC [frame: Frame] = {
ENABLE UNWIND => NULL;
 pred: InfoList;
IF list=NIL THEN RETURN;
IF list.info.frame=frame THEN { list ← list.rest; RETURN };
 pred ← list;
FOR l:InfoList ← list.rest, l.rest UNTIL l=NIL DO
  IF l.info.frame=frame THEN { pred.rest ← l.rest; RETURN };
  pred ← l; ENDLOOP };

GetInfo: PUBLIC ENTRY PROC [frame: Frame] RETURNS [info: Info] = {
ENABLE UNWIND => NULL;
FOR l:InfoList ← list, l.rest UNTIL l=NIL DO
  IF l.info.frame=frame THEN RETURN [l.info];
  ENDLOOP;
RETURN [NIL] };

AddContext: PUBLIC ENTRY PROC [frame: Frame, init: PROC RETURNS[Graphics.Context], name: ATOM, enabled, initOnErase: BOOLEANTRUE] = {
ENABLE UNWIND => NULL;
 end,new: TDC.DCList ← NIL;
 found: BOOLEANFALSE;
 context: Graphics.Context ← init[];
FOR l:InfoList ← list, l.rest UNTIL l=NIL DO
  IF l.info.frame=frame THEN {
   FOR dl: TDC.DCList ← l.info.dcList, dl.next UNTIL dl=NIL DO
    IF dl.name=name THEN {
     dl.init ←init; dl.dc ← context;
     dl.enabled ← enabled; dl.initOnErase ← initOnErase;
     found ← TRUE;
     };
    end ← dl;
    ENDLOOP;
   IF ~found THEN new ← NEW[TDC.DCRec ←
    [next: NIL, init: init, dc: context, enabled: enabled, name: name, initOnErase: initOnErase]];
   IF end=NIL THEN l.info.dcList ← new ELSE end.next ← new;
   RETURN};
  ENDLOOP;
 };

RemoveContext: PUBLIC ENTRY PROC [frame: Frame, name: ATOM] RETURNS [context: Graphics.Context ← NIL]= {
ENABLE UNWIND => NULL;
 prev: TDC.DCList ← NIL;
 found: BOOLEANFALSE;
FOR l:InfoList ← list, l.rest UNTIL l=NIL DO
  IF l.info.frame=frame THEN {
   IF l.info.dcList=NIL THEN SIGNAL NotFound;
   FOR dl: TDC.DCList ← l.info.dcList, dl.next UNTIL dl=NIL DO
    IF dl.name=name THEN {
     IF prev=NIL THEN l.info.dcList ← dl.next
     ELSE {prev.next ← dl.next; RETURN[dl.dc]};
     };
    prev ← dl;
    ENDLOOP;
   SIGNAL NotFound;
   RETURN[NIL];
    };
  ENDLOOP;
 };

EnableContext: PUBLIC PROC [frame: Frame, name: ATOM] = {
ENABLE UNWIND => NULL;
 found: BOOLEANFALSE;
FOR l:InfoList ← list, l.rest UNTIL l=NIL DO
  IF l.info.frame=frame THEN {
   IF l.info.dcList=NIL THEN SIGNAL NotFound;
   FOR dl: TDC.DCList ← l.info.dcList, dl.next UNTIL dl=NIL DO
    IF dl.name=name THEN {dl.dc ← dl.init[]; dl.enabled ← TRUE};
    ENDLOOP;
   RETURN};
  ENDLOOP;
  SIGNAL NotFound
 };

DisableContext: PUBLIC PROC [frame: Frame, name: ATOM] = {
ENABLE UNWIND => NULL;
 found: BOOLEANFALSE;
FOR l:InfoList ← list, l.rest UNTIL l=NIL DO
  IF l.info.frame=frame THEN {
   IF l.info.dcList=NIL THEN SIGNAL NotFound;
   FOR dl: TDC.DCList ← l.info.dcList, dl.next UNTIL dl=NIL DO
    IF dl.name=name THEN dl.enabled ← FALSE;
    ENDLOOP;
   RETURN};
  ENDLOOP;
  SIGNAL NotFound
 };

ForAllDCs: PUBLIC PROC [list: TDC.DCList, proc: TDC.GProc] = {
FOR l: TDC.DCList ← list, l.next UNTIL l=NIL DO
  IF l.enabled THEN proc[l.dc];
  ENDLOOP;
 };



END...