MODULE ttysize; (* Quick check of the tvtty libc binding: raw mode, terminal size, timed read. *) FROM SYSTEM IMPORT ADDRESS, ADR, ADDADR, CAST, BYTE; FROM tvtty IMPORT tcgetattr, tcsetattr, ioctl, read, write; FROM InOut IMPORT WriteString, WriteLn, WriteInt; FROM Delay IMPORT Delay; TYPE BytePtr = POINTER TO BYTE; CONST ICANON = 2; ECHO = 8; ISIG = 1; IEXTEN = 32768; ICRNL = 256; IXON = 1024; TCSAFLUSH = 2; TIOCGWINSZ = 5413H; VAR t : ARRAY [0..63] OF BYTE; ws : ARRAY [0..7] OF BYTE; rc : INTEGER; PROCEDURE GetDWord(p : ADDRESS; off : INTEGER) : CARDINAL; VAR q : BytePtr; v : CARDINAL; BEGIN q := CAST(BytePtr, ADDADR(p, off)); v := VAL(CARDINAL, q^); q := CAST(BytePtr, ADDADR(q, 1)); v := v + VAL(CARDINAL, q^) * 256; q := CAST(BytePtr, ADDADR(q, 1)); v := v + VAL(CARDINAL, q^) * 65536; q := CAST(BytePtr, ADDADR(q, 1)); v := v + VAL(CARDINAL, q^) * 16777216; RETURN v END GetDWord; PROCEDURE PutDWord(p : ADDRESS; off : INTEGER; v : CARDINAL); VAR q : BytePtr; x : CARDINAL; BEGIN x := v; q := CAST(BytePtr, ADDADR(p, off)); q^ := VAL(BYTE, x MOD 256); x := x DIV 256; q := CAST(BytePtr, ADDADR(q, 1)); q^ := VAL(BYTE, x MOD 256); x := x DIV 256; q := CAST(BytePtr, ADDADR(q, 1)); q^ := VAL(BYTE, x MOD 256); x := x DIV 256; q := CAST(BytePtr, ADDADR(q, 1)); q^ := VAL(BYTE, x MOD 256) END PutDWord; PROCEDURE Raw; VAR lf, iff : CARDINAL; BEGIN rc := tcgetattr(0, ADR(t)); lf := GetDWord(ADR(t), 12); lf := VAL(CARDINAL, CAST(BITSET, lf) * CAST(BITSET, MAX(CARDINAL) - (ICANON + ECHO + ISIG + IEXTEN))); PutDWord(ADR(t), 12, lf); iff := GetDWord(ADR(t), 0); iff := VAL(CARDINAL, CAST(BITSET, iff) * CAST(BITSET, MAX(CARDINAL) - (ICRNL + IXON))); PutDWord(ADR(t), 0, iff); t[17 + 6] := 0; (* VMIN = 0 *) t[17 + 5] := 1; (* VTIME = 1 (0.1 s) *) rc := tcsetattr(0, TCSAFLUSH, ADR(t)) END Raw; PROCEDURE Restore; BEGIN rc := tcsetattr(0, TCSAFLUSH, ADR(t)) END Restore; VAR rows, cols, tries : INTEGER; buf : ARRAY [0..31] OF CHAR; b : CARDINAL; found : BOOLEAN; BEGIN WriteString("tcgetattr rc="); WriteInt(rc, 0); WriteLn; Raw; IF ioctl(1, TIOCGWINSZ, ADR(ws)) = 0 THEN rows := VAL(INTEGER, ws[0]) + VAL(INTEGER, ws[1]) * 256; cols := VAL(INTEGER, ws[2]) + VAL(INTEGER, ws[3]) * 256 ELSE rows := 24; cols := 80 END; WriteString("size="); WriteInt(rows, 0); WriteString("x"); WriteInt(cols, 0); WriteLn; WriteString("waiting 2s for a key (press one): "); found := FALSE; tries := 0; WHILE (NOT found) AND (tries < 20) DO rc := read(0, ADR(buf), 1); IF rc > 0 THEN b := VAL(CARDINAL, ORD(buf[0])); WriteString("got byte "); WriteInt(VAL(INTEGER, b), 0); WriteLn; found := TRUE ELSE tries := tries + 1; Delay(1) END END; IF NOT found THEN WriteString("no key"); WriteLn END; Restore; WriteString("restored"); WriteLn END ttysize.