ttysize.mod 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. MODULE ttysize;
  2. (* Quick check of the tvtty libc binding: raw mode, terminal size, timed read. *)
  3. FROM SYSTEM IMPORT ADDRESS, ADR, ADDADR, CAST, BYTE;
  4. FROM tvtty IMPORT tcgetattr, tcsetattr, ioctl, read, write;
  5. FROM InOut IMPORT WriteString, WriteLn, WriteInt;
  6. FROM Delay IMPORT Delay;
  7. TYPE BytePtr = POINTER TO BYTE;
  8. CONST
  9. ICANON = 2; ECHO = 8; ISIG = 1; IEXTEN = 32768;
  10. ICRNL = 256; IXON = 1024;
  11. TCSAFLUSH = 2; TIOCGWINSZ = 5413H;
  12. VAR
  13. t : ARRAY [0..63] OF BYTE;
  14. ws : ARRAY [0..7] OF BYTE;
  15. rc : INTEGER;
  16. PROCEDURE GetDWord(p : ADDRESS; off : INTEGER) : CARDINAL;
  17. VAR q : BytePtr; v : CARDINAL;
  18. BEGIN
  19. q := CAST(BytePtr, ADDADR(p, off));
  20. v := VAL(CARDINAL, q^);
  21. q := CAST(BytePtr, ADDADR(q, 1)); v := v + VAL(CARDINAL, q^) * 256;
  22. q := CAST(BytePtr, ADDADR(q, 1)); v := v + VAL(CARDINAL, q^) * 65536;
  23. q := CAST(BytePtr, ADDADR(q, 1)); v := v + VAL(CARDINAL, q^) * 16777216;
  24. RETURN v
  25. END GetDWord;
  26. PROCEDURE PutDWord(p : ADDRESS; off : INTEGER; v : CARDINAL);
  27. VAR q : BytePtr; x : CARDINAL;
  28. BEGIN
  29. x := v;
  30. q := CAST(BytePtr, ADDADR(p, off)); q^ := VAL(BYTE, x MOD 256); x := x DIV 256;
  31. q := CAST(BytePtr, ADDADR(q, 1)); q^ := VAL(BYTE, x MOD 256); x := x DIV 256;
  32. q := CAST(BytePtr, ADDADR(q, 1)); q^ := VAL(BYTE, x MOD 256); x := x DIV 256;
  33. q := CAST(BytePtr, ADDADR(q, 1)); q^ := VAL(BYTE, x MOD 256)
  34. END PutDWord;
  35. PROCEDURE Raw;
  36. VAR lf, iff : CARDINAL;
  37. BEGIN
  38. rc := tcgetattr(0, ADR(t));
  39. lf := GetDWord(ADR(t), 12);
  40. lf := VAL(CARDINAL, CAST(BITSET, lf) * CAST(BITSET, MAX(CARDINAL) - (ICANON + ECHO + ISIG + IEXTEN)));
  41. PutDWord(ADR(t), 12, lf);
  42. iff := GetDWord(ADR(t), 0);
  43. iff := VAL(CARDINAL, CAST(BITSET, iff) * CAST(BITSET, MAX(CARDINAL) - (ICRNL + IXON)));
  44. PutDWord(ADR(t), 0, iff);
  45. t[17 + 6] := 0; (* VMIN = 0 *)
  46. t[17 + 5] := 1; (* VTIME = 1 (0.1 s) *)
  47. rc := tcsetattr(0, TCSAFLUSH, ADR(t))
  48. END Raw;
  49. PROCEDURE Restore;
  50. BEGIN
  51. rc := tcsetattr(0, TCSAFLUSH, ADR(t))
  52. END Restore;
  53. VAR
  54. rows, cols, tries : INTEGER;
  55. buf : ARRAY [0..31] OF CHAR;
  56. b : CARDINAL;
  57. found : BOOLEAN;
  58. BEGIN
  59. WriteString("tcgetattr rc="); WriteInt(rc, 0); WriteLn;
  60. Raw;
  61. IF ioctl(1, TIOCGWINSZ, ADR(ws)) = 0 THEN
  62. rows := VAL(INTEGER, ws[0]) + VAL(INTEGER, ws[1]) * 256;
  63. cols := VAL(INTEGER, ws[2]) + VAL(INTEGER, ws[3]) * 256
  64. ELSE
  65. rows := 24; cols := 80
  66. END;
  67. WriteString("size="); WriteInt(rows, 0); WriteString("x"); WriteInt(cols, 0); WriteLn;
  68. WriteString("waiting 2s for a key (press one): ");
  69. found := FALSE;
  70. tries := 0;
  71. WHILE (NOT found) AND (tries < 20) DO
  72. rc := read(0, ADR(buf), 1);
  73. IF rc > 0 THEN
  74. b := VAL(CARDINAL, ORD(buf[0]));
  75. WriteString("got byte "); WriteInt(VAL(INTEGER, b), 0); WriteLn;
  76. found := TRUE
  77. ELSE
  78. tries := tries + 1;
  79. Delay(1)
  80. END
  81. END;
  82. IF NOT found THEN WriteString("no key"); WriteLn END;
  83. Restore;
  84. WriteString("restored"); WriteLn
  85. END ttysize.