docs: sync .org with implementation for backend-size, read-raw-byte, SIGWINCH

backend-protocol.org / simple.lisp:
- Replace hard-coded 80x24 prose with full 5-step fallback chain
  (MY_TERM env vars → ioctl fd 0 → ioctl stdout → /dev/tty → 80x24)
- Document return-from pattern (or discards secondary values)

modern-backend.org / modern.lisp:
- Replace simple ioctl-only prose with 4-step fallback chain
- Document env-var pre-check and /dev/tty fallback

text-input.org / input.lisp:
- Update read-raw-byte prose: with-pinned-objects/vector-sap
  instead of alien buffer (code was already correct, prose stale)
- Add missing (require :sb-posix) to SIGWINCH handler code block
- Document :sb-posix requirement in prose
This commit is contained in:
2026-05-14 16:25:45 -04:00
parent b44b4b6aa0
commit 916f473107
6 changed files with 138 additions and 47 deletions

View File

@@ -642,27 +642,58 @@ is responsible for redrawing the full screen after resume.
(values))
#+END_SRC
** Backend-size via ioctl
** Backend-size via ioctl and env vars
*** backend-size
Uses TIOCGWINSZ (=0x5413= = 21523) to query actual terminal dimensions
from the kernel via =ioctl=. The =alien-sap= wrapper ensures
compatibility across SBCL versions. Returns (values cols rows).
Uses a fallback chain to determine terminal dimensions:
1. **Env var pre-check** — ~MY_TERM_COLS~ / ~MY_TERM_ROWS~, set by
the calling script before ~exec sbcl~. Uses ~return-from~ to preserve
both values (~or~ discards secondary values).
2. **ioctl on stdout** — fast, correct after SIGWINCH at runtime.
3. **ioctl on ~/dev/tty~** — fallback when stdout is not a terminal.
4. **~(values 80 24)~** — last resort.
#+BEGIN_SRC lisp :tangle ../src/backend/modern.lisp
(defmethod backend-size ((b modern-backend))
(or (ignore-errors
(let* ((+tiocgwinsz+ 21523) ; 0x5413 on Linux
(winsize (sb-alien:make-alien sb-alien:unsigned-short 4)))
(unwind-protect
(progn
(sb-unix:unix-ioctl (sb-sys:fd-stream-fd (backend-output-stream b))
+tiocgwinsz+
(sb-alien:alien-sap winsize))
(values (sb-alien:deref winsize 1) ;; cols
(sb-alien:deref winsize 0))) ;; rows
(sb-alien:free-alien winsize))))
;; MY_TERM_COLS/MY_TERM_ROWS — set by the calling script.
;; Check FIRST with return-from so both values (cols and rows)
;; are preserved (or discards secondaries).
(let ((cstr (sb-ext:posix-getenv "MY_TERM_COLS"))
(rstr (sb-ext:posix-getenv "MY_TERM_ROWS")))
(when (and cstr rstr)
(let ((cols (parse-integer cstr :junk-allowed t))
(rows (parse-integer rstr :junk-allowed t)))
(when (and cols rows (> cols 0) (> rows 0))
(return-from backend-size (values cols rows))))))
(or
(multiple-value-bind (cols rows)
(ignore-errors
(let* ((winsize (sb-alien:make-alien sb-alien:unsigned-short 4)))
(unwind-protect
(let ((ok (sb-unix:unix-ioctl
(sb-sys:fd-stream-fd (backend-output-stream b))
21523 (sb-alien:alien-sap winsize))))
(when ok
(values (sb-alien:deref winsize 1) ;; cols
(sb-alien:deref winsize 0)))) ;; rows
(sb-alien:free-alien winsize))))
(when (and cols rows (> cols 0) (> rows 0))
(values cols rows)))
;; Direct ioctl on /dev/tty.
(ignore-errors
(let ((tty-fd (sb-unix:unix-open "/dev/tty" 0 0)))
(when (and tty-fd (numberp tty-fd) (> tty-fd 0))
(unwind-protect
(let* ((winsize (sb-alien:make-alien sb-alien:unsigned-short 4)))
(let ((ok (sb-unix:unix-ioctl tty-fd 21523
(sb-alien:alien-sap winsize))))
(when ok
(let ((cols (sb-alien:deref winsize 1))
(rows (sb-alien:deref winsize 0)))
(values cols rows)))))
(sb-unix:unix-close tty-fd)))))
(values 80 24)))
#+END_SRC