-- edited by Teitelman June 9, 1982 7:35 am
-- edited by McGregor June 11, 1982 11:08 am

DIRECTORY
 ViewerIO, IO, Rope,
 ViewerClasses, TypeScript;

ViewerIOImpl: PROGRAM

IMPORTS IO, TypeScript
EXPORTS IO, ViewerIO
SHARES IO =

BEGIN

Viewer: TYPE = ViewerClasses.Viewer;

ViewerStreamData: TYPE = REF ViewerStreamDataRecord;
ViewerStreamDataRecord: TYPE = RECORD[
 viewer: Viewer,
 echoTo: IO.STREAMNIL
 ];

ViewerInStreamProcs: REF IO.StreamProcs ← IO.CreateRefStreamProcs[
 getChar: ViewerGetChar,
 close: ViewerClose,
 endOf: ViewerEndOf,
 charsAvail: ViewerCharsAvail,
 setEcho: ViewerSetEcho,
 userAbort: ViewerUserAbort,
 name: "Viewers Input"
 ];

ViewerOutStreamProcs: REF IO.StreamProcs ← IO.CreateRefStreamProcs[
 putChar: ViewerPutChar,
 putBlock: ViewerPutBlock,
 close: ViewerClose,
 endOf: ViewerEndOf,
 eraseChar: ViewerEraseChar,
 userAbort: ViewerUserAbort,
 name: "Viewers Output"
];

CreateTTYStreams: PUBLIC SAFE PROC [name: Rope.ROPE] RETURNS [in: IO.STREAM, out: IO.STREAM] =
TRUSTED
{[in, out] ← CreateViewerStreams[name];
};


CreateViewerStreams: PUBLIC PROC [name: Rope.ROPE, viewer: Viewer ← NIL, backingFile: Rope.ROPENIL] RETURNS [in: IO.STREAM, out: IO.STREAM] =
{OPEN IO;
IF viewer = NIL THEN viewer ← TypeScript.Create[info: [name: name]];
{in ← CreateProcsStream[streamProcs: ViewerInStreamProcs, streamData: NEW[ViewerStreamDataRecord ← [viewer: viewer]] ];
out ← CreateProcsStream[streamProcs: ViewerOutStreamProcs, streamData: NEW[ViewerStreamDataRecord ← [viewer: viewer]] ];
IF backingFile # NIL THEN out ← IO.CreateDribbleStream[stream: out, dribbleTo: IO.CreateFileStream[fileName: backingFile, accessOptions: overwrite], flushEveryNChars: 256];
[] ← SetEcho[in, out];
};
};

ViewerGetChar: SAFE PROCEDURE [self: IO.STREAM] RETURNS [char: CHARACTER] =
TRUSTED
BEGIN
data: ViewerStreamData ← NARROW[self.streamData];
IF data.viewer.destroyed THEN IO.Error[StreamClosed];
char ← TypeScript.GetChar[data.viewer];
IF data.echoTo # NIL THEN IO.PutChar[data.echoTo, char];
END; -- of ViewerGetChar

ViewerPutChar: SAFE PROCEDURE[self: IO.STREAM, char: CHARACTER] =
TRUSTED
BEGIN
data: ViewerStreamData ← NARROW[self.streamData];
IF data.viewer.destroyed THEN IO.Error[StreamClosed];
TypeScript.PutChar[data.viewer, char];
END; -- of ViewerPutChar

ViewerPutBlock: SAFE PROCEDURE[self: IO.STREAM, block: REF READONLY TEXT, startIndex: NAT, stopIndexPlusOne: NAT] =
TRUSTED
BEGIN
data: ViewerStreamData ← NARROW[self.streamData];
IF data.viewer.destroyed THEN IO.Error[StreamClosed];
TypeScript.PutText[ts: data.viewer, text: block, start: startIndex, stopPlusOne: stopIndexPlusOne];
END; -- of ViewerPutChar

ViewerReset: SAFE PROCEDURE[self: IO.STREAM] =
TRUSTED
BEGIN
data: ViewerStreamData ← NARROW[self.streamData];
TypeScript.Reset[data.viewer];
END; -- of ViewerClose

ViewerClose: SAFE PROCEDURE[self: IO.STREAM, abort: BOOLEAN] =
TRUSTED
BEGIN
data: ViewerStreamData ← NARROW[self.streamData];
IF ~data.viewer.destroyed THEN TypeScript.Destroy[data.viewer];
END; -- of ViewerClose

ViewerEndOf: SAFE PROCEDURE[self: IO.STREAM] RETURNS [BOOLEAN] =
CHECKED
BEGIN
data: ViewerStreamData ← NARROW[self.streamData];
IF data.viewer.destroyed THEN IO.Error[StreamClosed];
RETURN[FALSE];
END; -- ViewerEndOf

ViewerCharsAvail: SAFE PROCEDURE[self: IO.STREAM] RETURNS [BOOLEAN] =
TRUSTED
BEGIN
data: ViewerStreamData ← NARROW[self.streamData];
IF data.viewer.destroyed THEN IO.Error[StreamClosed];
RETURN[TypeScript.CharsAvailable[data.viewer]];
END; -- ViewerCharsAvail

ViewerEraseChar: SAFE PROCEDURE[self: IO.STREAM, char: CHARACTER] =
TRUSTED
BEGIN
data: ViewerStreamData ← NARROW[self.streamData];
IF data.viewer.destroyed THEN IO.Error[StreamClosed];
TypeScript.BackSpace[data.viewer];
END; -- of ViewerEraseChar

ViewerSetEcho: SAFE PROCEDURE[self: IO.STREAM, echoTo: IO.STREAM] RETURNS[oldEcho: IO.STREAM] =
CHECKED
BEGIN
data: ViewerStreamData ← NARROW[self.streamData];
IF data.viewer.destroyed THEN IO.Error[StreamClosed];
oldEcho ← data.echoTo;
data.echoTo ← echoTo;
END; -- of ViewerSetEcho

-- until Andrew gets around to doing this in a more general fashion, this will allow aborting of typeout to a stream that is connected to a typescript/exec
ViewerUserAbort: SAFE PROC [self: IO.STREAM] RETURNS [abort: BOOLEAN] =
TRUSTED
{data: ViewerStreamData ← NARROW[self.streamData];
RETURN[TypeScript.UserAbort[data.viewer]];
};


END.

March 24, 1982 7:46 pm W. Teitelman. Fixed Close to check if viewer already destroyed. Added name argument to CreateRefStreamProcs.
13-Apr-82 14:05:22 W. Teitelman. Added checks for whether viewer was destroyed, and if so, raised IO error
May 27, 1982 2:49 pm W. Teitelman. Changed name of IOStream to IO. Made changes relating to IO being in the Safe language
June 1, 1982 6:01 pm W. Teitelman. Added CheckForAbort.