IMPLEMENTATION MODULE VT100; IMPORT ASCII; FROM STextIO IMPORT WriteString, WriteChar; FROM NumberIO IMPORT WriteCard; IMPORT IO, termios, FIO; VAR savedTerm : termios.TERMIOS; flushFlag : INTEGER; haveTerm : BOOLEAN; (* helper: ESC [ *) PROCEDURE CSI; BEGIN WriteChar(ASCII.esc); WriteChar("["); END CSI; PROCEDURE CSIPriv; (* ESC [ ? *) BEGIN WriteChar(ASCII.esc); WriteString("[?"); END CSIPriv; (* SGR *) PROCEDURE ResetAttributes; BEGIN CSI; WriteString("0m"); END ResetAttributes; PROCEDURE Bold; BEGIN CSI; WriteString("1m"); END Bold; PROCEDURE Underline; BEGIN CSI; WriteString("4m"); END Underline; PROCEDURE Blink; BEGIN CSI; WriteString("5m"); END Blink; PROCEDURE Reverse; BEGIN CSI; WriteString("7m"); END Reverse; (* Cursor *) PROCEDURE CursorHome; BEGIN CSI; WriteChar("H"); END CursorHome; PROCEDURE CursorPosition(line, col : CARDINAL); BEGIN CSI; WriteCard(line, 1); WriteChar(";"); WriteCard(col, 1); WriteChar("H"); END CursorPosition; PROCEDURE HVPosition(line, col : CARDINAL); BEGIN CSI; WriteCard(line, 1); WriteChar(";"); WriteCard(col, 1); WriteChar("f"); END HVPosition; PROCEDURE CursorUp(n : CARDINAL); BEGIN CSI; WriteCard(n, 1); WriteChar("A"); END CursorUp; PROCEDURE CursorDown(n : CARDINAL); BEGIN CSI; WriteCard(n, 1); WriteChar("B"); END CursorDown; PROCEDURE CursorRight(n : CARDINAL); BEGIN CSI; WriteCard(n, 1); WriteChar("C"); END CursorRight; PROCEDURE CursorLeft(n : CARDINAL); BEGIN CSI; WriteCard(n, 1); WriteChar("D"); END CursorLeft; PROCEDURE Index; BEGIN WriteChar(ASCII.esc); WriteChar("D"); END Index; PROCEDURE ReverseIndex; BEGIN WriteChar(ASCII.esc); WriteChar("M"); END ReverseIndex; PROCEDURE NextLine; BEGIN WriteChar(ASCII.esc); WriteChar("E"); END NextLine; PROCEDURE SaveCursor; BEGIN WriteChar(ASCII.esc); WriteChar("7"); END SaveCursor; PROCEDURE RestoreCursor; BEGIN WriteChar(ASCII.esc); WriteChar("8"); END RestoreCursor; (* Erase *) PROCEDURE ClearLineRight; BEGIN CSI; WriteChar("K"); END ClearLineRight; PROCEDURE ClearLineLeft; BEGIN CSI; WriteString("1K"); END ClearLineLeft; PROCEDURE ClearLine; BEGIN CSI; WriteString("2K"); END ClearLine; PROCEDURE ClearScreenDown; BEGIN CSI; WriteChar("J"); END ClearScreenDown; PROCEDURE ClearScreenUp; BEGIN CSI; WriteString("1J"); END ClearScreenUp; PROCEDURE ClearScreen; BEGIN CSI; WriteString("2J"); END ClearScreen; PROCEDURE SetScrollRegion(top, bottom : CARDINAL); BEGIN CSI; WriteCard(top, 1); WriteChar(";"); WriteCard(bottom, 1); WriteChar("r"); END SetScrollRegion; (* Tabs *) PROCEDURE TabSet; BEGIN WriteChar(ASCII.esc); WriteChar("H"); END TabSet; PROCEDURE TabClear; BEGIN CSI; WriteChar("g"); END TabClear; PROCEDURE TabClearAll; BEGIN CSI; WriteString("3g"); END TabClearAll; (* Double-size / alignment *) PROCEDURE DoubleHeightTop; BEGIN WriteChar(ASCII.esc); WriteString("#3"); END DoubleHeightTop; PROCEDURE DoubleHeightBottom; BEGIN WriteChar(ASCII.esc); WriteString("#4"); END DoubleHeightBottom; PROCEDURE SingleWidth; BEGIN WriteChar(ASCII.esc); WriteString("#5"); END SingleWidth; PROCEDURE DoubleWidth; BEGIN WriteChar(ASCII.esc); WriteString("#6"); END DoubleWidth; PROCEDURE ScreenAlign; BEGIN WriteChar(ASCII.esc); WriteString("#8"); END ScreenAlign; (* Modes *) PROCEDURE SetNewLine; BEGIN CSI; WriteString("20h"); END SetNewLine; PROCEDURE ResetNewLine; BEGIN CSI; WriteString("20l"); END ResetNewLine; PROCEDURE SetAppCursorKeys; BEGIN CSIPriv; WriteString("1h"); END SetAppCursorKeys; PROCEDURE SetCursorKeys; BEGIN CSIPriv; WriteString("1l"); END SetCursorKeys; PROCEDURE SetANSI; BEGIN CSIPriv; WriteString("2h"); END SetANSI; PROCEDURE SetVT52; BEGIN CSIPriv; WriteString("2l"); END SetVT52; PROCEDURE Set132Columns; BEGIN CSIPriv; WriteString("3h"); END Set132Columns; PROCEDURE Set80Columns; BEGIN CSIPriv; WriteString("3l"); END Set80Columns; PROCEDURE SetSmoothScroll; BEGIN CSIPriv; WriteString("4h"); END SetSmoothScroll; PROCEDURE SetJumpScroll; BEGIN CSIPriv; WriteString("4l"); END SetJumpScroll; PROCEDURE SetReverseScreen; BEGIN CSIPriv; WriteString("5h"); END SetReverseScreen; PROCEDURE SetNormalScreen; BEGIN CSIPriv; WriteString("5l"); END SetNormalScreen; PROCEDURE SetRelativeOrigin; BEGIN CSIPriv; WriteString("6h"); END SetRelativeOrigin; PROCEDURE SetAbsoluteOrigin; BEGIN CSIPriv; WriteString("6l"); END SetAbsoluteOrigin; PROCEDURE SetAutoWrap; BEGIN CSIPriv; WriteString("7h"); END SetAutoWrap; PROCEDURE ResetAutoWrap; BEGIN CSIPriv; WriteString("7l"); END ResetAutoWrap; PROCEDURE SetAutoRepeat; BEGIN CSIPriv; WriteString("8h"); END SetAutoRepeat; PROCEDURE ResetAutoRepeat; BEGIN CSIPriv; WriteString("8l"); END ResetAutoRepeat; PROCEDURE SetInterlace; BEGIN CSIPriv; WriteString("9h"); END SetInterlace; PROCEDURE ResetInterlace; BEGIN CSIPriv; WriteString("9l"); END ResetInterlace; (* Keypad *) PROCEDURE SetAltKeypad; BEGIN WriteChar(ASCII.esc); WriteChar("="); END SetAltKeypad; PROCEDURE SetNumKeypad; BEGIN WriteChar(ASCII.esc); WriteChar(">"); END SetNumKeypad; (* Charsets *) PROCEDURE SetUK_G0; BEGIN WriteChar(ASCII.esc); WriteString("(A"); END SetUK_G0; PROCEDURE SetUS_G0; BEGIN WriteChar(ASCII.esc); WriteString("(B"); END SetUS_G0; PROCEDURE SetGraphics_G0; BEGIN WriteChar(ASCII.esc); WriteString("(0"); END SetGraphics_G0; PROCEDURE SetAlt_G0; BEGIN WriteChar(ASCII.esc); WriteString("(1"); END SetAlt_G0; PROCEDURE SetAltGraph_G0; BEGIN WriteChar(ASCII.esc); WriteString("(2"); END SetAltGraph_G0; PROCEDURE SetUK_G1; BEGIN WriteChar(ASCII.esc); WriteString(")A"); END SetUK_G1; PROCEDURE SetUS_G1; BEGIN WriteChar(ASCII.esc); WriteString(")B"); END SetUS_G1; PROCEDURE SetGraphics_G1; BEGIN WriteChar(ASCII.esc); WriteString(")0"); END SetGraphics_G1; PROCEDURE SetAlt_G1; BEGIN WriteChar(ASCII.esc); WriteString(")1"); END SetAlt_G1; PROCEDURE SetAltGraph_G1; BEGIN WriteChar(ASCII.esc); WriteString(")2"); END SetAltGraph_G1; PROCEDURE Shift2; BEGIN WriteChar(ASCII.esc); WriteChar("N"); END Shift2; PROCEDURE Shift3; BEGIN WriteChar(ASCII.esc); WriteChar("O"); END Shift3; (* Reports / reset *) PROCEDURE RequestDeviceStatus; BEGIN CSI; WriteString("5n"); END RequestDeviceStatus; PROCEDURE RequestCursorPosition; BEGIN CSI; WriteString("6n"); END RequestCursorPosition; PROCEDURE Identify; BEGIN CSI; WriteChar("c"); END Identify; PROCEDURE Identify2; BEGIN CSI; WriteString("0c"); END Identify2; PROCEDURE ResetTerminal; BEGIN WriteChar(ASCII.esc); WriteChar("c"); END ResetTerminal; (* LEDs / tests *) PROCEDURE LedsOff; BEGIN CSI; WriteString("0q"); END LedsOff; PROCEDURE Led1; BEGIN CSI; WriteString("1q"); END Led1; PROCEDURE Led2; BEGIN CSI; WriteString("2q"); END Led2; PROCEDURE Led3; BEGIN CSI; WriteString("3q"); END Led3; PROCEDURE Led4; BEGIN CSI; WriteString("4q"); END Led4; PROCEDURE TestPowerUp; BEGIN CSI; WriteString("2;1y"); END TestPowerUp; PROCEDURE TestLoopback; BEGIN CSI; WriteString("2;2y"); END TestLoopback; PROCEDURE TestPowerRepeat; BEGIN CSI; WriteString("2;9y"); END TestPowerRepeat; PROCEDURE TestLoopRepeat; BEGIN CSI; WriteString("2;10y"); END TestLoopRepeat; (* Terminal input mode (cf. Editor/Tests/T17.mod): Unbuffered saves the termios state and disables line buffering so device replies can be read char by char; Buffered restores it. *) PROCEDURE Unbuffered; BEGIN flushFlag := termios.tcsflush(); savedTerm := termios.InitTermios(); haveTerm := termios.tcgetattr(FIO.StdIn, savedTerm) # -1; IO.UnBufferedMode(0, TRUE); IO.UnBufferedMode(1, TRUE); END Unbuffered; PROCEDURE Buffered; VAR res : INTEGER; BEGIN IO.BufferedMode(0, TRUE); IO.BufferedMode(1, TRUE); IF haveTerm THEN haveTerm := FALSE; res := termios.tcsetattr(FIO.StdIn, flushFlag, savedTerm); END; END Buffered; END VT100.