Initial revision
authorChris Hanson <org/chris-hanson/cph>
Fri, 2 Nov 1990 04:16:38 +0000 (04:16 +0000)
committerChris Hanson <org/chris-hanson/cph>
Fri, 2 Nov 1990 04:16:38 +0000 (04:16 +0000)
v7/src/edwin/termcap.scm [new file with mode: 0644]
v7/src/edwin/tterm.scm [new file with mode: 0644]

diff --git a/v7/src/edwin/termcap.scm b/v7/src/edwin/termcap.scm
new file mode 100644 (file)
index 0000000..738ee94
--- /dev/null
@@ -0,0 +1,271 @@
+#| -*-Scheme-*-
+
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/termcap.scm,v 1.1 1990/11/02 04:16:24 cph Rel $
+
+Copyright (c) 1990 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science.  Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. |#
+
+;;;; Termcap(3) Interface
+
+(declare (usual-integrations))
+
+(define-primitives
+  (termcap-initialize 1)
+  (termcap-get-number 1)
+  (termcap-get-flag 1)
+  (termcap-get-string 1)
+  (termcap-param-string 5)
+  (termcap-goto-string 5)
+  (termcap-pad-string 4))
+\f
+(define-structure (termcap-description
+                  (constructor %make-termcap-description)
+                  (conc-name false))
+  (terminal-type-name false read-only true)
+
+  (delete-is-insert-mode? false read-only true)
+  (enter/exit-standout-mode-same? false read-only true)
+  (insert/delete-char-ok? false read-only true)
+  (insert/delete-line-ok? false read-only true)
+  (scroll-region-ok? false read-only true)
+
+  (tf-automatic-wrap false read-only true)
+  (tf-cursor-backwards-wrap false read-only true)
+  (tf-generic false read-only true)
+  (tf-hardcopy false read-only true)
+  (tf-hazeltine false read-only true)
+  (tf-insert-mode-motion false read-only true)
+  (tf-lose-wrap false read-only true)
+  (tf-magic-wrap false read-only true)
+  (tf-memory-above-screen false read-only true)
+  (tf-memory-below-screen false read-only true)
+  (tf-meta-key false read-only true)
+  (tf-must-write-spaces false read-only true)
+  (tf-newline-doesnt-scroll false read-only true)
+  (tf-overstrike false read-only true)
+  (tf-overstrike-space-erase false read-only true)
+  (tf-overwrite-preserves-standout false read-only true)
+  (tf-standout-mode-motion false read-only true)
+  (tf-teleray false read-only true)
+  (tf-underscore false read-only true)
+
+  (tn-memory-lines false read-only true)
+  (tn-minimum-padding-speed false read-only true)
+  (tn-standout-marker-width false read-only true)
+  (tn-x-size false read-only true)
+  (tn-y-size false read-only true)
+
+  (ts-audible-bell false read-only true)
+  (ts-clear-line false read-only true)
+  (ts-clear-multi-char false read-only true)
+  (ts-clear-screen false read-only true)
+  (ts-clear-to-bottom false read-only true)
+  (ts-cursor-down false read-only true)
+  (ts-cursor-down-multi false read-only true)
+  (ts-cursor-left false read-only true)
+  (ts-cursor-left-multi false read-only true)
+  (ts-cursor-line-start false read-only true)
+  (ts-cursor-lower-left false read-only true)
+  (ts-cursor-move false read-only true)
+  (ts-cursor-move-x false read-only true)
+  (ts-cursor-right false read-only true)
+  (ts-cursor-right-multi false read-only true)
+  (ts-cursor-up false read-only true)
+  (ts-cursor-up-multi false read-only true)
+  (ts-cursor-upper-left false read-only true)
+  (ts-delete-char false read-only true)
+  (ts-delete-line false read-only true)
+  (ts-delete-multi-char false read-only true)
+  (ts-delete-multi-line false read-only true)
+  (ts-enhance-cursor false read-only true)
+  (ts-enter-delete-mode false read-only true)
+  (ts-enter-insert-mode false read-only true)
+  (ts-enter-standout-mode false read-only true)
+  (ts-enter-termcap-mode false read-only true)
+  (ts-exit-delete-mode false read-only true)
+  (ts-exit-insert-mode false read-only true)
+  (ts-exit-standout-mode false read-only true)
+  (ts-exit-termcap-mode false read-only true)
+  (ts-forward-scroll false read-only true)
+  (ts-forward-scroll-multi false read-only true)
+  (ts-insert-char false read-only true)
+  (ts-insert-line false read-only true)
+  (ts-insert-multi-char false read-only true)
+  (ts-insert-multi-line false read-only true)
+  (ts-invisible-cursor false read-only true)
+  (ts-normal-cursor false read-only true)
+  (ts-pad-char false read-only true)
+  (ts-pad-inserted-char false read-only true)
+  (ts-reverse-scroll false read-only true)
+  (ts-reverse-scroll-multi false read-only true)
+  (ts-set-scroll-region false read-only true)
+  (ts-set-scroll-region-1 false read-only true)
+  (ts-set-window false read-only true)
+  (ts-visible-bell false read-only true))
+\f
+(define (make-termcap-description terminal-type-name)
+  (and (termcap-initialize terminal-type-name)
+       (let ((supdup? (string=? terminal-type-name "supdup"))
+            (tn-standout-marker-width (termcap-get-number "sg"))
+            (ts-cursor-down
+             (or (termcap-get-string "do") (termcap-get-string "nl")))
+            (ts-delete-char (termcap-get-string "dc"))
+            (ts-delete-line (termcap-get-string "dl"))
+            (ts-delete-multi-char (termcap-get-string "DC"))
+            (ts-delete-multi-line (termcap-get-string "DL"))
+            (ts-enter-delete-mode (termcap-get-string "dm"))
+            (ts-enter-insert-mode (termcap-get-string "im"))
+            (ts-enter-standout-mode (termcap-get-string "so"))
+            (ts-exit-standout-mode (termcap-get-string "se"))
+            (ts-forward-scroll (termcap-get-string "sf"))
+            (ts-forward-scroll-multi (termcap-get-string "SF"))
+            (ts-insert-char (termcap-get-string "ic"))
+            (ts-insert-line (termcap-get-string "al"))
+            (ts-insert-multi-char (termcap-get-string "IC"))
+            (ts-insert-multi-line (termcap-get-string "AL"))
+            (ts-pad-inserted-char (termcap-get-string "ip"))
+            (ts-reverse-scroll (termcap-get-string "sr"))
+            (ts-reverse-scroll-multi (termcap-get-string "SR"))
+            (ts-set-scroll-region (termcap-get-string "cs"))
+            (ts-set-scroll-region-1 (termcap-get-string "cS"))
+            (ts-set-window (termcap-get-string "wi")))
+        (if (not ts-forward-scroll)
+            (set! ts-forward-scroll ts-cursor-down))
+        (if (not ts-enter-standout-mode)
+            (begin
+              (set! tn-standout-marker-width (termcap-get-number "ug"))
+              (set! ts-enter-standout-mode (termcap-get-string "us"))
+              (set! ts-exit-standout-mode (termcap-get-string "ue"))))
+        (%make-termcap-description
+         terminal-type-name
+
+         ;; delete-is-insert-mode?
+         (and ts-enter-delete-mode
+              ts-enter-insert-mode
+              (string=? ts-enter-delete-mode ts-enter-insert-mode))
+         ;; enter/exit-standout-mode-same?
+         (and ts-enter-standout-mode
+              ts-exit-standout-mode
+              (string=? ts-enter-standout-mode ts-exit-standout-mode))
+         ;; insert/delete-char-ok?
+         (and (or ts-insert-char ts-insert-multi-char
+                  ts-enter-insert-mode ts-pad-inserted-char)
+              (or ts-delete-char ts-delete-multi-char))
+         ;; insert/delete-line-ok?
+         (or (and (or ts-insert-line ts-insert-multi-line)
+                  (or ts-delete-line ts-delete-multi-line))
+             (and (or ts-set-scroll-region
+                      ts-set-scroll-region-1
+                      ts-set-window)
+                  (or ts-forward-scroll ts-forward-scroll-multi)
+                  (or ts-reverse-scroll ts-reverse-scroll-multi)))
+         ;; scroll-region-ok?
+         (or ts-set-scroll-region ts-set-scroll-region-1 ts-set-window)
+
+         (termcap-get-flag "am")       ;tf-automatic-wrap
+         (termcap-get-flag "bw")       ;tf-cursor-backwards-wrap
+         (termcap-get-flag "gn")       ;tf-generic
+         (termcap-get-flag "hc")       ;tf-hardcopy
+         (termcap-get-flag "hz")       ;tf-hazeltine
+         (termcap-get-flag "mi")       ;tf-insert-mode-motion
+         supdup?                       ;tf-lose-wrap
+         (termcap-get-flag "xn")       ;tf-magic-wrap
+         (termcap-get-flag "da")       ;tf-memory-above-screen
+         (or (termcap-get-flag "db")   ;tf-memory-below-screen
+             supdup?)
+         (or (termcap-get-flag "km")   ;tf-meta-key
+             (termcap-get-flag "MT"))
+         (termcap-get-flag "in")       ;tf-must-write-spaces
+         (termcap-get-flag "ns")       ;tf-newline-doesnt-scroll
+         (termcap-get-flag "os")       ;tf-overstrike
+         (termcap-get-flag "eo")       ;tf-overstrike-space-erase
+         (termcap-get-flag "xs")       ;tf-overwrite-preserves-standout
+         (termcap-get-flag "ms")       ;tf-standout-mode-motion
+         (termcap-get-flag "xt")       ;tf-teleray
+         (termcap-get-flag "ul")       ;tf-underscore
+
+         (termcap-get-number "lm")     ;tn-memory-lines
+         (termcap-get-number "pb")     ;tn-minimum-padding-speed
+         tn-standout-marker-width
+         (termcap-get-number "co")     ;tn-x-size
+         (termcap-get-number "li")     ;tn-y-size
+
+         (or (termcap-get-string "bl") ;ts-audible-bell
+             "\007")
+         (termcap-get-string "ce")     ;ts-clear-line
+         (termcap-get-string "ec")     ;ts-clear-multi-char
+         (termcap-get-string "cl")     ;ts-clear-screen
+         (termcap-get-string "cd")     ;ts-clear-to-bottom
+         ts-cursor-down
+         (termcap-get-string "DO")     ;ts-cursor-down-multi
+         (if (termcap-get-flag "bs")   ;ts-cursor-left
+             "\010"
+             (or (termcap-get-string "le")
+                 (termcap-get-string "bc")))
+         (termcap-get-string "LE")     ;ts-cursor-left-multi
+         (termcap-get-string "cr")     ;ts-cursor-line-start
+         (termcap-get-string "ll")     ;ts-cursor-lower-left
+         (termcap-get-string "cm")     ;ts-cursor-move
+         (termcap-get-string "ch")     ;ts-cursor-move-x
+         (termcap-get-string "nd")     ;ts-cursor-right
+         (termcap-get-string "RI")     ;ts-cursor-right-multi
+         (termcap-get-string "up")     ;ts-cursor-up
+         (termcap-get-string "UP")     ;ts-cursor-up-multi
+         (termcap-get-string "ho")     ;ts-cursor-upper-left
+         ts-delete-char
+         ts-delete-line
+         ts-delete-multi-char
+         ts-delete-multi-line
+         (termcap-get-string "vs")     ;ts-enhance-cursor
+         ts-enter-delete-mode
+         ts-enter-insert-mode
+         ts-enter-standout-mode
+         (termcap-get-string "ti")     ;ts-enter-termcap-mode
+         (termcap-get-string "ed")     ;ts-exit-delete-mode
+         (termcap-get-string "ei")     ;ts-exit-insert-mode
+         ts-exit-standout-mode
+         (termcap-get-string "te")     ;ts-exit-termcap-mode
+         ts-forward-scroll
+         ts-forward-scroll-multi
+         ts-insert-char
+         ts-insert-line
+         ts-insert-multi-char
+         ts-insert-multi-line
+         (termcap-get-string "vi")     ;ts-invisible-cursor
+         (termcap-get-string "ve")     ;ts-normal-cursor
+         (termcap-get-string "pc")     ;ts-pad-char
+         ts-pad-inserted-char
+         ts-reverse-scroll
+         ts-reverse-scroll-multi
+         ts-set-scroll-region
+         ts-set-scroll-region-1
+         ts-set-window
+         (termcap-get-string "vb")     ;ts-visible-bell
+         ))))
\ No newline at end of file
diff --git a/v7/src/edwin/tterm.scm b/v7/src/edwin/tterm.scm
new file mode 100644 (file)
index 0000000..8c74ae1
--- /dev/null
@@ -0,0 +1,823 @@
+#| -*-Scheme-*-
+
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/tterm.scm,v 1.1 1990/11/02 04:16:38 cph Exp $
+
+Copyright (c) 1990 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science.  Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. |#
+
+;;;; Termcap(3) Screen Implementation
+
+(declare (usual-integrations))
+
+(define-primitives
+  (baud-rate->index 1)
+  (tty-get-interrupt-enables 0)
+  (tty-set-interrupt-enables 1))
+
+(define (output-port/baud-rate port)
+  (let ((channel (output-port/channel port)))
+    (and channel
+        (channel-type=terminal? channel)
+        (terminal-output-baud-rate channel))))
+
+(define (output-port/buffered-chars port)
+  (let ((operation (output-port/operation port 'BUFFERED-CHARS)))
+    (if operation
+       (operation port)
+       0)))
+\f
+(define (console-available?)
+  (let ((description (console-termcap-description)))
+    (and (termcap-description? description)
+        (sufficiently-powerful? description)
+        (no-undesirable-characteristics? description))))
+
+(define (make-console-screen)
+  (let ((description (console-termcap-description)))
+    (cond ((not (output-port/baud-rate console-output-port))
+          (error "standard output not a terminal"))
+         ((not description)
+          (error "terminal type not set"))
+         ((not (termcap-description? description))
+          (error "unknown terminal type" description))
+         ((not (sufficiently-powerful? description))
+          (error "terminal type not powerful enough"
+                 (terminal-type-name description)))
+         ((not (no-undesirable-characteristics? description))
+          (error "terminal type has undesirable characteristics"
+                 (terminal-type-name description))))
+    (make-screen (let ((baud-rate (output-port/baud-rate console-output-port)))
+                  (let ((baud-rate-index (baud-rate->index baud-rate)))
+                    (make-terminal-state
+                     description
+                     baud-rate-index
+                     baud-rate
+                     (fix:1+ (fix:quotient baud-rate 2400)))))
+                console-beep
+                console-clear-line!
+                console-clear-rectangle!
+                console-clear-screen!
+                console-discard!
+                console-enter!
+                console-exit!
+                console-flush!
+                console-modeline-event!
+                console-preempt-update?
+                console-scroll-lines-down!
+                console-scroll-lines-up!
+                console-wrap-update!
+                console-write-char!
+                console-write-cursor!
+                console-write-substring!
+                (tn-x-size description)
+                (tn-y-size description))))
+
+(define (console-termcap-description)
+  (if (eq? console-description 'UNKNOWN)
+      (set! console-description
+           (let ((term ((ucode-primitive get-environment-variable 1) "TERM")))
+             (and term
+                  (or (and (output-port/baud-rate console-output-port)
+                           (make-termcap-description term))
+                      term)))))
+  console-description)
+
+(define (sufficiently-powerful? description)
+  (and (let ((x-size (tn-x-size description)))
+        (and x-size
+             (> x-size 0)))
+       (let ((y-size (tn-y-size description)))
+        (and y-size
+             (> y-size 0)))
+       (ts-cursor-move description)))
+
+(define (no-undesirable-characteristics? description)
+  (not (or (tf-hazeltine description)
+          (tf-teleray description)
+          (tf-underscore description))))
+\f
+(define (make-console-input-port screen)
+  screen                               ; ignored
+  console-input-port)
+
+(define (signal-interrupt! interrupt-enables)
+  interrupt-enables                    ; ignored
+  ;; (editor-beep)                     ; kbd beeps by itself
+  (temporary-message "Quit")
+  (^G-signal))
+
+(define (with-console-interrupts-enabled thunk)
+  (with-console-interrupt-state 2 thunk))
+
+(define (with-console-interrupts-disabled thunk)
+  (with-console-interrupt-state 0 thunk))
+
+(define (with-console-interrupt-state state thunk)
+  (let ((outside)
+       (inside state))
+    (dynamic-wind (lambda ()
+                   (set! outside (tty-get-interrupt-enables))
+                   (tty-set-interrupt-enables inside))
+                 thunk
+                 (lambda ()
+                   (set! inside (tty-get-interrupt-enables))
+                   (tty-set-interrupt-enables outside)))))
+
+(define console-display-type)
+(define console-description)
+
+(define (initialize-package!)
+  (set! console-display-type
+       (make-display-type 'CONSOLE
+                          false
+                          console-available?
+                          make-console-screen
+                          make-console-input-port
+                          with-console-grabbed
+                          with-console-interrupts-enabled
+                          with-console-interrupts-disabled))
+  (set! console-description 'UNKNOWN)
+  unspecific)
+\f
+(define (with-console-grabbed receiver)
+  (bind-console-state false
+    (lambda (get-outside-state)
+      (terminal-operation terminal-raw-input
+                         (input-port/channel console-input-port))
+      (terminal-operation terminal-raw-output
+                         (output-port/channel console-output-port))
+      (set! hook/^g-interrupt signal-interrupt!)
+      (tty-set-interrupt-enables 2)
+      (receiver
+       (lambda (thunk)
+        (bind-console-state (get-outside-state)
+          (lambda (get-inside-state)
+            get-inside-state
+            (thunk))))))))
+
+(define (bind-console-state state receiver)
+  (let ((outside-state)
+       (inside-state state))
+    (dynamic-wind (lambda ()
+                   (set! outside-state (console-state))
+                   (if inside-state
+                       (set-console-state! inside-state))
+                   (set! inside-state false)
+                   unspecific)
+                 (lambda ()
+                   (receiver (lambda () outside-state)))
+                 (lambda ()
+                   (set! inside-state (console-state))
+                   (set-console-state! outside-state)
+                   (set! outside-state false)
+                   unspecific))))
+
+(define (console-state)
+  (vector (channel-state (input-port/channel console-input-port))
+         (channel-state (output-port/channel console-output-port))
+         hook/^g-interrupt
+         (tty-get-interrupt-enables)))
+
+(define (set-console-state! state)
+  (set-channel-state! (input-port/channel console-input-port)
+                     (vector-ref state 0))
+  (set-channel-state! (output-port/channel console-output-port)
+                     (vector-ref state 1))
+  (set! hook/^g-interrupt (vector-ref state 2))
+  (tty-set-interrupt-enables (vector-ref state 3)))
+
+(define (channel-state channel)
+  (and channel
+       (channel-type=terminal? channel)
+       (terminal-get-state channel)))
+
+(define (set-channel-state! channel state)
+  (if (and channel
+          (channel-type=terminal? channel)
+          state)
+      (terminal-set-state channel state)))
+
+(define (terminal-operation operation channel)
+  (if (and channel
+          (channel-type=terminal? channel))
+      (operation channel)))
+\f
+;;;; Terminal State
+
+(define-structure (terminal-state
+                  (constructor make-terminal-state
+                               (description
+                                baud-rate-index
+                                baud-rate
+                                preemption-modulus))
+                  (conc-name terminal-state/))
+  (description false read-only true)
+  (baud-rate-index false read-only true)
+  (baud-rate false read-only true)
+  (preemption-modulus false read-only true)
+  (cursor-x false)
+  (cursor-y false)
+  (standout-mode? false)
+  (insert-mode? false)
+  (delete-mode? false)
+  (scroll-region false))
+
+(define-integrable (screen-description screen)
+  (terminal-state/description (screen-state screen)))
+
+(define-integrable (screen-baud-rate-index screen)
+  (terminal-state/baud-rate-index (screen-state screen)))
+
+(define-integrable (screen-baud-rate screen)
+  (terminal-state/baud-rate (screen-state screen)))
+
+(define-integrable (screen-preemption-modulus screen)
+  (terminal-state/preemption-modulus (screen-state screen)))
+
+(define-integrable (screen-cursor-x screen)
+  (terminal-state/cursor-x (screen-state screen)))
+
+(define-integrable (set-screen-cursor-x! screen cursor-x)
+  (set-terminal-state/cursor-x! (screen-state screen) cursor-x))
+
+(define-integrable (screen-cursor-y screen)
+  (terminal-state/cursor-y (screen-state screen)))
+
+(define-integrable (set-screen-cursor-y! screen cursor-y)
+  (set-terminal-state/cursor-y! (screen-state screen) cursor-y))
+
+(define-integrable (screen-standout-mode? screen)
+  (terminal-state/standout-mode? (screen-state screen)))
+
+(define-integrable (set-screen-standout-mode?! screen standout-mode?)
+  (set-terminal-state/standout-mode?! (screen-state screen) standout-mode?))
+
+(define-integrable (screen-insert-mode? screen)
+  (terminal-state/insert-mode? (screen-state screen)))
+
+(define-integrable (set-screen-insert-mode?! screen insert-mode?)
+  (set-terminal-state/insert-mode?! (screen-state screen) insert-mode?))
+
+(define-integrable (screen-delete-mode? screen)
+  (terminal-state/delete-mode? (screen-state screen)))
+
+(define-integrable (set-screen-delete-mode?! screen delete-mode?)
+  (set-terminal-state/delete-mode?! (screen-state screen) delete-mode?))
+
+(define-integrable (screen-scroll-region screen)
+  (terminal-state/scroll-region (screen-state screen)))
+
+(define-integrable (set-screen-scroll-region! screen scroll-region)
+  (set-terminal-state/scroll-region! (screen-state screen) scroll-region))
+\f
+;;;; Console Screen Operations
+
+(define (console-discard! screen)
+  screen
+  (set! console-description 'UNKNOWN)
+  unspecific)
+
+(define (console-enter! screen)
+  (maybe-output screen (ts-enter-termcap-mode (screen-description screen)))
+  (set-screen-cursor-x! screen false)
+  (set-screen-cursor-y! screen false))
+
+(define (console-exit! screen)
+  (let ((description (screen-description screen)))
+    (move-cursor screen 0 (fix:-1+ (tn-y-size description)))
+    (exit-standout-mode screen)
+    (exit-insert-mode screen)
+    (maybe-output screen (ts-exit-termcap-mode description)))
+  (output-port/flush-output console-output-port))
+
+(define (console-modeline-event! screen window type)
+  screen window type
+  unspecific)
+
+(define (console-wrap-update! screen thunk)
+  screen
+  (thunk)
+  (output-port/flush-output console-output-port))
+
+(define (console-preempt-update? screen y)
+  (and (fix:= 0 (fix:remainder y (screen-preemption-modulus screen)))
+       (begin
+        (let ((n (output-port/buffered-chars console-output-port)))
+          (if (fix:< 20 n)
+              (begin
+                (output-port/flush-output console-output-port)
+                (let ((baud-rate (screen-baud-rate screen)))
+                  (if (fix:< baud-rate 2400)
+                      (let ((msec (quotient (* n 10000) baud-rate)))
+                        (if (>= msec 1000)
+                            (let ((t (+ (real-time-clock) msec)))
+                              (let loop ()
+                                (if (< (real-time-clock) t)
+                                    (loop)))))))))))
+        true)))
+
+(define (console-beep screen)
+  (output-1 screen (ts-audible-bell (screen-description screen))))
+
+(define (console-flush! screen)
+  screen
+  (output-port/flush-output console-output-port))
+\f
+(define (console-write-cursor! screen x y)
+  (move-cursor screen x y))
+
+(define (console-write-char! screen x y char highlight)
+  (if (let ((description (screen-description screen)))
+       (not (and (tf-automatic-wrap description)
+                 (fix:= x (fix:-1+ (tn-x-size description)))
+                 (fix:= y (fix:-1+ (tn-y-size description))))))
+      (begin
+       (exit-insert-mode screen)
+       (move-cursor screen x y)
+       (highlight-if-desired screen highlight)
+       (output-char screen char)
+       (record-cursor-after-output screen (fix:1+ x)))))
+
+(define (console-write-substring! screen x y string start end highlight)
+  (if (fix:< start end)
+      (begin
+       (exit-insert-mode screen)
+       (move-cursor screen x y)
+       (highlight-if-desired screen highlight)
+       (let ((end
+              (if (let ((description (screen-description screen)))
+                    (and (tf-automatic-wrap description)
+                         (fix:= y (fix:-1+ (tn-y-size description)))
+                         (fix:= (fix:+ x (fix:- end start))
+                                (tn-x-size description))))
+                  (fix:-1+ end)
+                  end)))
+         (do ((i start (fix:1+ i)))
+             ((fix:= i end))
+           (output-char screen (string-ref string i)))
+         (record-cursor-after-output screen (fix:+ x (fix:- end start)))))))
+
+(define (console-clear-line! screen x y first-unused-x)
+  (move-cursor screen x y)
+  (clear-line screen first-unused-x))
+
+(define (console-clear-screen! screen)
+  (clear-screen screen))
+\f
+(define (console-clear-rectangle! screen xl xu yl yu highlight)
+  (let ((description (screen-description screen)))
+    (let ((x-size (tn-x-size description))
+         (y-size (tn-y-size description)))
+      (cond ((not (fix:= xu x-size))
+            (let ((n (fix:- xu xl)))
+              (do ((y yl (fix:1+ y)))
+                  ((fix:= y yu))
+                (move-cursor screen xl y)
+                (clear-multi-char screen n))))
+           ((fix:= yl (fix:1+ yu))
+            (move-cursor screen xl yl)
+            (clear-line screen x-size))
+           ((and (fix:= xl 0) (fix:= yu y-size))
+            (if (fix:= yl 0)
+                (clear-screen screen)
+                (begin
+                  (move-cursor screen 0 yl)
+                  (clear-to-bottom screen))))
+           (else
+            (do ((y yl (fix:1+ y)))
+                ((fix:= y yu))
+              (move-cursor screen xl y)
+              (clear-line screen x-size)))))))
+
+(define (console-scroll-lines-down! screen xl xu yl yu amount)
+  (let ((description (screen-description screen)))
+    (and (insert/delete-line-ok? description)
+        (fix:= xl 0)
+        (fix:= xu (tn-x-size description))
+        (begin
+          (let ((y-size (tn-y-size description)))
+            (if (or (fix:= yu y-size)
+                    (scroll-region-ok? description))
+                (insert-lines screen yl yu amount)
+                (begin
+                  (delete-lines screen (fix:- yu amount) y-size amount)
+                  (insert-lines screen yl y-size amount))))
+          'CLEARED))))
+
+(define (console-scroll-lines-up! screen xl xu yl yu amount)
+  (let ((description (screen-description screen)))
+    (and (insert/delete-line-ok? description)
+        (fix:= xl 0)
+        (fix:= xu (tn-x-size description))
+        (begin
+          (let ((y-size (tn-y-size description)))
+            (if (or (fix:= yu y-size)
+                    (scroll-region-ok? description))
+                (delete-lines screen yl yu amount)
+                (begin
+                  (delete-lines screen yl y-size amount)
+                  (insert-lines screen yu y-size amount))))
+          'CLEARED))))
+\f
+;;;; Termcap Commands
+
+(define (clear-screen screen)
+  (let ((description (screen-description screen)))
+    (let ((ts-clear-screen (ts-clear-screen description)))
+      (if ts-clear-screen
+         (begin
+           (exit-standout-mode screen)
+           (output-n screen ts-clear-screen (tn-y-size description))
+           (set-screen-cursor-x! screen 0)
+           (set-screen-cursor-y! screen 0))
+         (begin
+           (move-cursor screen 0 0)
+           (clear-to-bottom screen))))))
+
+(define (clear-to-bottom screen)
+  (let ((description (screen-description screen)))
+    (let ((ts-clear-to-bottom (ts-clear-to-bottom description)))
+      (if ts-clear-to-bottom
+         (begin
+           (exit-standout-mode screen)
+           (output screen ts-clear-to-bottom))
+         (let ((x-size (tn-x-size description))
+               (y-size (tn-y-size description)))
+           (do ((y (screen-cursor-y screen) (fix:1+ y)))
+               ((fix:= y y-size))
+             (move-cursor screen 0 y)
+             (clear-line screen x-size)))))))
+
+(define (clear-line screen first-unused-x)
+  (exit-standout-mode screen)
+  (let ((description (screen-description screen)))
+    (let ((ts-clear-line (ts-clear-line description)))
+      (if ts-clear-line
+         (output-1 screen ts-clear-line)
+         (begin
+           (exit-insert-mode screen)
+           (let ((first-unused-x
+                  (if (and (tf-automatic-wrap description)
+                           (fix:= first-unused-x (tn-x-size description))
+                           (fix:= (screen-cursor-y screen)
+                                  (fix:-1+ (tn-y-size description))))
+                      (fix:-1+ first-unused-x)
+                      first-unused-x)))
+             (do ((x (screen-cursor-x screen) (fix:1+ x)))
+                 ((fix:= x first-unused-x))
+               (output-char screen #\space))
+             (record-cursor-after-output screen first-unused-x)))))))
+
+(define (clear-multi-char screen n)
+  (exit-standout-mode screen)
+  (let ((description (screen-description screen)))
+    (let ((ts-clear-multi-char (ts-clear-multi-char description)))
+      (if ts-clear-multi-char
+         (output-1 screen (parameterize-1 ts-clear-multi-char n))
+         (begin
+           (exit-insert-mode screen)
+           (let ((cursor-x (screen-cursor-x screen)))
+             (let ((x-end
+                    (let ((x-end (fix:+ cursor-x n))
+                          (x-size (tn-x-size description)))
+                      (if (fix:> x-end x-size)
+                          (error "can't clear past end of line"))
+                      (if (and (fix:= x-end x-size)
+                               (tf-automatic-wrap description)
+                               (fix:= (screen-cursor-y screen)
+                                      (fix:-1+ (tn-y-size description))))
+                          (fix:-1+ x-size)
+                          x-end))))
+               (do ((x cursor-x (fix:1+ x)))
+                   ((fix:= x x-end))
+                 (output-char screen #\space))
+               (record-cursor-after-output screen x-end))))))))
+\f
+(define (insert-lines screen yl yu n)
+  (let ((description (screen-description screen))
+       (n-lines (fix:- yu yl)))
+    (let ((y-size (tn-y-size description)))
+      (cond ((ts-insert-line description)
+            =>
+            (lambda (ts-insert-line)
+              (if (not (fix:= yu y-size))
+                  (set-scroll-region screen yl yu))
+              (move-cursor screen 0 yl)
+              (exit-standout-mode screen)
+              (let ((ts-insert-multi-line (ts-insert-multi-line description)))
+                (if (and (fix:> n 1) ts-insert-multi-line)
+                    (output-n screen
+                              (parameterize-1 ts-insert-multi-line n)
+                              n-lines)
+                    (do ((i 0 (fix:1+ i)))
+                        ((fix:= i n))
+                      (output-n screen ts-insert-line n-lines))))
+              (clear-scroll-region screen)))
+           ((ts-reverse-scroll description)
+            =>
+            (lambda (ts-reverse-scroll)
+              (set-scroll-region screen yl yu)
+              (move-cursor screen 0 yl)
+              (exit-standout-mode screen)
+              (do ((i 0 (fix:1+ i)))
+                  ((fix:= i n))
+                (output-n screen ts-reverse-scroll n-lines))
+              (clear-scroll-region screen)
+              (if (and (tf-memory-above-screen description)
+                       (fix:= yl 0)
+                       (fix:= yu y-size))
+                  (let ((x-size (tn-x-size description)))
+                    (do ((y 0 (fix:1+ y)))
+                        ((fix:= y n))
+                      (move-cursor screen 0 y)
+                      (clear-line screen x-size))))))
+           (else
+            (error "can't insert lines" screen))))))
+
+(define (delete-lines screen yl yu n)
+  (let ((description (screen-description screen))
+       (n-lines (fix:- yu yl)))
+    (let ((y-size (tn-y-size description)))
+      (cond ((ts-delete-line description)
+            =>
+            (lambda (ts-delete-line)
+              (if (not (fix:= yu y-size))
+                  (set-scroll-region screen yl yu))
+              (move-cursor screen 0 yl)
+              (exit-standout-mode screen)
+              (let ((ts-delete-multi-line (ts-delete-multi-line description)))
+                (if (and (fix:> n 1) ts-delete-multi-line)
+                    (output-n screen
+                              (parameterize-1 ts-delete-multi-line n)
+                              n-lines)
+                    (do ((i 0 (fix:1+ i)))
+                        ((fix:= i n))
+                      (output-n screen ts-delete-line n-lines))))))
+           ((ts-forward-scroll description)
+            =>
+            (lambda (ts-forward-scroll)
+              (set-scroll-region screen yl yu)
+              (move-cursor screen 0 (fix:-1+ yu))
+              (exit-standout-mode screen)
+              (do ((i 0 (fix:1+ i)))
+                  ((fix:= i n))
+                (output-n screen ts-forward-scroll n-lines))))
+           (else
+            (error "can't delete lines" screen)))
+      (if (and (tf-memory-below-screen description)
+              (not (screen-scroll-region screen))
+              (fix:> n 0))
+         (begin
+           (move-cursor screen 0 (fix:- y-size n))
+           (clear-to-bottom screen)))
+      (clear-scroll-region screen))))
+\f
+(define (set-scroll-region screen yl yu)
+  (let ((y-size (tn-y-size (screen-description screen))))
+    (if (and (fix:= yl 0) (fix:= yu y-size))
+       (clear-scroll-region screen)
+       (if (let ((scroll-region (screen-scroll-region screen)))
+             (not (and scroll-region
+                       (fix:= yl (car scroll-region))
+                       (fix:= yu (cdr scroll-region)))))
+           (begin
+             (%set-scroll-region screen yl yu)
+             (set-screen-scroll-region! screen (cons yl yu)))))))
+
+(define (clear-scroll-region screen)
+  (let ((scroll-region (screen-scroll-region screen)))
+    (if scroll-region
+       (begin
+         (%set-scroll-region screen 0 (tn-y-size (screen-description screen)))
+         (set-screen-scroll-region! screen false)))))
+
+(define (%set-scroll-region screen yl yu)
+  (output-1 screen
+           (let ((description (screen-description screen)))
+             (cond ((ts-set-scroll-region description)
+                    =>
+                    (lambda (ts-set-scroll-region)
+                      (parameterize-2 ts-set-scroll-region yl (fix:-1+ yu))))
+                   ((ts-set-scroll-region-1 description)
+                    =>
+                    (lambda (ts-set-scroll-region-1)
+                      (let ((y-size (tn-y-size description)))
+                        (parameterize-4 ts-set-scroll-region-1
+                                        y-size
+                                        yl
+                                        (fix:- y-size yu)
+                                        y-size))))
+                   ((ts-set-window description)
+                    =>
+                    (lambda (ts-set-window)
+                      (parameterize-4 ts-set-window
+                                      yl (fix:-1+ yu)
+                                      0 (fix:-1+ (tn-x-size description)))))
+                   (else
+                    (error "can't set scroll region" screen)))))
+  (set-screen-cursor-x! screen false)
+  (set-screen-cursor-y! screen false))
+\f
+(define (highlight-if-desired screen highlight)
+  (if highlight
+      (enter-standout-mode screen)
+      (exit-standout-mode screen)))
+
+(define-integrable (enter-standout-mode screen)
+  ;; If the terminal uses standout markers, don't use standout.
+  ;; It's too complicated to bother with.
+  (if (and (not (screen-standout-mode? screen))
+          (not (tn-standout-marker-width (screen-description screen))))
+      (begin
+       (set-screen-standout-mode?! screen true)
+       (maybe-output-1
+        screen
+        (ts-enter-standout-mode (screen-description screen))))))
+
+(define-integrable (exit-standout-mode screen)
+  (if (screen-standout-mode? screen)
+      (begin
+       (set-screen-standout-mode?! screen false)
+       (maybe-output-1 screen
+                       (ts-exit-standout-mode (screen-description screen))))))
+
+(define-integrable (enter-insert-mode screen)
+  (if (not (screen-insert-mode? screen))
+      (begin
+       (set-screen-insert-mode?! screen true)
+       (maybe-output-1 screen
+                       (ts-enter-insert-mode (screen-description screen))))))
+
+(define-integrable (exit-insert-mode screen)
+  (if (screen-insert-mode? screen)
+      (begin
+       (set-screen-insert-mode?! screen false)
+       (maybe-output-1 screen
+                       (ts-exit-insert-mode (screen-description screen))))))
+
+(define-integrable (enter-delete-mode screen)
+  (if (not (screen-delete-mode? screen))
+      (begin
+       (set-screen-delete-mode?! screen true)
+       (maybe-output-1 screen
+                       (ts-enter-delete-mode (screen-description screen))))))
+
+(define-integrable (exit-delete-mode screen)
+  (if (screen-delete-mode? screen)
+      (begin
+       (set-screen-delete-mode?! screen false)
+       (maybe-output-1 screen
+                       (ts-exit-delete-mode (screen-description screen))))))
+\f
+(define (move-cursor screen x y)
+  (let ((description (screen-description screen))
+       (cursor-x (screen-cursor-x screen))
+       (cursor-y (screen-cursor-y screen)))
+    (if (not (and cursor-x (fix:= x cursor-x) (fix:= y cursor-y)))
+       (let ((y-size (tn-y-size description))
+             (trivial-command (lambda (command) (output-1 screen command)))
+             (general-case
+              (lambda ()
+                (output-1 screen
+                          (parameterize-2 (ts-cursor-move description)
+                                          y x)))))
+         (if (not (tf-standout-mode-motion description))
+             (exit-standout-mode screen))
+         (if (not (tf-insert-mode-motion description))
+             (exit-insert-mode screen))
+         (cond ((and (fix:= x 0)
+                     (fix:= y 0)
+                     (ts-cursor-upper-left description))
+                => trivial-command)
+               ((and (fix:= x 0)
+                     (fix:= y (fix:-1+ y-size))
+                     (ts-cursor-lower-left description))
+                => trivial-command)
+               ((not cursor-x)
+                (general-case))
+               ((fix:= y cursor-y)
+                (cond ((and (fix:= x (fix:-1+ cursor-x))
+                            (ts-cursor-left description))
+                       => trivial-command)
+                      ((and (fix:= x (fix:1+ cursor-x))
+                            (ts-cursor-right description))
+                       => trivial-command)
+                      ((and (fix:= x 0)
+                            (ts-cursor-line-start description))
+                       => trivial-command)
+                      ((ts-cursor-move-x description)
+                       =>
+                       (lambda (ts-cursor-move-x)
+                         (output-1 screen
+                                   (parameterize-1 ts-cursor-move-x x))))
+                      (else
+                       (general-case))))
+               ((fix:= x cursor-x)
+                (cond ((and (fix:= y (fix:-1+ cursor-y))
+                            (ts-cursor-up description))
+                       => trivial-command)
+                      ((and (fix:= y (fix:1+ cursor-y))
+                            (ts-cursor-down description))
+                       => trivial-command)
+                      (else
+                       (general-case))))
+               (else
+                (general-case)))
+         (set-screen-cursor-x! screen x)
+         (set-screen-cursor-y! screen y)))))
+
+(define (record-cursor-after-output screen cursor-x)
+  (let ((description (screen-description screen)))
+    (let ((x-size (tn-x-size description)))
+      (cond ((fix:< cursor-x x-size)
+            (set-screen-cursor-x! screen cursor-x))
+           ((fix:> cursor-x x-size)
+            (error "wrote past end of line" cursor-x x-size))
+           ((or (tf-magic-wrap description)
+                (tf-lose-wrap description))
+            (set-screen-cursor-x! screen false)
+            (set-screen-cursor-y! screen false))
+           ((tf-automatic-wrap description)
+            (set-screen-cursor-x! screen 0)
+            (set-screen-cursor-y! screen (fix:1+ (screen-cursor-y screen))))
+           (else
+            (set-screen-cursor-x! screen (fix:-1+ x-size)))))))
+\f
+(define (pad-string screen string n-lines)
+  (termcap-pad-string string
+                     n-lines
+                     (screen-baud-rate-index screen)
+                     (ts-pad-char (screen-description screen))))
+
+(define (goto-string screen string x y)
+  (let ((description (screen-description screen)))
+    (termcap-goto-string string x y
+                        (ts-cursor-left description)
+                        (ts-cursor-up description))))
+
+(define-integrable (parameterize-1 string p1)
+  (termcap-param-string string p1 0 0 0))
+
+(define-integrable (parameterize-2 string p1 p2)
+  (termcap-param-string string p1 p2 0 0))
+
+(define-integrable (parameterize-4 string p1 p2 p3 p4)
+  (termcap-param-string string p1 p2 p3 p4))
+
+(define (output screen command)
+  (output-n screen
+           command
+           (fix:- (let ((scroll-region (screen-scroll-region screen)))
+                    (if scroll-region
+                        (cdr scroll-region)
+                        (tn-y-size (screen-description screen))))
+                  (screen-cursor-y screen))))
+
+(define-integrable (output-1 screen command)
+  (output-n screen command 1))
+
+(define-integrable (output-n screen command n-lines)
+  (output-port/write-string console-output-port
+                           (pad-string screen command n-lines)))
+
+(define (maybe-output screen command)
+  (if command
+      (output screen command)))
+
+(define-integrable (maybe-output-1 screen command)
+  (maybe-output-n screen command 1))
+
+(define (maybe-output-n screen command n-lines)
+  (if command
+      (output-n screen command n-lines)))
+
+(define-integrable (output-char screen char)
+  screen
+  (output-port/write-char console-output-port char))
\ No newline at end of file