-- File: ExecIO.mesa
-- edited by Levin, April 27, 1981 4:12 PM.
-- edited by Brotz, January 19, 1981 4:17 PM.
-- edited by Schroeder, January 19, 1981 3:45 PM.

DIRECTORY
Ascii,
dsD: FROM "DisplayDefs",
Editor,
inD: FROM "InteractorDefs",
Inline,
intCommon: FROM "intCommon",
IODefs,
LaurelExecDefs,
LaurelExecImpDefs,
ovD: FROM "OverviewDefs",
ProcessDefs,
StreamDefs,
String,
vmD: FROM "VirtualMgrDefs";

ExecIO: MONITOR LOCKS lock
IMPORTS dsD, Editor, inD, Inline, intC: intCommon, IODefs,
LaurelExecImpDefs, ProcessDefs, StreamDefs, String, vmD
EXPORTS LaurelExecDefs, LaurelExecImpDefs =

BEGIN

OPEN StreamDefs;

cmMnp: PUBLIC inD.MessageTextNbrPtr;

lock: PUBLIC MONITORLOCK;
ioState: PUBLIC LaurelExecImpDefs.IOState;
caretIsOn: BOOLEAN;

realInputAcceptor: inD.KeyboardInputAcceptor;


-- Initialization/Finalization --

InitializeExecIO: PUBLIC ENTRY PROCEDURE =
BEGIN
realKeyStream ← intC.keystream;
realInputAcceptor ← inD.keyboardInputAcceptorPtr↑;
inD.keyboardInputAcceptorPtr↑ ← InputAcceptor;
caretIsOn ← FALSE;
ioState ← originalScreen;
ProcessDefs.DisableTimeout[@charsAvailable];
ProcessDefs.DisableTimeout[@inputAcceptorCanRun];
END; -- of InitializeExecIO --


FinalizeExecIO: PUBLIC ENTRY PROCEDURE =
BEGIN
ks: StreamHandle = IODefs.GetInputStream[];
inD.keyboardInputAcceptorPtr↑ ← realInputAcceptor;
IF ioState = typescriptActive THEN LaurelExecImpDefs.SpliceExecutiveOutOfEditor[];
ks.reset[ks];
ioState ← goingAway;
NOTIFY inputAcceptorCanRun;
END; -- of FinalizeExecIO --


-- Key Stream Implementation Procedures --

charsAvailable, inputAcceptorCanRun: CONDITION;
realKeyStream: PUBLIC StreamHandle;


ResetKS: PUBLIC PROCEDURE[stream: StreamHandle] =
BEGIN
WITH s: stream SELECT FROM
Keyboard =>
BEGIN
realKeyStream.reset[realKeyStream];
LaurelExecImpDefs.FlushSourceSelection[]
END;
ENDCASE => ERROR StreamError[stream, StreamType];
END; -- of ResetKS --


PutBackKS: PUBLIC PROCEDURE[stream: StreamHandle, char: UNSPECIFIED] =
BEGIN
WITH s: stream SELECT FROM
Keyboard => realKeyStream.putback[realKeyStream, char];
ENDCASE => ERROR StreamError[stream, StreamType];
END; -- of PutBackKS --


PutKS: PUBLIC PROCEDURE[stream: StreamHandle, char: UNSPECIFIED] =
BEGIN
ERROR StreamError[stream, StreamAccess];
END; -- of PutKS --


GetKS: PUBLIC ENTRY PROCEDURE [stream: StreamHandle] RETURNS [UNSPECIFIED] =
BEGIN
char: CHARACTER;
WITH s: stream SELECT FROM
Keyboard =>
BEGIN
OPEN LaurelExecImpDefs;
WHILE realKeyStream.endof[realKeyStream] DO
NOTIFY inputAcceptorCanRun;
caretIsOn ← TRUE;
IF ioState ~= originalScreen THEN RefreshCaret[FALSE];
WAIT charsAvailable [ ! UNWIND => NULL ];
ENDLOOP;
char ← realKeyStream.get[realKeyStream ! UNWIND => NULL];
-- assert: char cannot be Editor.shiftedSelectionFlag
IF char = takeFromSecondaryChar AND
(char ← GetFromSourceSelection[]) < ovD.LineBreakValue THEN
realKeyStream.putback[realKeyStream, takeFromSecondaryChar];
inD.StopBlinkingCaret[]; caretIsOn ← FALSE;
END;
ENDCASE => RETURN WITH ERROR StreamError[stream, StreamType];
RETURN[Inline.BITAND[char, ovD.CharMask]]
END; -- of GetKS --



InputAcceptor: PUBLIC ENTRY inD.KeyboardInputAcceptor =
BEGIN
IF char = Editor.shiftedSelectionFlag THEN LaurelExecImpDefs.InitSourceSelection[]
ELSE realKeyStream.putback[realKeyStream, char];
UNTIL realKeyStream.endof[realKeyStream] OR ioState = goingAway DO
NOTIFY charsAvailable;
WAIT inputAcceptorCanRun;
ENDLOOP;
END; -- of InputAcceptor --


EndOfKS: PUBLIC ENTRY PROCEDURE [stream: StreamHandle] RETURNS [BOOLEAN] =
BEGIN
WITH s: stream SELECT FROM
Keyboard => RETURN[realKeyStream.endof[realKeyStream]];
ENDCASE => RETURN WITH ERROR StreamError[stream, StreamType];
END; -- of EndOfKS --


DestroyKS: PUBLIC PROCEDURE[stream: StreamHandle] =
BEGIN
WITH s: stream SELECT FROM
Keyboard => NULL;
ENDCASE => ERROR StreamError[stream, StreamType];
END; -- of DestroyKS --


-- Display Stream Implementation Procedures --


ResetDS: PUBLIC PROCEDURE[stream: StreamHandle] =
BEGIN
ERROR StreamError[stream, StreamType];
END; -- of ResetDS --


GetDS: PUBLIC PROCEDURE[stream: StreamHandle] RETURNS[UNSPECIFIED] =
BEGIN
ERROR StreamError[stream, StreamAccess];
END; -- of GetDS --


PutBackDS: PUBLIC PROCEDURE[stream: StreamHandle, char: UNSPECIFIED] =
BEGIN
ERROR StreamError[stream, StreamAccess];
END; -- of PutBackDS --


PutDS: PUBLIC ENTRY PROCEDURE[stream: StreamHandle, char: UNSPECIFIED] =
BEGIN
IF ioState = originalScreen THEN
{ioState ← typescriptActive; LaurelExecImpDefs.SpliceExecutiveIntoEditor[]};
WITH s: stream SELECT FROM
Display => AppendCharToMessage[Inline.BITAND[char, ovD.CharMask]];
ENDCASE => ERROR StreamError[stream, StreamType];
END; -- of PutDS --


EndOfDS: PUBLIC PROCEDURE[stream: StreamHandle] RETURNS[empty: BOOLEAN] =
BEGIN
SIGNAL StreamError[stream, StreamType];
RETURN[FALSE]
END; -- of PutDS --


DestroyDS: PUBLIC PROCEDURE[stream: StreamHandle] =
BEGIN
ERROR StreamError[stream, StreamAccess];
END; -- of DestroyDS --


ClearCurrentLineDS: PUBLIC PROCEDURE[stream: StreamHandle] =
BEGIN
stream.put[stream, ’?];
stream.put[stream, Ascii.CR];
END; -- of ClearCurrentLineDS --


ClearLineDS: PUBLIC PROCEDURE[stream: StreamHandle, line: CARDINAL] =
BEGIN
ERROR StreamError[stream, StreamAccess]; -- this should never be called
END; -- of ClearLineDS --


ClearCharDS: PUBLIC PROCEDURE[stream: StreamHandle, char: CHARACTER] =
BEGIN
AppendCharToMessage[Ascii.BS];
END; -- of ClearCharDS --


caretX: inD.ScreenXCoord;
caretY: inD.ScreenYCoord;


RefreshCaret: PUBLIC -- INTERNAL -- PROCEDURE [knowCaretPosition: BOOLEAN] =
-- inside monitor to protect caretIsOn
BEGIN
IF caretIsOn THEN
BEGIN
IF knowCaretPosition THEN inD.StartBlinkingCaret[caretX, caretY]
ELSE inD.SetCaretBlinking[intC.target.point, cmMnp ! UNWIND => NULL];
END;
END; -- of RefreshCaret --



AppendCharToMessage: PROCEDURE [char: CHARACTER] =
BEGIN
OPEN intC;
composeMessage: vmD.ComposeMessagePtr = LOOPHOLE[cmMnp.message];
line: inD.LinePtr;
knowCaretPosition: BOOLEAN ← FALSE;

inD.StopBlinkingCaret[];
line ← Editor.MakeCharIndexVisible[target.point, cmMnp];
IF char = Ascii.BS THEN
BEGIN
IF target.point = 0 THEN RETURN;
vmD.UnAppendMessageChar[composeMessage];
target.point ← vmD.GetMessageSize[composeMessage];
Editor.RefreshFromFirstChange[target.point, 1, 0, cmMnp];
END
ELSE BEGIN
rightX: dsD.ScreenXCoord;
IF target.point > 60000 THEN LaurelExecImpDefs.ShortenTypeScript[];
[] ← vmD.AppendMessageChar[composeMessage, char];
IF char = Ascii.CR
OR inD.rightMargin - inD.CRWidth >= (rightX ← dsD.GetCharRightX[char, line.rightX])
THEN BEGIN
IF line.state = endOfMessage THEN
BEGIN
line.rightX ← inD.leftMargin;
line.state ← normalText;
IF line.nextLine ~= NIL THEN line.nextLine.state ← endOfMessage;
END;
line.rightX ← IF char = Ascii.TAB
THEN rightX
ELSE dsD.PutCharInBitMap[char, line.rightX, line.y, plainFace];
IF char # Ascii.CR THEN
BEGIN
knowCaretPosition ← TRUE;
caretX ← line.rightX - 3;
caretY ← line.y + 9;
END;
FOR line ← line.nextLine, line.nextLine UNTIL line = NIL DO
line.firstCharIndex ← line.firstCharIndex + 1;
ENDLOOP;
END
ELSE Editor.RefreshFromFirstChange[target.point, 0, 1, cmMnp];
target.point ← vmD.GetMessageSize[composeMessage];
END;
[] ← Editor.MakeCharIndexVisible[target.point, cmMnp]; -- so that caret won’t disappear.
RefreshCaret[knowCaretPosition];
END; -- of AppendCharToMessage --

-- Miscellaneous --

FlashTypescriptRegion: PUBLIC PROCEDURE =
BEGIN
dcb: dsD.DCBptr = intC.CMRegion.dcb;

InvertPause: PROCEDURE = INLINE
BEGIN
startTime: CARDINAL = inD.realTimeClock↑;
UNTIL inD.realTimeClock↑ - startTime >= 8 DO NULL ENDLOOP;
END; -- of InvertPause --

dcb.background ← IF dcb.background = white THEN black ELSE white;
InvertPause[];
dcb.background ← IF dcb.background = white THEN black ELSE white;
END; -- of FlashTypescriptRegion --


GetUserCredentials: PUBLIC PROC [name, password, registry: STRING ← NIL] =
BEGIN
IF name#NIL THEN String.AppendString[name, intC.user.name
! String.StringBoundsFault => CONTINUE ];
IF password#NIL THEN String.AppendString[password, intC.user.password
! String.StringBoundsFault => CONTINUE ];
IF registry#NIL THEN String.AppendString[registry, intC.user.registry
! String.StringBoundsFault => CONTINUE ];
END; --GetUserCredentials--

END. -- of ExecIO --