-- LocalTTYDriver.mesa
-- Edited by Brotz, June 24, 1982 3:01 PM


DIRECTORY
Ascii,
Editor,
exD: FROM "ExceptionDefs",
inD: FROM "InteractorDefs",
intCommon,
IODefs,
LaurelTTYDefs,
StreamDefs,
String,
vmD: FROM "VirtualMgrDefs";

LocalTTYDriver: MONITOR
IMPORTS Editor, exD, inD, intC: intCommon, IODefs, LaurelTTYDefs, StreamDefs, String,
vmD =

BEGIN


Main: PROCEDURE =
BEGIN
handleObject: LaurelTTYDefs.HandleObject ←
[IODefs.ReadChar,
ReadString,
ReadDecimal,
IODefs.WriteChar,
IODefs.WriteString,
IODefs.WriteLine,
IODefs.WriteDecimal,
WriteLongDecimal,
SendNow,
CharsLeft,
LinesLeft,
SetWidth,
SetHeight,
DelTyped,
Synch,
Flush];
exD.SetExternalExceptionProc[IODefs.WriteString];
inD.SetExternalConfirmProc[MyConfirm];
LaurelTTYDefs.ZeroBuffer[@LaurelTTYDefs.buffer];
vmD.InsertRangeInMessage[0, LaurelTTYDefs.buffer,
[0, vmD.GetMessageSize[intC.cmTextNbr.message], intC.cmTextNbr.message]];
LaurelTTYDefs.TTYInterface[@handleObject];
vmD.ReplaceRangeInMessage
[to: [0, vmD.GetMessageSize[intC.cmTextNbr.message], intC.cmTextNbr.message],
from: [0, vmD.GetMessageSize[LaurelTTYDefs.buffer], LaurelTTYDefs.buffer]];
Editor.RefreshSoThatFirstCharStartsLine[0, intC.cmTextNbr.lines, intC.cmTextNbr];
Editor.InitializeSelection[@intC.target];
LaurelTTYDefs.CleanupTTYEditor[];
exD.SetExternalExceptionProc[NIL];
inD.SetExternalConfirmProc[NIL];
END; -- of Main --


ReadString: PROCEDURE [s: STRING] RETURNS [end: CHARACTER] =
BEGIN

ShowIt: PROCEDURE = {IODefs.WriteString[s]};

Unwrite: PROCEDURE =
BEGIN
IF s.length > 0 THEN
BEGIN
IODefs.WriteChar[’\];
IODefs.WriteChar[s[s.length - 1]];
s.length ← s.length - 1;
END;
END; -- of Unwrite --

ClearWord: PROCEDURE =
BEGIN
state: {alpha, other} ← other;
WHILE s.length > 0 DO
SELECT s[s.length - 1] FROM
IN [’a .. ’z], IN [’A .. ’Z], IN [’0 .. ’9] => state ← alpha;
ENDCASE => IF state # other THEN EXIT;
Unwrite[];
ENDLOOP;
END; -- of ClearWord --

c: CHARACTER;
ShowIt[];
SELECT (c ← IODefs.ReadChar[]) FROM
Ascii.ControlA, Ascii.BS, Ascii.ControlW, --client wants to edit it--
Ascii.SP, Ascii.CR, Ascii.DEL => NULL; --client accepts it--
ENDCASE => IF s.length > 0 THEN
{IODefs.WriteString["← "L]; s.length ← 0}; --client rejects it--
DO
SELECT c FROM
Ascii.ControlA, Ascii.BS => Unwrite[];
Ascii.ControlW => ClearWord[];
ENDCASE =>
BEGIN
SELECT c FROM
Ascii.SP, Ascii.CR, Ascii.ESC, Ascii.DEL => {end ← c; EXIT};
ENDCASE => NULL;
IF s.length < s.maxlength THEN
BEGIN
s[s.length] ← c;
s.length ← s.length + 1;
IODefs.WriteChar[c];
END
ELSE IODefs.WriteChar[Ascii.BEL];
END;
c ← IODefs.ReadChar[];
ENDLOOP;
END; -- of ReadString --


ReadDecimal: PROCEDURE RETURNS [n: CARDINAL] =
BEGIN
s: STRING ← [10];
[] ← ReadString[s];
n ← String.StringToDecimal[s ! String.InvalidNumber => {n ← 0; CONTINUE}];
END; -- of ReadDecimal --


WriteLongDecimal: PROCEDURE [n: LONG INTEGER] =
BEGIN
s: STRING = [11] -- -6553665536 --;
String.AppendLongDecimal[s, n];
IODefs.WriteString[s];
END; -- of WriteLongDecimal --


SendNow: PROCEDURE = {};

CharsLeft: PROCEDURE RETURNS [CARDINAL] = {RETURN[LAST[CARDINAL]]};

LinesLeft: PROCEDURE RETURNS [CARDINAL] = {RETURN[LAST[CARDINAL]]};

SetWidth: PROCEDURE [new: CARDINAL] = {};

SetHeight: PROCEDURE [new: CARDINAL] = {};

Synch: PROCEDURE = {};

DelTyped: PROCEDURE RETURNS [BOOLEAN] = {RETURN[StreamDefs.ControlDELtyped[]]};

Flush: PROCEDURE =
BEGIN
stream: StreamDefs.StreamHandle ← IODefs.GetInputStream[];
stream.reset[stream];
StreamDefs.ResetControlDEL[];
END; -- of Flush --


MyConfirm: PROCEDURE RETURNS [BOOLEAN] =
BEGIN
IODefs.WriteString["Type ESC to confirm, DEL to cancel."L];
SELECT IODefs.ReadChar[] FROM
Ascii.ESC, Ascii.CR, ’y, ’Y => {IODefs.WriteString["Yes"L]; RETURN[TRUE]};
ENDCASE => {IODefs.WriteString["Yes"L]; RETURN[FALSE]};
END; -- of MyConfirm --


Main[];


END. -- of LocalTTYDriver --