DIRECTORY Commander USING [CommandProc, Register], EditedStream, Icons USING [IconFlavor, NewIconFromFile], InputFocus USING [PopInputFocus, PushInputFocus], IO, PopUpMenu, Process, Rope, RuntimeError USING [UNCAUGHT], TerminalIO, ViewerClasses USING [Viewer], ViewerIO USING [CreateViewerStreams, GetViewerFromStream], ViewerOps USING [PaintViewer], ViewerTools USING [SetSelection]; TerminalIOImpl: CEDAR MONITOR IMPORTS Commander, EditedStream, Icons, InputFocus, IO, PopUpMenu, Process, Rope, RuntimeError, ViewerIO, ViewerOps, ViewerTools EXPORTS TerminalIO = BEGIN UserAbort: PUBLIC SIGNAL = CODE; -- Signalyzed allways outside of monitor-lock terminalParent: ViewerClasses.Viewer_NIL; messageUsed: BOOLEAN _ FALSE; in, out, editedIn: IO.STREAM _ NIL; terminalIcon: Icons.IconFlavor; inputIcon: Icons.IconFlavor; del: CHAR = LOOPHOLE[127, CHAR]; delRope: Rope.ROPE = Rope.FromChar[del]; moduleEntered: BOOLEAN _ FALSE; next: CONDITION; -- the next module might enter the "moduleEntered" region MyLock: INTERNAL PROC [] = BEGIN ENABLE UNWIND => NULL; WHILE moduleEntered DO WAIT next; ENDLOOP; moduleEntered _ TRUE; terminalParent.icon _ inputIcon; terminalParent.name _ "Terminal [Input Expected]"; ViewerOps.PaintViewer[terminalParent, caption]; END; MyUnLock: INTERNAL PROC [] = BEGIN ENABLE UNWIND => NULL; moduleEntered _ FALSE; NOTIFY next; terminalParent.icon _ terminalIcon; terminalParent.name _ "Terminal"; ViewerOps.PaintViewer[terminalParent, caption]; terminalParent.inhibitDestroy _ FALSE; END; LockList: TYPE = LIST OF PROC; lockList: LockList_NIL; unLockList: LockList_NIL; AddLock: PUBLIC ENTRY PROC [lock, unLock: PROC] = BEGIN ENABLE UNWIND => NULL; lockList _ CONS[lock, lockList]; IF unLockList=NIL THEN unLockList _ LIST[unLock] ELSE FOR l: LockList _ unLockList, l.rest DO IF l.rest=NIL THEN {l.rest_LIST[unLock]; EXIT} ENDLOOP; END; Lock: INTERNAL PROC = BEGIN FOR l: LockList _ lockList, l.rest WHILE l#NIL DO l.first[! RuntimeError.UNCAUGHT => CONTINUE] ENDLOOP END; UnLock: INTERNAL PROC = BEGIN FOR l: LockList _ unLockList, l.rest WHILE l#NIL DO l.first[! RuntimeError.UNCAUGHT => CONTINUE] ENDLOOP END; InternalCreateTerminal: INTERNAL PROC [] = BEGIN [in: in, out: out] _ ViewerIO.CreateViewerStreams[ name: "Terminal", viewer: NIL, editedStream: FALSE]; [editedIn] _ EditedStream.Create[in: in, echoTo: out]; terminalParent _ ViewerIO.GetViewerFromStream[out]; IF terminalParent=NIL THEN ERROR; terminalParent.icon _ terminalIcon; END; Done: TYPE = {ok, repeat, intError, abort}; RequestRope: PUBLIC ENTRY PROC [text, text2: Rope.ROPE _ NIL] RETURNS [Rope.ROPE] = BEGIN ENABLE UNWIND => UnLock[]; done: Done; r: Rope.ROPE; DoIt: INTERNAL PROC [] = BEGIN ENABLE BEGIN IO.Error => IF ec=StreamClosed THEN { done_repeat; IO.Reset[editedIn]; CONTINUE } ELSE REJECT; EditedStream.Rubout => { done_abort; IO.Reset[editedIn]; CONTINUE }; END; InternalWriteRope[text]; InternalWriteRope[text2]; InputFocus.PushInputFocus[terminalParent]; ViewerTools.SetSelection[terminalParent]; r _ IO.GetLineRope[editedIn]; InputFocus.PopInputFocus[]; IF Rope.Find[r, delRope]>=0 THEN done_abort; END; Lock[]; DO done _ ok; DoIt[]; IF done=ok THEN {UnLock[]; RETURN [r]} ELSE IF done=repeat THEN {InternalWriteRope["XXX\n"]} ELSE {InternalWriteRope[" ..user abort\n"]; SIGNAL UserAbort} ENDLOOP; END; RequestChar: PUBLIC ENTRY PROC [text, text2: Rope.ROPE _ NIL] RETURNS [CHAR] = BEGIN ENABLE UNWIND => UnLock[]; done: Done; ch: CHAR; DoIt: INTERNAL PROC [] = BEGIN ENABLE BEGIN IO.Error => IF ec=StreamClosed THEN {done_repeat; CONTINUE} ELSE REJECT; EditedStream.Rubout => { done_abort; IO.Reset[in]; CONTINUE }; END; InternalWriteRope[text]; InternalWriteRope[text2]; InputFocus.PushInputFocus[terminalParent]; ViewerTools.SetSelection[terminalParent]; ch _ IO.GetChar[in]; -- returns immediately, no CR to eat InputFocus.PopInputFocus[]; IF ch=del THEN done_abort; END; Lock[]; DO done _ ok; DoIt[]; IF done=ok THEN {UnLock[]; RETURN[ch]} ELSE IF done=repeat THEN {InternalWriteRope["XXX\n"]} ELSE { InternalWriteRope[" ..user abortion\n"]; SIGNAL UserAbort }; ENDLOOP; END; RequestInt: PUBLIC ENTRY PROC [text, text2: Rope.ROPE _ NIL] RETURNS [INT] = BEGIN ENABLE UNWIND => UnLock[]; done: Done; i: INT; DoIt: INTERNAL PROC [] = BEGIN ENABLE BEGIN IO.Error => IF ec=StreamClosed THEN {done_repeat; CONTINUE} ELSE IF ec=Overflow THEN {done_intError; CONTINUE} ELSE IF ec=SyntaxError THEN {done_intError; CONTINUE} ELSE REJECT; EditedStream.Rubout => { done_abort; IO.Reset[editedIn]; CONTINUE }; END; ch: CHAR; InternalWriteRope[text]; InternalWriteRope[text2]; InputFocus.PushInputFocus[terminalParent]; ViewerTools.SetSelection[terminalParent]; i _ IO.GetInt[editedIn]; WHILE IO.CharsAvail[editedIn]>0 DO [ch] _ IO.GetChar[editedIn]; IF ch=del THEN done_abort; IF ch#15C AND done#abort THEN done_intError ENDLOOP; InputFocus.PopInputFocus[]; END; Lock[]; DO done _ ok; DoIt[]; IF done=ok THEN {UnLock[]; RETURN[i]} ELSE IF done=repeat THEN {InternalWriteRope["XXX\n"]} ELSE IF done=intError THEN {InternalWriteRope[" ?? (integer), please repeat: \n"]} ELSE {InternalWriteRope[" ..user abortion\n"]; SIGNAL UserAbort} ENDLOOP; END; ChoiceError: ERROR = CODE; RequestSelection: PUBLIC ENTRY PROC [ label: Rope.ROPE _ NIL, choice: LIST OF Rope.ROPE, text: Rope.ROPE _ NIL, default: CARDINAL_0] RETURNS [CARDINAL] = BEGIN ENABLE UNWIND => UnLock[]; c: CARDINAL _ 0; IF (choice=NIL) OR (choice.first=NIL) THEN RETURN WITH ERROR ChoiceError; Lock[]; IF text#NIL THEN InternalWriteRope[text]; IO.Flush[out ! RuntimeError.UNCAUGHT => CONTINUE]; Process.Pause[Process.MsecToTicks[5]]; c _ PopUpMenu.RequestSelection[label, choice, default]; UnLock[]; RETURN [c]; END; UserSaysYes: PUBLIC PROC [label, text: Rope.ROPE _ NIL, default: BOOLEAN_FALSE] RETURNS [BOOLEAN] = BEGIN RETURN [SELECT RequestSelection[label, LIST["yes", "no"], text, (IF default THEN 1 ELSE 2)] FROM 1 => TRUE, 2 => FALSE ENDCASE => default]; END; InternalWriteRope: INTERNAL PROC [text: Rope.ROPE] = BEGIN IF out=NIL THEN InternalCreateTerminal[]; IO.PutRope[out, text ! IO.Error => { IF ec=StreamClosed THEN { InternalCreateTerminal[]; IO.PutRope[out, text]; CONTINUE } ELSE REJECT }]; END; WriteRope: PUBLIC ENTRY PROC [text: Rope.ROPE] = BEGIN ENABLE UNWIND => NULL; InternalWriteRope[text]; END; WriteLn: PUBLIC PROC [] = BEGIN WriteRope["\n"]; END; WriteChar: PUBLIC PROC [ch: CHAR] = BEGIN WriteRope[Rope.FromChar[ch]]; END; WriteInt: PUBLIC PROC [i: INT] = BEGIN WriteRope[IO.PutFR[format: " %g", v1: IO.int[i]]]; END; CreateTerminal: ENTRY Commander.CommandProc = BEGIN ENABLE UNWIND => NULL; InternalCreateTerminal[]; END; Init: PROC [] = BEGIN terminalIcon _ Icons.NewIconFromFile["TerminalIO.icons", 0 ! RuntimeError.UNCAUGHT => { terminalIcon_Icons.NewIconFromFile["/indigo/chipndale/TerminalIO5.1/TerminalIO.icons", 0 ! RuntimeError.UNCAUGHT => {terminalIcon_Icons.IconFlavor[unInit]; CONTINUE}]; CONTINUE }]; inputIcon _ Icons.NewIconFromFile["TerminalIO.icons", 1 ! RuntimeError.UNCAUGHT => { inputIcon_Icons.NewIconFromFile["/indigo/chipndale/TerminalIO5.1/TerminalIO.icons", 1 ! RuntimeError.UNCAUGHT => {inputIcon_terminalIcon; CONTINUE}]; CONTINUE }]; AddLock[MyLock, MyUnLock]; Commander.Register[ key: "Terminal", proc: CreateTerminal, doc: "Create terminal viewer if it does not yet exist"]; END; Init[]; END. DTerminalIOImpl.mesa By Ch. Jacobi August 3, 1983 9:54 am Last edited by Ch. Jacobi November 9, 1983 12:06 pm -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --Terminals own locking procedures --is set if process releases the monitorlock but waits still for input --conveniant to be here since in all places where UnLock is called -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --Lock, UnLock mechanism -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --creation of viewer -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --input procedures --RequestRope --RequestChar --RequestInt --SILLY FLUSH DOESN'T WORK -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --output procedures --terminalParent.inhibitDestroy _ FALSE; -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- Ê ,˜Jšœ™Jšœ$™$Jšœ3™3J˜šÏk ˜ Jšœ œ˜(Jšœ ˜ Jšœœ"˜-Jšœ œ!˜1Jšœ˜J˜ Jšœ˜Jšœ˜Jšœ œœ˜J˜ Jšœœ ˜Jšœ œ,˜:Jšœ œ˜!Jšœ œ˜!—J˜JšÏbœœ˜J˜šœ˜Jšœ,œJ˜x—šœ˜J˜ —Jš˜J˜Jšœ œœœÏc-˜NJšœ%œ˜)Jšœ œœ˜Jšœœœœ˜#J˜J˜J˜Jšœœœœ˜ Jšœœ˜(J™Jšœ;™;Jšœ"™"J˜šœœœ˜ JšœF™F—Jšœ œŸ9˜KJ˜šÏnœœœ˜šœ˜Jšœœœ˜—šœ˜Jšœ˜ Jšœ˜—Jšœœ˜J˜ J˜5J˜/Jšœ˜—J˜š œœœ˜šœ˜Jšœœœ˜—Jšœœ˜Jšœ˜ J˜#J˜!J˜/JšœC™CJšœ œ˜&Jšœ˜—J˜Jšœ8™8Jšœ™J˜Jš œ œœœœ˜Jšœœ˜Jšœœ˜J˜š  œœœœœ˜1šœ˜Jšœœœ˜—Jšœ œ˜ Jšœ œœœ˜0š˜šœ"˜'Jš œœœ œ œ˜.Jšœ˜——Jšœ˜—J˜š œœœ˜Jš˜šœ œœ˜1Jšœœœ˜,Jš˜—Jšœ˜—J˜š œœœ˜Jš˜šœ"œœ˜3Jšœœœ˜,Jš˜—Jšœ˜—J˜Jšœ;™;Jšœ™J˜š œœœ˜+Jš˜˜2J˜Jšœœ˜ Jšœœ˜—Jšœ6˜6Jšœ3˜3Jšœœœœ˜!J˜#Jšœ˜—J˜Jšœ8™8Jšœ™J˜Jšœœ!˜+J˜š  œœœœœœœœ˜Sšœ˜Jšœœ ˜—Jšœ ˜ Jšœœ˜ J˜š œœœ˜šœ˜šœ˜ šœ ˜ šœœ˜Jšœ œ˜)Jšœ˜—Jšœœ˜ —šœ˜Jšœ œ˜(J˜—Jšœ˜——J˜J˜Jšœ*˜*Jšœ)˜)Jšœœ˜J˜Jšœœ ˜,Jšœ˜J˜—Jšœ ™ Jšœ˜š˜J˜ J˜Jšœ œ œ˜&Jšœœ œ˜5Jšœ(œ ˜>Jšœ˜—Jšœ˜—J˜š  œœœœœœœœ˜Nšœ˜Jšœœ ˜—Jšœ ˜ Jšœœ˜ J˜š œœœ˜šœ˜šœ˜ šœ ˜ Jšœœœ˜/Jšœœ˜ —šœ˜Jšœ œ ˜"J˜—Jšœ˜——J˜J˜Jšœ*˜*Jšœ)˜)JšœœŸ$˜:J˜Jšœœ ˜Jšœ˜J˜—Jšœ ™ J˜š˜Jšœ ˜ J˜Jšœ œ œ˜&Jšœœ œ˜5šœ˜Jšœ)˜)Jšœ ˜J˜—Jšœ˜—Jšœ˜—J˜š  œœœœœœœœ˜Lšœ˜Jšœœ ˜—Jšœ ˜ Jšœœ˜J˜š œœœ˜šœ˜šœ˜ šœ ˜ Jšœœœ˜/Jšœœ œœ˜2Jšœœœœ˜5Jšœœ˜ —šœ˜Jšœ œ˜(J˜—Jšœ˜——Jšœœ˜ J˜J˜Jšœ*˜*Jšœ)˜)Jšœœ˜šœœ˜"Jšœœ˜Jšœœ ˜Jšœœ œ˜+Jšœ˜—J˜Jšœ˜J˜—Jšœ ™ J˜šœ˜J˜ J˜Jšœ œ œ˜%Jšœœ œ˜5Jšœœœ9˜SJšœ+œ ˜AJšœ˜—Jšœ˜—J˜Jšœ œœ˜J˜š œœœœ˜%Jšœ œœ˜Jšœœœœ˜Jšœ œœ˜šœ œ˜Jšœœ˜—šœ˜Jšœœ ˜—Jšœœ˜Jšœ œœœœœœœ ˜IJ˜Jšœœœ˜)Jšœœœ˜2J˜Jšœ™Jšœ&˜&J˜J˜7J˜ Jšœ˜ Jšœ˜—J˜š  œœœœœ œœœœ˜cJšœ˜šœœ˜š œœœ œœ˜QJšœœ˜ Jšœ˜ Jšœ ˜——Jšœ˜—J˜Jšœ8™8Jšœ™J˜š œœœ œ˜5Jšœ˜Jšœœœ˜)šœœ ˜$šœœ˜J˜Jšœ˜Jš˜J˜—Jšœ˜ Jšœ˜—Jšœ˜—J˜š   œœœœ œ˜1šœ˜Jšœœœ˜—J˜Jšœ"œ™(Jšœ˜—J˜š œœœ˜Jšœ˜J˜Jšœ˜—J˜š  œœœœ˜$Jšœ˜J˜Jšœ˜—J˜š œœœœ˜!Jšœ˜Jšœ œœ ˜2Jšœ˜J˜—Jšœ;™;J˜š œœ˜-šœ˜Jšœœœ˜—J˜Jšœ˜—J˜š œœ˜Jš˜˜;šœœ˜šœX˜XJšœœ,œ˜N—Jš˜Jšœ˜——˜8šœœ˜šœU˜UJšœœœ˜?——Jš˜Jšœ˜—J˜˜J˜J˜J˜8—Jšœ˜—J˜Jšœ˜Jšœ˜J˜—…—-v