NSTTYBImpl.mesa
Copyright (C) 1984, 1986 by Xerox Corporation. All rights reserved.
Last edited by McManis on: 21-Aug-85 9:40:43
Overview: Implement's NS versions of TTY operations
Tim Diebert: December 9, 1986 2:00:14 pm PST
DIRECTORY
Ascii USING [ControlC],
Basics USING [BITAND],
NSString USING [Character, String],
NSTranslate USING [
AccentPointer, AccentRange, AccentType, emptySlot, InputMapping, ISOCode,
LoadTables, maxEntries, SneakProc, XlateInfo],
NSTTY USING [],
SCSMsgs USING [MsgHandle],
TextInputMessages USING [Key],
TTY USING [CharStatus, -- EchoClass, -- GetChar, GetEditedString, Handle, -- LineOverflow, -- PutChar, PutLine, PutString, RemoveCharacter, Rubout],
TTYExtras USING [ --accents, bs, controlW, controlX, -- cr, -- DEL, ff, -- GetByte, -- Handle, lf, lowerAlpha, -- Object, -- numbers, -- PutByte, space--, star, upperAlpha --];
XMessage USING [Get];
NSTTYBImpl: MONITOR LOCKS h USING h: Handle
IMPORTS Basics, TTY, TTYExtras
EXPORTS TTY, NSTTY, TTYExtras = BEGIN
sneak: NSTranslate.SneakProc = {};
Handle: PUBLIC TYPE = REF Object;
Object: PUBLIC TYPE = TTYExtras.Object;
ESCAPE: BYTE = 377B;
NSGetChar: PUBLIC SAFE PROCEDURE [h: Handle] RETURNS [c: NSString.Character] =
TRUSTED BEGIN
c ← [0, LOOPHOLE[TTY.GetChar[h]]];
entry: LONG POINTER TO NSTranslate.InputMapping;
found: BOOLEANFALSE;
Convert: PROCEDURE = {
SELECT TRUE FROM
entry.bsCode # 0 => {
h.inputState ← bs; h.inputChar ← [entry.bsSet, entry.bsCode]};
entry.accentCode # 0 => {
h.inputChar ← [entry.set, entry.code];
h.inputState ← have;
c ← [entry.accentSet, entry.accentCode];
found ← TRUE};
ENDCASE => {
c ← [entry.set, entry.code];
IF PossibleAccent[c] THEN {h.inputState ← normal; h.inputChar ← c}
ELSE {
found ← TRUE;
IF h.inputState = normal THEN {
h.inputState ← have;
c ← h.inputChar;
h.inputChar ← [entry.set, entry.code]}
ELSE h.inputState ← idle}};
};
h.line ← 0;
UNTIL found DO
SELECT h.inputState FROM
idle => {entry ← @h.dataFile.inputTable[Get7BitByte[h]]; Convert[]};
bs => {
inChar: NSTranslate.ISOCode ← Get7BitByte[h];
IF inChar = TTYExtras.bs THEN h.inputState ← wait
ELSE {entry ← @h.dataFile.inputTable[inChar]; Convert[]}};
wait => {
c ← h.inputChar;
entry ← @h.dataFile.inputTable[Get7BitByte[h]];
h.inputChar ← [entry.set, entry.code];
h.inputState ← idle;
IF AccentTypeOf[c, h.inputChar, h.dataFile] = Backspace THEN Convert[]};
normal => {
entry ← @h.dataFile.inputTable[Get7BitByte[h]]; Convert[]};
have => {h.inputState ← idle; c ← h.inputChar; found ← TRUE};
ENDCASE;
ENDLOOP;
END;
NSGetString: PUBLIC SAFE PROCEDURE [h: Handle, s: NSString.String,
t: PROCEDURE [c: NSString.Character] RETURNS [status: TTY.CharStatus]] = TRUSTED {
NSPutChar[h, NSGetEditedString[h, s, t]]};
myT: SAFE PROC [char: CHAR] RETURNS [status: TTY.CharStatus] = TRUSTED {
RETURN[t[[0, LOOPHOLE[char]]]]};
TTY.PutChar[h, TTY.GetEditedString[h, s, myT]]};
NSGetEditedString: PUBLIC SAFE PROCEDURE [h: Handle, s: NSString.String,
t: PROCEDURE [c: NSString.Character] RETURNS [status: TTY.CharStatus]]
RETURNS [c: NSString.Character] = TRUSTED BEGIN
myT: SAFE PROC [char: CHAR] RETURNS [status: TTY.CharStatus] = TRUSTED {
RETURN[t[[0, LOOPHOLE[c]]]]};
RETURN[[0, LOOPHOLE[TTY.GetEditedString[h, s, myT]]]];
firstChar: BOOLEANTRUE;
EchoChar: PROCEDURE [c: NSString.Character] = BEGIN
byte: NSTranslate.ISOCode;
EchoPutChar: PROCEDURE [iso: NSTranslate.ISOCode] = BEGIN
SELECT h.echo FROM
plain => PutISOChar[h, iso];
stars => PutISOChar[h, TTYExtras.star];
ENDCASE;
END;
IF h.outputState = idle
THEN IF PossibleAccent[c]
THEN {h.outputState ← wait; h.outputChar ← c}
ELSE EchoPutChar[h.dataFile.outputTable[c.code]]
ELSE {
accentType: NSTranslate.AccentType;
[byte, accentType] ← Translate[h.outputChar, c, h.dataFile];
h.outputState ← idle;
SELECT accentType FROM
Normal => {
IF PossibleAccent[c]
THEN {h.outputState ← wait; h.outputChar ← c}
ELSE {EchoPutChar[byte]; EchoPutChar[h.dataFile.outputTable[c.code]]}};
DeadChar => {
EchoPutChar[byte];
EchoPutChar[h.dataFile.outputTable[h.outputChar.code]]};
Backspace => {
EchoPutChar[byte];
BackwardClear[h, 1];
EchoPutChar[h.dataFile.outputTable[h.outputChar.code]]};
Accented => EchoPutChar[byte];
ENDCASE => NULL};
END;
DeleteChar: PROCEDURE = BEGIN
accentType: NSTranslate.AccentType ← Normal;
DeletePutChar: PROCEDURE =
BEGIN IF h.echo # none THEN BackwardClear[h, 1] END;
SELECT s.length FROM
0 => NULL;
1 => {DeletePutChar[]; s.length ← 0};
ENDCASE =>
IF PossibleAccent[NSString.Character[0, s.bytes[s.length - 2]]] THEN
BEGIN
byte: NSTranslate.ISOCode;
accentType: NSTranslate.AccentType;
[byte, accentType] ← Translate[
NSString.Character[0, s.bytes[s.length - 2]], NSString.Character[
0, s.bytes[s.length - 1]], h.dataFile];
SELECT accentType FROM
Normal => {DeletePutChar[]; s.length ← s.length - 1};
DeadChar => {DeletePutChar[]; s.length ← s.length - 2};
Backspace => {DeletePutChar[]; s.length ← s.length - 2};
Accented => {DeletePutChar[]; s.length ← s.length - 2};
ENDCASE => NULL
END
ELSE {DeletePutChar[]; s.length ← s.length - 1};
END;
DeleteWord: PROCEDURE = BEGIN
IF s.length # 0 THEN DeleteChar[];
WHILE s.length # 0
AND
(SELECT s.bytes[s.length - 1] FROM
IN TTYExtras.lowerAlpha, IN TTYExtras.upperAlpha, IN
TTYExtras.numbers, IN TTYExtras.accents => TRUE,
ENDCASE => FALSE) DO DeleteChar[] ENDLOOP;
END;
DeleteInput: PROCEDURE = INLINE
BEGIN WHILE s.length # 0 DO DeleteChar ENDLOOP END;
IF s.length > 0 THEN
SELECT h.echo -- equivalent to "TTY.GetEcho[h]" -- FROM
plain => NSPutString[h, s­];
stars => {
FOR i: CARDINAL IN [1..s­.length] DO
PutISOChar[h, TTYExtras.star]; ENDLOOP};
none => NULL;
ENDCASE;
DO
c ← NSGetChar[h];
SELECT c.code FROM
Ascii.ControlC.ORD => SIGNAL TTY.Rubout;
TTYExtras.bs, TTYExtras.DEL => DeleteChar[];
TTYExtras.controlW => DeleteWord[];
TTYExtras.controlX => DeleteInput[];
ENDCASE =>
SELECT t[c] FROM
stop => EXIT;
ok => {
IF firstChar THEN DeleteInput[];
IF s.length >= s.maxlength THEN [] ← SIGNAL TTY.LineOverflow[NIL];
s.bytes[s.length] ← c.code;
s.length ← s.length + 1;
EchoChar[c]};
ENDCASE => NULL;
firstChar ← FALSE;
ENDLOOP;
END;
NSPutString: PUBLIC SAFE PROCEDURE [h: Handle, s: NSString.String] = TRUSTED BEGIN
TTY.PutString[h, s];
charSet: BYTE ← 0;
escape: BOOLEANFALSE;
FOR i: CARDINAL IN [0..s.length) DO
IF escape THEN {charSet ← s.bytes[i]; escape ← FALSE; LOOP};
escape ← s.bytes[i] = ESCAPE;
IF NOT escape THEN
NSPutChar[h, NSString.Character[charSet, s.bytes[i]]]
ENDLOOP;
END;
NSPutLine: PUBLIC SAFE PROCEDURE [h: Handle, s: NSString.String] = TRUSTED {
TTY.PutLine[h, s];
IF s.length=0 THEN FeedLine[h]
ELSE {NSPutString[h, s]; SetLinePosition[h, 0]};
};
NSPutChar: PUBLIC SAFE PROCEDURE [h: Handle, c: NSString.Character] = TRUSTED BEGIN
TTY.PutChar[h, LOOPHOLE[c.code]];
byte: NSTranslate.ISOCode;
IF c.chset # 0 THEN
BEGIN
PutISOChar[h, h.dataFile.header.badChar];
RETURN;
END;
IF h.outputState = idle THEN
IF PossibleAccent[c] THEN {h.outputState ← wait; h.outputChar ← c}
ELSE PutISOChar[h, h.dataFile.outputTable[c.code]]
ELSE
BEGIN
accentType: NSTranslate.AccentType;
[byte, accentType] ← Translate[h.outputChar, c, h.dataFile];
h.outputState ← idle;
SELECT accentType FROM
Normal => {
IF PossibleAccent[c] THEN {h.outputState ← wait; h.outputChar ← c}
ELSE {
PutISOChar[h, byte]; PutISOChar[h, h.dataFile.outputTable[c.code]]}};
DeadChar => {
PutISOChar[h, byte]; PutISOChar[h, h.dataFile.outputTable[c.code]]};
Backspace => {
PutISOChar[h, byte];
BackwardClear[h, 1];
PutISOChar[h, h.dataFile.outputTable[c.code]]};
Accented => PutISOChar[h, byte];
ENDCASE => NULL;
END;
END;
PutISOChar: PROCEDURE [h: Handle, ch: NSTranslate.ISOCode] = BEGIN
ENABLE UNWIND => {h.outputState ← idle; h.inputState ← idle};
CheckState[h];
IF h.col = h.width THEN {h.col ← 0; NextLine[h]};
IF ch = 0 THEN ch ← h.dataFile.header.badChar;
SELECT ch FROM
TTYExtras.cr => FeedLine[h];
TTYExtras.ff => NextPage[h];
TTYExtras.lf => NULL;
TTYExtras.bs => BackwardClear[h, 1];
ENDCASE => {
h.col ← h.col + 1;
TTYExtras.PutByte[h, ch];
IF h.col = h.width THEN {h.col ← 0; NextLine[h]}};
END;
PossibleAccent: PROC [nsChar: NSString.Character] RETURNS [BOOLEAN] = INLINE {
RETURN[nsChar.chset = 0 AND nsChar.code IN NSTranslate.AccentRange]};
AccentTypeOf: PROC [nsChar1, nsChar2: NSString.Character, dataFile: NSTranslate.XlateInfo]
RETURNS
[type: NSTranslate.AccentType] = BEGIN
accentP: NSTranslate.AccentPointer ← @dataFile.accentTable[nsChar1.code];
type ← accentP.defaultType;
FOR index: CARDINAL IN [0..NSTranslate.maxEntries) UNTIL
(accentP.accentedChar[index].code = NSTranslate.emptySlot) DO
IF accentP.accentedChar[index].code = nsChar2.code THEN
RETURN[accentP.accentedChar[index].accentedType]
ENDLOOP;
END;
Translate: PROC [nsChar1, nsChar2: NSString.Character, dataFile: NSTranslate.XlateInfo]
RETURNS
[char: NSTranslate.ISOCode, type: NSTranslate.AccentType] = BEGIN
accentP: NSTranslate.AccentPointer ← @dataFile.accentTable[nsChar1.code];
type ← accentP.defaultType;
char ← dataFile.outputTable[nsChar1.code];
FOR index: CARDINAL IN [0..NSTranslate.maxEntries) UNTIL
(accentP.accentedChar[index].code = NSTranslate.emptySlot) DO
IF accentP.accentedChar[index].code = nsChar2.code THEN
IF accentP.accentedChar[index].accentedType = Accented THEN
RETURN[
accentP.accentedChar[index].isoCode, accentP.accentedChar[
index].accentedType]
ELSE
RETURN[
dataFile.outputTable[nsChar1.code], accentP.accentedChar[
index].accentedType];
ENDLOOP;
END;
CheckState: PROCEDURE [h: Handle] = INLINE {
IF h.inputAborted THEN ERROR ABORTED};
Terminal Control Functions
NewPage: PUBLIC SAFE PROCEDURE [h: Handle] = TRUSTED {h.line ← 0};
NextPage: PROCEDURE [h: Handle] = TRUSTED BEGIN h.line ← 0; CarriageReturn[h]; END;
ForwardClear: PROCEDURE [h: Handle, n: CARDINAL] = BEGIN
THROUGH [1..n] WHILE (h.col < h.width) DO
TTYExtras.PutByte[h, TTYExtras.space]; h.col ← h.col + 1 ENDLOOP
END;
BackwardClear: PROCEDURE [h: Handle, n: CARDINAL] = BEGIN
n ← IF n > h.col THEN h.col ELSE n;
h.col ← h.col - n;
TTY.RemoveCharacter[h, n];
END;
NextLine: PROCEDURE [h: Handle] = BEGIN
SELECT TRUE FROM
h.line + 1 = h.pageLength => BEGIN
NSPutString[h, M[TextInputMessages.Key[keyMore]]];
IF TTYExtras.GetByte[h] =
Ascii.ControlC.ORD THEN {NextPage[h]; SIGNAL TTY.Rubout}
ELSE NextPage[h];
END;
h.pageLength = 0 => RETURN;
ENDCASE => h.line ← h.line + 1;
END;
Get7BitByte: PROC [h: Handle] RETURNS [c: BYTE] = {
RETURN[Basics.BITAND[TTYExtras.GetByte[h], 177B]]};
M: PROC [key: TextInputMessages.Key] RETURNS [str: NSString.String] = {
r: XString.ReaderBody ← XMessage.Get[SCSMsgs.MsgHandle[textInput], key.ORD];
str ← [bytes: LOOPHOLE[r.bytes], length: r.limit, maxlength: r.limit]};
CarriageReturn: PROCEDURE [h: Handle] =
BEGIN TTYExtras.PutByte[h, TTYExtras.cr]; h.col ← 0 END;
FeedLine: PROCEDURE [h: Handle] = BEGIN CarriageReturn[h]; NextLine[h]; END;
SetLinePosition: PUBLIC SAFE PROCEDURE [h: Handle, position: CARDINAL] = TRUSTED {
IF position >= h.col THEN ForwardClear[h, position - h.col]
ELSE {FeedLine[h]; ForwardClear[h, position]}};
Terminal Configuration
SetDataFile: PUBLIC PROCEDURE [h: Handle, d: NSTranslate.XlateInfo] =
BEGIN h.dataFile ← d END;
SetLineWidth: PUBLIC SAFE PROCEDURE [h: Handle, n: CARDINAL] = TRUSTED {h.width ← n};
SetPagination: PUBLIC ENTRY SAFE PROCEDURE [h: Handle, pageLength: CARDINAL]
RETURNS
[oldPageLength: CARDINAL] = TRUSTED {
oldPageLength ← h.pageLength; h.pageLength ← pageLength};
[] ← NSTranslate.LoadTables[sneak];
END.
LOG
9-Nov-83 16:19:04 - Alfvin - Created.
15-Nov-83 11:52:41 - Saund - Execute now passes the default string as argument to plug in proc.
30-Nov-83 20:36:37 - Saund - Added Put*
20-Jan-84 13:59:37 - Saund - PutString = TTYExtras.PutNSString.
23-Jan-84 13:59:32 - Saund - Implemented SetLinePosition and SetPagination.
5-Apr-84 18:03:00 - Wu - A clean Start
24-Apr-84 15:03:05 - Alfvin - Removed LOOPHOLES, eliminated superfluous MONITOR
25-Apr-84 15:28:50 - Alfvin - Fix screwup in last edit
11-May-84 13:18:19 - Knguyen - Fix AR#7364: TextInput: GetText no default as stars when echoStars=TRUE. Fix is in proc. NSGetEditedString
16-May-84 0:04:14 - Alfvin - Don't maintain newline at all because it was not being maintained properly.
21-May-84 15:31:06 - KNguyen - Fix proc. NextLine for Saund. This causes the Async. msgs to no longer display the "(More)" prompt.
31-May-84 1:20:07 - Saund - Fix Ars 8200 and 8100: No more CTL C at (More) and (More) multinationalized.
7-Jun-84 20:04:21 - Alfvin - Truncate to 7 bit chars in NSGetChar.
8-Jun-84 11:02:24 - Saund - Put the check for CTRL C back in NextLine:
18-Jun-84 16:21:11 - Saund - Remove insertion of CRLF in 80 col lines.
25-Jun-84 15:15:41 - Saund - NSPutLine does a SetLinePosition[] instead of FeedLine
1-Aug-84 14:24:25 - Saund - Fix AR: 10321 NSTTY: Non-CharSet0 chars are displayed as character set 0.
9-May-85 13:42:16 - McManis - Changed SetPagination to return oldPageLength (like old NSTTYExtras.NewSetPagination).
4-Jun-85 17:32:20 - McManis - Converted to XMessage. This dependency should be removed ASAP.
21-Aug-85 8:42:34 - McManis - Replaced SCSMsgDomains with SCSMsgs.