Requires microcode 11.50 and runtime 14.100.
authorChris Hanson <org/chris-hanson/cph>
Fri, 2 Nov 1990 03:25:13 +0000 (03:25 +0000)
committerChris Hanson <org/chris-hanson/cph>
Fri, 2 Nov 1990 03:25:13 +0000 (03:25 +0000)
* Implementation of update optimizer, and direct use of termcap rather
  than the buggy curses.

* Extensive rewrite of display update code.  New display update
  scrolls lines in some cases, and is tuned to offset the added cost
  of running the update optimizer.

* New display update event-tracing facility for debugging.

* If the last line of the buffer is empty, and the previous line is
  completely visible, the modeline says that the bottom of the buffer
  is visible.

* Editor variables can have value validity tests, which are applied
  whenever the variable's value is altered.  If the test fails, an
  error is signalled, so that user code can depend on the variable's
  contents satisfying the validity test.

* `(buffer-point (current-buffer))' now equivalent to
  `(current-point)'.

* `window-redraw!' no longer takes a second argument.  It's new
  meaning is to force the window to be redrawn from scratch, without
  affecting the window starting point or cursor position.

* Removed procedures:
window-end-index
window-redraw-preserving-point!

* Changed `window-start-index' to `window-start-mark'.

* Change terminal state control to use new I/O port operations that
  extract channels, and perform the terminal controls directly on
  those channels.

* Internal flag `debug-internal-errors?' facilitates debugging Edwin
  if set true.  Normally this is false.

* When first starting the editor, the default behavior is to try to
  use Scheme's controlling terminal, and if that isn't available, to
  use X.  If Scheme is started under Emacs, it has no controlling
  terminal, and therefore it will use X.

29 files changed:
v7/src/edwin/buffer.scm
v7/src/edwin/buffrm.scm
v7/src/edwin/bufwfs.scm
v7/src/edwin/bufwin.scm
v7/src/edwin/bufwiu.scm
v7/src/edwin/bufwmc.scm
v7/src/edwin/comman.scm
v7/src/edwin/comwin.scm
v7/src/edwin/debuge.scm
v7/src/edwin/decls.scm
v7/src/edwin/display.scm
v7/src/edwin/ed-ffi.scm
v7/src/edwin/editor.scm
v7/src/edwin/edtfrm.scm
v7/src/edwin/edtstr.scm
v7/src/edwin/edwin.ldr
v7/src/edwin/edwin.pkg
v7/src/edwin/edwin.sf
v7/src/edwin/hlpcom.scm
v7/src/edwin/image.scm
v7/src/edwin/modlin.scm
v7/src/edwin/modwin.scm
v7/src/edwin/rename.scm
v7/src/edwin/screen.scm
v7/src/edwin/utlwin.scm
v7/src/edwin/wincom.scm
v7/src/edwin/window.scm
v7/src/edwin/winren.scm
v7/src/edwin/xterm.scm

index 68a54accfe931fef2b989e3892df60f39ec30a82..822c8a0d82e0329d41412c8e9d85335ac793f6a4 100644 (file)
@@ -1,6 +1,6 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/buffer.scm,v 1.137 1990/10/03 04:54:07 cph Exp $
+;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/buffer.scm,v 1.138 1990/11/02 03:22:26 cph Rel $
 ;;;
 ;;;    Copyright (c) 1986, 1989, 1990 Massachusetts Institute of Technology
 ;;;
@@ -53,7 +53,7 @@
   modes
   comtabs
   windows
-  cursor-y
+  display-start
   pathname
   truename
   alist
@@ -100,7 +100,7 @@ The buffer is guaranteed to be deselected at that time."
        (vector-set! buffer buffer-index:modes (list mode))
        (vector-set! buffer buffer-index:comtabs (mode-comtabs mode))
        (vector-set! buffer buffer-index:windows '())
-       (vector-set! buffer buffer-index:cursor-y false)
+       (vector-set! buffer buffer-index:display-start false)
        (vector-set! buffer buffer-index:pathname false)
        (vector-set! buffer buffer-index:truename false)
        (vector-set! buffer buffer-index:alist '())
@@ -139,8 +139,7 @@ The buffer is guaranteed to be deselected at that time."
      (buffer-modeline-event! buffer 'BUFFER-PATHNAME)
      (vector-set! buffer buffer-index:auto-save-pathname false)
      (vector-set! buffer buffer-index:auto-save-modified? false)
-     (vector-set! buffer buffer-index:save-length 0)
-     unspecific)))
+     (vector-set! buffer buffer-index:save-length 0))))
 
 (define (set-buffer-name! buffer name)
   (vector-set! buffer buffer-index:name name)
@@ -155,31 +154,27 @@ The buffer is guaranteed to be deselected at that time."
   (buffer-modeline-event! buffer 'BUFFER-TRUENAME))
 
 (define-integrable (set-buffer-auto-save-pathname! buffer pathname)
-  (vector-set! buffer buffer-index:auto-save-pathname pathname)
-  unspecific)
+  (vector-set! buffer buffer-index:auto-save-pathname pathname))
 
 (define-integrable (set-buffer-auto-saved! buffer)
-  (vector-set! buffer buffer-index:auto-save-modified? false)
-  unspecific)
+  (vector-set! buffer buffer-index:auto-save-modified? false))
 
 (define-integrable (set-buffer-save-length! buffer)
-  (vector-set! buffer buffer-index:save-length (buffer-length buffer))
-  unspecific)
+  (vector-set! buffer buffer-index:save-length (buffer-length buffer)))
 
 (define-integrable (set-buffer-backed-up?! buffer flag)
-  (vector-set! buffer buffer-index:backed-up? flag)
-  unspecific)
+  (vector-set! buffer buffer-index:backed-up? flag))
 
 (define-integrable (set-buffer-modification-time! buffer flag)
-  (vector-set! buffer buffer-index:modification-time flag)
-  unspecific)
+  (vector-set! buffer buffer-index:modification-time flag))
 
 (define-integrable (set-buffer-comtabs! buffer comtabs)
-  (vector-set! buffer buffer-index:comtabs comtabs)
-  unspecific)
+  (vector-set! buffer buffer-index:comtabs comtabs))
 
-(define-integrable (buffer-point buffer)
-  (group-point (buffer-group buffer)))
+(define (buffer-point buffer)
+  (if (current-buffer? buffer)
+      (current-point)
+      (group-point (buffer-group buffer))))
 
 (define-integrable (%set-buffer-point! buffer mark)
   (set-group-point! (buffer-group buffer) mark))
@@ -211,18 +206,15 @@ The buffer is guaranteed to be deselected at that time."
 (define (add-buffer-window! buffer window)
   (vector-set! buffer
               buffer-index:windows
-              (cons window (vector-ref buffer buffer-index:windows)))
-  unspecific)
+              (cons window (vector-ref buffer buffer-index:windows))))
 
 (define (remove-buffer-window! buffer window)
   (vector-set! buffer
               buffer-index:windows
-              (delq! window (vector-ref buffer buffer-index:windows)))
-  unspecific)
+              (delq! window (vector-ref buffer buffer-index:windows))))
 
-(define-integrable (set-buffer-cursor-y! buffer cursor-y)
-  (vector-set! buffer buffer-index:cursor-y cursor-y)
-  unspecific)
+(define-integrable (set-buffer-display-start! buffer mark)
+  (vector-set! buffer buffer-index:display-start mark))
 
 (define-integrable (buffer-visible? buffer)
   (not (null? (buffer-windows buffer))))
@@ -238,18 +230,15 @@ The buffer is guaranteed to be deselected at that time."
        (set-cdr! entry value)
        (vector-set! buffer buffer-index:alist
                     (cons (cons key value)
-                          (vector-ref buffer buffer-index:alist)))))
-  unspecific)
+                          (vector-ref buffer buffer-index:alist))))))
 
 (define (buffer-remove! buffer key)
   (vector-set! buffer
               buffer-index:alist
-              (del-assq! key (vector-ref buffer buffer-index:alist)))
-  unspecific)
+              (del-assq! key (vector-ref buffer buffer-index:alist))))
 
 (define-integrable (reset-buffer-alist! buffer)
-  (vector-set! buffer buffer-index:alist '())
-  unspecific)
+  (vector-set! buffer buffer-index:alist '()))
 \f
 ;;;; Modification Flags
 
@@ -278,8 +267,7 @@ The buffer is guaranteed to be deselected at that time."
        (begin
          (set-group-modified! group true)
          (buffer-modeline-event! buffer 'BUFFER-MODIFIED)))
-    (vector-set! buffer buffer-index:auto-save-modified? true)
-    unspecific))
+    (vector-set! buffer buffer-index:auto-save-modified? true)))
 
 (define (buffer-clip-daemon buffer)
   (lambda (group start end)
@@ -327,8 +315,7 @@ The buffer is guaranteed to be deselected at that time."
        (begin
          ((car thunks))
          (loop (cdr thunks)))))
-  (vector-set! buffer buffer-index:initializations '())
-  unspecific)
+  (vector-set! buffer buffer-index:initializations '()))
 \f
 ;;;; Local Bindings
 
@@ -337,6 +324,7 @@ The buffer is guaranteed to be deselected at that time."
    (lambda ()
      (let ((buffer (current-buffer))
           (old-value (variable-value variable)))
+       (check-variable-value-validity! variable new-value)
        (%set-variable-value! variable new-value)
        (invoke-variable-assignment-daemons! variable)
        (let ((bindings (buffer-local-bindings buffer)))
@@ -344,8 +332,7 @@ The buffer is guaranteed to be deselected at that time."
           (if (not binding)
               (vector-set! buffer
                            buffer-index:local-bindings
-                           (cons (cons variable old-value) bindings))))))
-     unspecific)))
+                           (cons (cons variable old-value) bindings)))))))))
 
 (define (unmake-local-binding! variable)
   (without-interrupts
@@ -359,8 +346,7 @@ The buffer is guaranteed to be deselected at that time."
                 (invoke-variable-assignment-daemons! variable)
                 (vector-set! buffer
                              buffer-index:local-bindings
-                             (delq! binding bindings)))))))
-     unspecific)))
+                             (delq! binding bindings))))))))))
 
 (define (undo-local-bindings!)
   (let ((buffer (current-buffer)))
@@ -369,8 +355,7 @@ The buffer is guaranteed to be deselected at that time."
                  (%set-variable-value! variable (cdr binding))
                  (invoke-variable-assignment-daemons! variable)))
              (buffer-local-bindings buffer))
-    (vector-set! buffer buffer-index:local-bindings '()))
-  unspecific)
+    (vector-set! buffer buffer-index:local-bindings '())))
 \f
 (define (with-current-local-bindings! thunk)
   (let ((wind-bindings
@@ -420,34 +405,24 @@ The buffer is guaranteed to be deselected at that time."
        (for-each invoke-variable-assignment-daemons! variables))))
 \f
 (define (variable-local-value buffer variable)
-  (let ((in-cell
-        (lambda ()
-          (variable-value variable))))
-    (if (current-buffer? buffer)
-       (in-cell)
-       (let ((binding (assq variable (buffer-local-bindings buffer))))
-         (cond (binding
-                (cdr binding))
-               ((and (variable-buffer-local? variable)
-                     (within-editor?))
-                (let ((binding
-                       (assq variable
-                             (buffer-local-bindings (current-buffer)))))
-                  (if binding
-                      (cdr binding)
-                      (in-cell))))
-               (else
-                (in-cell)))))))
+  (let ((binding
+        (and (within-editor?)
+             (not (current-buffer? buffer))
+             (or (assq variable (buffer-local-bindings buffer))
+                 (and (variable-buffer-local? variable)
+                      (assq variable
+                            (buffer-local-bindings (current-buffer))))))))
+    (if binding
+       (cdr binding)
+       (variable-value variable))))
 
 (define (set-variable-local-value! buffer variable value)
-  (if (current-buffer? buffer)
-      (set-variable-value! variable value)
-      (let ((binding (assq variable (buffer-local-bindings buffer))))
-       (if binding
-           (begin
-             (set-cdr! binding value)
-             unspecific)
-           (set-variable-value! variable value)))))
+  (let ((binding
+        (and (not (current-buffer? buffer))
+             (assq variable (buffer-local-bindings buffer)))))
+    (if binding
+       (set-cdr! binding value)
+       (set-variable-value! variable value))))
 
 (define (define-variable-local-value! buffer variable value)
   (if (current-buffer? buffer)
@@ -460,8 +435,7 @@ The buffer is guaranteed to be deselected at that time."
                 (set-cdr! binding value)
                 (vector-set! buffer
                              buffer-index:local-bindings
-                             (cons (cons variable value) bindings)))
-            unspecific))))))
+                             (cons (cons variable value) bindings)))))))))
 
 (define (variable-local-value? buffer variable)
   (assq variable (buffer-local-bindings buffer)))
@@ -475,11 +449,10 @@ The buffer is guaranteed to be deselected at that time."
 (define (set-variable-default-value! variable value)
   (let ((binding (assq variable (buffer-local-bindings (current-buffer)))))
     (if binding
-       (begin
-         (set-cdr! binding value)
-         unspecific)
+       (set-cdr! binding value)
        (without-interrupts
         (lambda ()
+          (check-variable-value-validity! variable value)
           (%set-variable-value! variable value)
           (invoke-variable-assignment-daemons! variable))))))
 \f
index 011b888f09b064bebe53d27d8306ca4a38ab5163..dfd1ccec1fa988e2c7d1f1c0a93e43b44cc88eab 100644 (file)
@@ -1,6 +1,6 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/buffrm.scm,v 1.36 1990/10/06 00:15:22 cph Exp $
+;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/buffrm.scm,v 1.37 1990/11/02 03:22:35 cph Rel $
 ;;;
 ;;;    Copyright (c) 1986, 1989, 1990 Massachusetts Institute of Technology
 ;;;
 (declare (usual-integrations))
 \f
 (define-class buffer-frame combination-leaf-window
-  (text-inferior
-   border-inferior
+  (
+   ;; The inferior (of type BUFFER-WINDOW) that displays the buffer's
+   ;; text.
+   text-inferior
+
+   ;; The inferior (of type MODELINE-WINDOW) that displays the
+   ;; modeline.  May be #F if this window has no modeline (e.g. a
+   ;; typein window).
    modeline-inferior
-   last-select-time
-   override-message))
 
-(define-integrable (buffer-frame? object)
-  (object-of-class? buffer-frame object))
+   ;; The inferior (of type VERTICAL-BORDER-WINDOW) that draws a
+   ;; vertical border on the right-hand side of the window when this
+   ;; window has a neighbor to its right.
+   border-inferior
 
-(define (make-buffer-frame superior new-buffer modeline?)
-  (let ((frame (=> superior :make-inferior buffer-frame)))
-    (let ((window (frame-text-inferior frame)))
-      (initial-buffer! window new-buffer)
-      (%window-setup-truncate-lines! window false))
-    (initial-modeline! frame modeline?)
-    frame))
+   ;; A nonnegative integer that is updated when this window is
+   ;; selected.  This updating is performed by the editor frame that
+   ;; this window is a part of.
+   last-select-time
+   ))
 
 (define-method buffer-frame (:make-leaf frame)
   (let ((frame* (=> superior :make-inferior buffer-frame)))
-    (initial-buffer! (frame-text-inferior frame*) (window-buffer frame))
+    (set-buffer-frame-size! frame* (window-x-size frame) (window-y-size frame))
+    (set-window-buffer! frame* (window-buffer frame))
     (initial-modeline! frame* modeline-inferior)
     frame*))
 
   (usual=> frame :initialize! window*)
   (set! text-inferior (make-inferior frame buffer-window))
   (set! border-inferior (make-inferior frame vertical-border-window))
-  (set! last-select-time 0)
-  (set! override-message false)
-  unspecific)
-
-;;; **** Kludge: The text-inferior will generate modeline events, so
-;;; if the modeline gets redisplayed first it will be left with its
-;;; redisplay-flag set but its superior's redisplay-flag cleared.
+  (set! last-select-time 0))
+
+(define-method buffer-frame (:kill! window)
+  (remove-buffer-window! (window-buffer window) window)
+  (usual=> window :kill!))
+
+(define-method buffer-frame (:update-display! window screen x-start y-start
+                                             xl xu yl yu display-style)
+  ;; Assumes that interrupts are disabled.
+  (and (update-inferior! text-inferior screen x-start y-start
+                        xl xu yl yu display-style
+                        buffer-window:update-display!)
+       (if modeline-inferior
+          (update-inferior! modeline-inferior screen x-start y-start
+                            xl xu yl yu display-style
+                            modeline-window:update-display!)
+          true)
+       (update-inferior! border-inferior screen x-start y-start
+                        xl xu yl yu display-style
+                        vertical-border-window:update-display!)))
 
 (define (initial-modeline! frame modeline?)
+  ;; **** Kludge: The text-inferior will generate modeline events, so
+  ;; if the modeline gets redisplayed first it will be left with its
+  ;; redisplay-flag set but its superior's redisplay-flag cleared.
   (with-instance-variables buffer-frame frame (modeline?)
     (if modeline?
        (begin
          (set! inferiors
                (append! (delq! modeline-inferior inferiors)
                         (list modeline-inferior))))
-       (set! modeline-inferior false))
-    unspecific))
-
-(define-integrable (window-cursor frame)
-  (%window-cursor (frame-text-inferior frame)))
-
+       (set! modeline-inferior false))))
+\f
 (define-integrable (frame-text-inferior frame)
   (with-instance-variables buffer-frame frame ()
     (inferior-window text-inferior)))
 
-(define (frame-modeline-inferior frame)
-  (with-instance-variables buffer-frame frame ()
-    (and modeline-inferior
-        (inferior-window modeline-inferior))))
-\f
-(define (window-select-time frame)
-  (with-instance-variables buffer-frame frame ()
-    last-select-time))
+(define-method buffer-frame (:set-size! window x y)
+  (set-buffer-frame-size! window x y))
 
-(define (set-window-select-time! frame time)
-  (with-instance-variables buffer-frame frame (time)
-    (set! last-select-time time)
-    unspecific))
+(define-method buffer-frame (:set-x-size! window x)
+  (set-buffer-frame-size! window x y-size))
+
+(define-method buffer-frame (:set-y-size! window y)
+  (set-buffer-frame-size! window x-size y))
 
 (define (set-buffer-frame-size! window x y)
   (with-instance-variables buffer-frame window (x y)
     (usual=> window :set-size! x y)
+    (if modeline-inferior
+       (begin
+         (set! y (- y (inferior-y-size modeline-inferior)))
+         (set-inferior-start! modeline-inferior 0 y)
+         (set-inferior-x-size! modeline-inferior x)))
     (if (window-has-right-neighbor? window)
-       (let ((x* (- x (inferior-x-size border-inferior))))
-         (set-inferior-start! border-inferior x* 0)
-         (set-inferior-y-size! border-inferior y)
-         (set! x x*))
+       (begin
+         (set! x (- x (inferior-x-size border-inferior)))
+         (set-inferior-start! border-inferior x 0)
+         (set-inferior-y-size! border-inferior y))
        (set-inferior-start! border-inferior false false))
-    (if modeline-inferior
-       (let ((y* (- y (inferior-y-size modeline-inferior))))
-         (set-inferior-start! modeline-inferior 0 y*)
-         (set-inferior-x-size! modeline-inferior x)
-         (set! y y*)))
     (set-inferior-start! text-inferior 0 0)
-    (set-inferior-size! text-inferior x y)))
-
-(define-method buffer-frame :set-size!
-  set-buffer-frame-size!)
-
-(define-method buffer-frame (:set-x-size! window x)
-  (set-buffer-frame-size! window x y-size))
-
-(define-method buffer-frame (:set-y-size! window y)
-  (set-buffer-frame-size! window x-size y))
+    (set-inferior-size! text-inferior x y))
+  (window-setup-truncate-lines! window))
 
 (define-method buffer-frame (:minimum-x-size window)
   (if (window-has-right-neighbor? window)
       (+ (ref-variable window-minimum-height)
         (inferior-y-size modeline-inferior))
       (ref-variable window-minimum-height)))
+\f
+;;;; External Entries
 
-(define (buffer-frame-x-size frame)
+(define-integrable (buffer-frame? object)
+  (object-of-class? buffer-frame object))
+
+(define (make-buffer-frame superior new-buffer modeline?)
+  (let ((frame (=> superior :make-inferior buffer-frame)))
+    (set-window-buffer! frame new-buffer)
+    (initial-modeline! frame modeline?)
+    frame))
+
+(define-integrable (buffer-frame-x-size frame)
   (window-x-size (frame-text-inferior frame)))
 
-(define (buffer-frame-y-size frame)
+(define-integrable (buffer-frame-y-size frame)
   (window-y-size (frame-text-inferior frame)))
-\f
-;;;; External Entries
+
+(define-integrable (buffer-frame-needs-redisplay? frame)
+  (buffer-window/needs-redisplay? (frame-text-inferior frame)))
+
+(define-integrable (window-cursor-enable! frame)
+  (buffer-window/cursor-enable! (frame-text-inferior frame)))
+
+(define-integrable (window-cursor-disable! frame)
+  (buffer-window/cursor-disable! (frame-text-inferior frame)))
+
+(define-integrable (window-select-time frame)
+  (with-instance-variables buffer-frame frame ()
+    last-select-time))
+
+(define-integrable (set-window-select-time! frame time)
+  (with-instance-variables buffer-frame frame (time)
+    (set! last-select-time time)))
 
 (define-integrable (window-buffer frame)
-  (%window-buffer (frame-text-inferior frame)))
+  (buffer-window/buffer (frame-text-inferior frame)))
 
 (define (set-window-buffer! frame buffer)
-  (if (and (string-ci=? (buffer-name buffer) "Bluffer")
-          (null? (buffer-windows buffer)))
-      (buffer-reset! buffer))
-  (%set-window-buffer! (frame-text-inferior frame) buffer))
+  ;; BUFFER-WINDOW/SET-BUFFER! expects to have interrupts locked here.
+  (without-interrupts
+   (lambda ()
+     ;; Someday this will bite someone...
+     (if (and (string-ci=? (buffer-name buffer) "bluffer")
+             (null? (buffer-windows buffer)))
+        (buffer-reset! buffer))
+     (if (window-buffer frame)
+        (remove-buffer-window! (window-buffer frame) frame))
+     (buffer-window/set-buffer! (frame-text-inferior frame) buffer)
+     (add-buffer-window! buffer frame)
+     (window-setup-truncate-lines! frame))))
 
 (define-integrable (window-point frame)
-  (%window-point (frame-text-inferior frame)))
-
-(define (set-window-point! frame point)
-  (let ((window (frame-text-inferior frame)))
-    (%set-window-point! window (clip-mark-to-display window point))))
+  (buffer-window/point (frame-text-inferior frame)))
 
-(define (window-redraw! frame redraw-type)
-  (%window-force-redraw! (frame-text-inferior frame) redraw-type))
+(define-integrable (set-window-point! frame mark)
+  (buffer-window/set-point! (frame-text-inferior frame) mark))
 
-(define (window-redraw-preserving-point! frame)
-  (let ((window (frame-text-inferior frame)))
-    (%window-force-redraw! window (%window-point-y window))))
-
-(define-integrable (window-needs-redisplay? frame)
-  (with-instance-variables buffer-frame frame ()
-    (car (inferior-redisplay-flags text-inferior))))
+(define-integrable (window-redraw! frame)
+  (buffer-window/redraw! (frame-text-inferior frame)))
 
 (define (window-modeline-event! frame type)
   (with-instance-variables buffer-frame frame (type)
     (if modeline-inferior
        (=> (inferior-window modeline-inferior) :event! type)))
   (screen-modeline-event! (window-screen frame) frame type))
+\f
+(define-integrable (window-override-message window)
+  (buffer-window/override-message (frame-text-inferior window)))
 
-(define (window-set-override-message! window message)
-  (with-instance-variables buffer-frame window (message)
-    (set! override-message message))
-  (set-override-message! (frame-text-inferior window) message))
+(define-integrable (window-set-override-message! window message)
+  (buffer-window/set-override-message! (frame-text-inferior window) message))
 
-(define (window-clear-override-message! window)
-  (clear-override-message! (frame-text-inferior window))
-  (with-instance-variables buffer-frame window ()
-    (set! override-message false)))
+(define-integrable (window-clear-override-message! window)
+  (buffer-window/clear-override-message! (frame-text-inferior window)))
 
-(define (window-override-message window)
-  (with-instance-variables buffer-frame window ()
-    override-message))
+(define-integrable (window-direct-update! frame display-style)
+  (buffer-window/direct-update! (frame-text-inferior frame) display-style))
 
 (define-integrable (window-home-cursor! window)
-  (home-cursor! (frame-text-inferior window)))
-\f
-(define-integrable (window-direct-update! frame display-style)
-  (%window-direct-update! (frame-text-inferior frame) display-style))
+  (buffer-window/home-cursor! (frame-text-inferior window)))
 
-(define (window-direct-output-insert-char! frame char)
-  (without-interrupts
-   (lambda ()
-     (let ((point (window-point frame)))
-       (%group-insert-char! (mark-group point) (mark-index point) char))
-     (%direct-output-insert-char! (frame-text-inferior frame) char))))
+(define-integrable (window-direct-output-forward-char! frame)
+  (buffer-window/direct-output-forward-char! (frame-text-inferior frame)))
 
-(define (window-direct-output-insert-newline! frame)
-  (without-interrupts
-   (lambda ()
-     (let ((point (window-point frame)))
-       (%group-insert-char! (mark-group point) (mark-index point) #\newline))
-     (%direct-output-insert-newline! (frame-text-inferior frame)))))
+(define-integrable (window-direct-output-backward-char! frame)
+  (buffer-window/direct-output-backward-char! (frame-text-inferior frame)))
 
-(define (window-direct-output-insert-substring! frame string start end)
-  (without-interrupts
-   (lambda ()
-     (let ((point (window-point frame)))
-       (%group-insert-substring! (mark-group point) (mark-index point)
-                                string start end))
-     (%direct-output-insert-substring! (frame-text-inferior frame)
-                                      string start end))))
+(define-integrable (window-direct-output-insert-char! frame char)
+  (buffer-window/direct-output-insert-char! (frame-text-inferior frame) char))
 
-(define-integrable (window-direct-output-forward-char! frame)
-  (without-interrupts
-   (lambda ()
-     (%direct-output-forward-character! (frame-text-inferior frame)))))
+(define-integrable (window-direct-output-insert-newline! frame)
+  (buffer-window/direct-output-insert-newline! (frame-text-inferior frame)))
 
-(define-integrable (window-direct-output-backward-char! frame)
-  (without-interrupts
-   (lambda ()
-     (%direct-output-backward-character! (frame-text-inferior frame)))))
+(define-integrable (window-direct-output-insert-substring! frame
+                                                          string start end)
+  (buffer-window/direct-output-insert-substring! (frame-text-inferior frame)
+                                                string start end))
 
-(define (window-scroll-y-absolute! frame y-point)
-  (let ((window (frame-text-inferior frame)))
-    (maybe-recompute-image! window)
-    (%window-scroll-y-absolute! window y-point)))
+(define-integrable (window-scroll-y-absolute! frame y-point)
+  (buffer-window/scroll-y-absolute! (frame-text-inferior frame) y-point))
 
-(define (window-scroll-y-relative! frame delta)
-  (let ((window (frame-text-inferior frame)))
-    (maybe-recompute-image! window)
-    (%window-scroll-y-relative! window delta)))
+(define-integrable (window-scroll-y-relative! frame delta)
+  (buffer-window/scroll-y-relative! (frame-text-inferior frame) delta))
 
-(define (set-window-start-mark! frame mark force?)
-  (let ((window (frame-text-inferior frame)))
-    (maybe-recompute-image! window)
-    (%set-window-start-mark! window
-                            (clip-mark-to-display window mark)
-                            force?)))
+(define-integrable (set-window-start-mark! frame mark force?)
+  (buffer-window/set-start-mark! (frame-text-inferior frame) mark force?))
 
 (define-integrable (window-y-center frame)
-  (%window-y-center (frame-text-inferior frame)))
+  (buffer-window/y-center (frame-text-inferior frame)))
 
-(define (window-start-index frame)
-  (let ((window (frame-text-inferior frame)))
-    (maybe-recompute-image! window)
-    (%window-start-index window)))
+(define-integrable (window-start-mark frame)
+  (buffer-window/start-mark (frame-text-inferior frame)))
 
-(define (window-end-index frame)
-  (let ((window (frame-text-inferior frame)))
-    (maybe-recompute-image! window)
-    (%window-end-index window)))
-\f
-(define (window-mark-visible? frame mark)
-  (let ((window (frame-text-inferior frame)))
-    (maybe-recompute-image! window)
-    (%window-mark-visible? window mark)))
-
-(define (window-mark->x frame mark)
-  (let ((window (frame-text-inferior frame)))
-    (maybe-recompute-image! window)
-    (%window-mark->x window (clip-mark-to-display window mark))))
-
-(define (window-mark->y frame mark)
-  (let ((window (frame-text-inferior frame)))
-    (maybe-recompute-image! window)
-    (%window-mark->y window (clip-mark-to-display window mark))))
-
-(define (window-mark->coordinates frame mark)
-  (let ((window (frame-text-inferior frame)))
-    (maybe-recompute-image! window)
-    (%window-mark->coordinates window (clip-mark-to-display window mark))))
-
-(define (window-point-x frame)
-  (let ((window (frame-text-inferior frame)))
-    (maybe-recompute-image! window)
-    (%window-point-x window)))
-
-(define (window-point-y frame)
-  (let ((window (frame-text-inferior frame)))
-    (maybe-recompute-image! window)
-    (%window-point-y window)))
-
-(define (window-point-coordinates frame)
-  (let ((window (frame-text-inferior frame)))
-    (maybe-recompute-image! window)
-    (%window-point-coordinates window)))
-
-(define (window-coordinates->mark frame x y)
-  (let ((window (frame-text-inferior frame)))
-    (maybe-recompute-image! window)
-    (%window-coordinates->mark window x y)))
+(define-integrable (window-mark-visible? frame mark)
+  (buffer-window/mark-visible? (frame-text-inferior frame) mark))
+
+(define-integrable (window-mark->x frame mark)
+  (buffer-window/mark->x (frame-text-inferior frame) mark))
+
+(define-integrable (window-mark->y frame mark)
+  (buffer-window/mark->y (frame-text-inferior frame) mark))
+
+(define-integrable (window-mark->coordinates frame mark)
+  (buffer-window/mark->coordinates (frame-text-inferior frame) mark))
 
+(define-integrable (window-point-x frame)
+  (buffer-window/point-x (frame-text-inferior frame)))
+
+(define-integrable (window-point-y frame)
+  (buffer-window/point-y (frame-text-inferior frame)))
+
+(define-integrable (window-point-coordinates frame)
+  (buffer-window/point-coordinates (frame-text-inferior frame)))
+
+(define-integrable (window-coordinates->mark frame x y)
+  (buffer-window/coordinates->mark (frame-text-inferior frame) x y))
+
+(define-integrable (set-window-debug-trace! frame debug-trace)
+  (%set-window-debug-trace! (frame-text-inferior frame) debug-trace))
+\f
 (define (window-setup-truncate-lines! frame)
-  (%window-setup-truncate-lines! (frame-text-inferior frame) 'START))
\ No newline at end of file
+  (let ((window (frame-text-inferior frame))
+       (truncate-lines?
+        (let ((buffer (window-buffer frame)))
+          (or (and (variable-local-value
+                    buffer
+                    (ref-variable-object truncate-partial-width-windows))
+                   (window-has-horizontal-neighbor? frame))
+              (variable-local-value buffer
+                                    (ref-variable-object truncate-lines))))))
+    (if (not (boolean=? (%window-truncate-lines? window) truncate-lines?))
+       (without-interrupts
+        (lambda ()
+          (%set-window-truncate-lines?! window truncate-lines?)
+          (buffer-window/redraw! window))))))
+
+(define-variable-per-buffer truncate-lines
+  "*True means do not display continuation lines;
+give each line of text one screen line.
+Automatically becomes local when set in any fashion.
+
+Note that this is overridden by the variable
+truncate-partial-width-windows if that variable is true
+and this buffer is not full-screen width."
+  false)
+
+(define-variable truncate-partial-width-windows
+  "*True means truncate lines in all windows less than full screen wide."
+  true)
+
+(let ((setup-truncate-lines!
+       (lambda (variable)
+        variable                       ;ignore
+        (for-each window-setup-truncate-lines! (window-list)))))
+  (add-variable-assignment-daemon!
+   (ref-variable-object truncate-lines)
+   setup-truncate-lines!)
+  (add-variable-assignment-daemon!
+   (ref-variable-object truncate-partial-width-windows)
+   setup-truncate-lines!))
\ No newline at end of file
index eda1258664f4aaa0983415fe438be2b2e326ac79..7fa20358f09ae0b4cbebf0159fd4610446201a93 100644 (file)
@@ -1,8 +1,8 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/bufwfs.scm,v 1.8 1990/10/09 16:23:21 cph Exp $
+;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/bufwfs.scm,v 1.9 1990/11/02 03:22:42 cph Rel $
 ;;;
-;;;    Copyright (c) 1986, 1989 Massachusetts Institute of Technology
+;;;    Copyright (c) 1986, 1989, 1990 Massachusetts Institute of Technology
 ;;;
 ;;;    This material was developed by the Scheme project at the
 ;;;    Massachusetts Institute of Technology, Department of
 ;;; of that license should have been included along with this file.
 ;;;
 
-;;;; Buffer Windows:  Fill and Scroll
+;;;; Buffer Windows: Fill and Scroll
 
 (declare (usual-integrations))
 \f
-;;;; Fill
+(define (fill-top window inferiors start)
+  ;; Assumes non-null INFERIORS.
+  (let loop
+      ((inferiors inferiors)
+       (start start)
+       (y-start (inferior-y-start (car inferiors))))
+    (if (fix:<= y-start 0)
+       inferiors
+       (let* ((end (fix:- start 1))
+              (start (%window-line-start-index window end))
+              (inferior (make-line-inferior window start end))
+              (y-start (fix:- y-start (inferior-y-size inferior))))
+         (%set-inferior-y-start! inferior y-start)
+         (loop (cons inferior inferiors) start y-start)))))
 
-(define (fill-top! window inferiors start fill-bottom?)
-  (with-instance-variables buffer-window window (inferiors start fill-bottom?)
-    ;; INFERIORS is assumed to be not '(), and START is the start index
-    ;; of the first inferior in that list.  FILL-BOTTOM?, if true, means
-    ;; try to fill the bottom of INFERIORS after filling the top.
-    (let ((group (buffer-group buffer)))
-      (define (do-bottom! inferiors start)
-       (if (null? (cdr inferiors))
-           (set-cdr! inferiors
-                     (fill-bottom window
-                                  (inferior-y-end (car inferiors))
-                                  (line-end-index group start)))
-           (do-bottom! (cdr inferiors)
-                       (fix:+ start (line-inferior-length inferiors)))))
-      (let loop
-         ((y-start (inferior-y-start (car inferiors)))
-          (start start)
-          (inferiors inferiors))
-       (cond ((not (fix:positive? y-start))
-              (if fill-bottom? (do-bottom! inferiors start))
-              (set-line-inferiors! window inferiors start))
-             ((group-start-index? group start)
-              (set-line-inferiors! window
-                                   (scroll-lines-up! window inferiors 0 start)
-                                   start))
-             (else
-              (let ((end (fix:-1+ start)))
-                (let ((start (line-start-index group end)))
+(define (fill-middle! window
+                     top-inferiors top-start
+                     bottom-inferiors bottom-start)
+  ;; Assumes non-null TOP-INFERIORS and BOTTOM-INFERIORS.
+  (let loop ((inferiors top-inferiors) (start top-start))
+    (let ((start (fix:+ start (line-inferior-length (car inferiors)))))
+      (if (not (null? (cdr inferiors)))
+         (loop (cdr inferiors) start)
+         (set-cdr!
+          inferiors
+          (let loop
+              ((start start) (y-start (%inferior-y-end (car inferiors))))
+            (if (fix:= start bottom-start)
+                bottom-inferiors
+                (let ((end (%window-line-end-index window start)))
                   (let ((inferior (make-line-inferior window start end)))
-                    (let ((y-start
-                           (fix:- y-start (inferior-y-size inferior))))
-                      (set-inferior-start! inferior 0 y-start)
-                      (loop y-start start (cons inferior inferiors))))))))))))
-
-(define (fill-bottom window y-end end-index)
-  (with-instance-variables buffer-window window (y-end end-index)
-    ;; Generates a list of inferiors which will be appended to a list
-    ;; ending in Y-END and END-INDEX.
-    (let ((group (buffer-group buffer)))
-      (let loop ((y-start y-end) (end end-index))
-       (if (or (not (fix:< y-start y-size))
-               (group-end-index? group end))
-           '()
-           (let ((start (fix:1+ end)))
-             (let ((end (line-end-index group start)))
-               (let ((inferior (make-line-inferior window start end)))
-                 (set-inferior-start! inferior 0 y-start)
-                 (cons inferior (loop (inferior-y-end inferior) end))))))))))
-
-(define (fill-middle! window y-end end-index tail tail-start-index)
-  (with-instance-variables buffer-window window
-                          (y-end end-index tail tail-start-index)
-    ;; Generates a list of inferiors which will be appended to a list
-    ;; ending in Y-END and END-INDEX.  TAIL will be appended to the
-    ;; generated list if it is visible, and scrolled up or down as
-    ;; needed.  TAIL-START-INDEX says where TAIL begins.  It is assumed
-    ;; that (> TAIL-START-INDEX END-INDEX), and that TAIL is non-'().
-    (let ((group (buffer-group buffer)))
-      (let loop ((y-end y-end) (end end-index))
-       (let ((start (fix:1+ end)))
-         (cond ((fix:= start tail-start-index)
-                (let ((old-y-end (inferior-y-start (car tail))))
-                  (cond ((fix:> y-end old-y-end)
-                         (scroll-lines-down! window tail y-end))
-                        ((fix:< y-end old-y-end)
-                         (scroll-lines-up! window tail y-end start))
-                        (else tail))))
-               ((not (fix:< y-end y-size)) '())
-               (else
-                (let ((end (line-end-index group start)))
-                  (let ((inferior (make-line-inferior window start end)))
-                    (set-inferior-start! inferior 0 y-end)
+                    (%set-inferior-y-start! inferior y-start)
                     (cons inferior
-                          (loop (inferior-y-end inferior) end)))))))))))
-\f
-;;;; Scroll
+                          (loop (fix:+ end 1)
+                                (fix:+ y-start
+                                       (inferior-y-size inferior))))))))))))
+  top-inferiors)
 
-(define (%set-window-start-mark! window mark force?)
-  (let ((start-y (%window-mark->y window mark)))
-    (and (or force?
-            (let ((point-y (fix:- (%window-point-y window) start-y)))
-              (and (not (fix:negative? point-y))
-                   (fix:< point-y (window-y-size window)))))
-        (begin
-          (%window-scroll-y-relative! window start-y)
-          true))))
+(define (fill-bottom! window inferiors start)
+  ;; Assumes non-null INFERIORS.
+  (let loop ((inferiors inferiors) (start start))
+    (let ((end
+          (fix:+ start
+                 (line-window-length
+                  (inferior-window (car inferiors))))))
+      (if (not (null? (cdr inferiors)))
+         (loop (cdr inferiors) (fix:+ end 1))
+         (let ((y-start (%inferior-y-end (car inferiors))))
+           (if (or (%window-group-end-index? window end)
+                   (fix:>= y-start (window-y-size window)))
+               (set-current-end-index! window end)
+               (set-cdr! inferiors
+                         (generate-line-inferiors window
+                                                  (fix:+ end 1)
+                                                  y-start)))))))
+  inferiors)
 
-(define (%window-scroll-y-absolute! window y-point)
-  (with-instance-variables buffer-window window (y-point)
-    (%window-scroll-y-relative! window
-                               (fix:- (%window-point-y window) y-point))))
+(define (generate-line-inferiors window start y-start)
+  ;; Assumes (FIX:< Y-START (WINDOW-Y-SIZE WINDOW))
+  (let ((y-size (window-y-size window)))
+    (let loop ((y-start y-start) (start start))
+      (let ((end (%window-line-end-index window start)))
+       (let ((inferior (make-line-inferior window start end)))
+         (%set-inferior-y-start! inferior y-start)
+         (cons inferior
+               (let ((y-start (fix:+ y-start (inferior-y-size inferior))))
+                 (if (or (%window-group-end-index? window end)
+                         (fix:>= y-start y-size))
+                     (begin
+                       (set-current-end-index! window end)
+                       '())
+                     (loop y-start (fix:+ end 1))))))))))
+\f
+(define (scroll-lines! window inferiors start y-start)
+  (cond ((or (null? inferiors)
+            (fix:= y-start (inferior-y-start (car inferiors))))
+        (values inferiors start))
+       ((fix:< y-start (inferior-y-start (car inferiors)))
+        (scroll-lines-up! window inferiors start y-start))
+       (else
+        (values (scroll-lines-down! window inferiors y-start) start))))
 
-(define (%window-scroll-y-relative! window y-delta)
-  (with-instance-variables buffer-window window (y-delta)
-    (cond ((fix:negative? y-delta)
-          (let ((y-start
-                 (fix:- (inferior-y-start (car line-inferiors)) y-delta)))
-            (if (fix:< y-start y-size)
-                (fill-top! window
-                           (scroll-lines-down! window line-inferiors y-start)
-                           (mark-index start-line-mark)
-                           false)
-                (redraw-at! window
-                            (or (%window-coordinates->mark window 0 y-delta)
-                                (buffer-start buffer))))))
-         ((fix:positive? y-delta)
-          (let ((inferiors (y->inferiors window y-delta)))
-            (if inferiors
-                (let ((start (inferiors->index window inferiors)))
-                  (set-line-inferiors!
-                   window
-                   (scroll-lines-up! window
-                                     inferiors
-                                     (fix:- (inferior-y-start (car inferiors))
-                                            y-delta)
-                                     start)
-                   start))
-                (redraw-at! window
-                            (or (%window-coordinates->mark window 0 y-delta)
-                                (buffer-end buffer)))))))
-    (everything-changed!
-     window
-     (lambda (window)
-       (let ((y
-             (if (fix:positive? y-delta)
-                 0
-                 (fix:-1+ (window-y-size window)))))
-        (%set-buffer-point! buffer (%window-coordinates->mark window 0 y))
-        (set! point (buffer-point buffer))
-        (set-inferior-start! cursor-inferior 0 y)
-        (set! point-moved? false)
-        (window-modeline-event! superior 'WINDOW-SCROLLED))))))
+(define (scroll-lines-up! window inferiors start y-start)
+  (let ((do-scroll
+        (lambda (inferiors start y-start)
+          (%scroll-lines-up! window inferiors y-start)
+          (values inferiors start))))
+    (if (fix:>= y-start 0)
+       (do-scroll inferiors start y-start)
+       (let loop ((inferiors inferiors) (start start) (y-start y-start))
+         (cond ((null? inferiors)
+                (values '() start))
+               ((fix:= y-start 0)
+                (do-scroll inferiors start y-start))
+               (else
+                (let ((y-end
+                       (fix:+ y-start (inferior-y-size (car inferiors)))))
+                  (if (fix:> y-end 0)
+                      (do-scroll inferiors start y-start)
+                      (loop (cdr inferiors)
+                            (fix:+ start
+                                   (line-inferior-length (car inferiors)))
+                            y-end)))))))))
 
-(define (redraw-at! window mark)
-  (with-instance-variables buffer-window window (mark)
-    (%set-buffer-point! buffer mark)
-    (set! point (buffer-point buffer))
-    (redraw-screen! window 0)))
-\f
 (define (scroll-lines-down! window inferiors y-start)
-  ;; Returns new list of new inferiors.
-  (with-instance-variables buffer-window window (inferiors y-start)
-    (let ((scrolled?
-          (let ((yl (inferior-y-start (car inferiors))))
-            (let ((amount (fix:- y-start yl)))
-              (and (fix:< yl saved-yu)
-                   (fix:< amount (fix:- saved-yu saved-yl))
-                   (screen-scroll-lines-down! saved-screen
-                                              (fix:+ saved-xl saved-x-start)
-                                              (fix:+ saved-xu saved-x-start)
-                                              (fix:+ (fix:max yl saved-yl)
-                                                     saved-y-start)
-                                              (fix:+ saved-yu saved-y-start)
-                                              amount))))))
-      (let loop ((inferiors inferiors) (y-start y-start))
-       (%set-inferior-y-start! (car inferiors) y-start)
-       (if (not scrolled?)
-           (inferior-needs-redisplay! (car inferiors)))
-       (cons (car inferiors)
-             (let ((inferiors (cdr inferiors))
-                   (y-start (inferior-y-end (car inferiors))))
-               (if (or (null? inferiors)
-                       (not (fix:< y-start y-size)))
-                   '()
-                   (loop inferiors y-start))))))))
+  (let ((y-size (window-y-size window)))
+    (if (or (null? inferiors)
+           (fix:>= y-start y-size))
+       '()
+       (begin
+         (let loop ((inferiors inferiors) (y-start y-start))
+           (if (not (null? (cdr inferiors)))
+               (let ((y-end
+                      (fix:+ y-start (inferior-y-size (car inferiors)))))
+                 (if (fix:>= y-end y-size)
+                     (set-cdr! inferiors '())
+                     (loop (cdr inferiors) y-end)))))
+         (%scroll-lines-down! window inferiors y-start)
+         inferiors))))
+\f
+(define (%scroll-lines-down! window inferiors y-start)
+  (adjust-scrolled-inferiors!
+   window
+   inferiors
+   y-start
+   (let ((yl (inferior-y-start (car inferiors)))
+        (yu (%inferior-y-end (car (last-pair inferiors)))))
+     (let ((amount (fix:- y-start yl)))
+       (and (fix:< yl (%window-saved-yu window))
+           (fix:< (%window-saved-yl window) yu)
+           (let ((yl (fix:max (%window-saved-yl window) yl))
+                 (yu (fix:min (%window-saved-yu window) (fix:+ yu amount))))
+             (and (fix:< amount (fix:- yu yl))
+                  (screen-scroll-lines-down
+                   (%window-saved-screen window)
+                   (fix:+ (%window-saved-xl window)
+                          (%window-saved-x-start window))
+                   (fix:+ (%window-saved-xu window)
+                          (%window-saved-x-start window))
+                   (fix:+ yl (%window-saved-y-start window))
+                   (fix:+ yu (%window-saved-y-start window))
+                   amount))))))))
 
-(define (scroll-lines-up! window inferiors y-start start-index)
-  ;; Returns new list of new inferiors.
-  (with-instance-variables buffer-window window (inferiors y-start start-index)
-    (let ((scrolled?
-          (let ((yl (inferior-y-start (car inferiors))))
-            (let ((amount (fix:- yl y-start)))
-              (and (fix:< yl saved-yu)
-                   (fix:< amount (fix:- saved-yu saved-yl))
-                   (screen-scroll-lines-up! saved-screen
-                                            (fix:+ saved-xl saved-x-start)
-                                            (fix:+ saved-xu saved-x-start)
-                                            (fix:+ (fix:max y-start saved-yl)
-                                                   saved-y-start)
-                                            (fix:+ saved-yu saved-y-start)
-                                            amount))))))
-      (let loop
-         ((inferiors inferiors) (y-start y-start) (start-index start-index))
-       (%set-inferior-y-start! (car inferiors) y-start)
-       (if (not scrolled?)
-           (inferior-needs-redisplay! (car inferiors)))
-       (cons (car inferiors)
-             (let ((y-start (inferior-y-end (car inferiors))))
-               (cond ((null? (cdr inferiors))
-                      (fill-bottom window
-                                   y-start
-                                   (line-end-index (buffer-group buffer)
-                                                   start-index)))
-                     ((fix:< y-start y-size)
-                      (loop (cdr inferiors)
-                            y-start
-                            (fix:+ start-index
-                                   (line-inferior-length inferiors))))
-                     (else '()))))))))
+(define (%scroll-lines-up! window inferiors y-start)
+  (adjust-scrolled-inferiors!
+   window
+   inferiors
+   y-start
+   (let ((yl (inferior-y-start (car inferiors)))
+        (yu (%inferior-y-end (car (last-pair inferiors)))))
+     (let ((amount (fix:- yl y-start)))
+       (and (fix:< yl (%window-saved-yu window))
+           (fix:< (%window-saved-yl window) yu)
+           (let ((yl (fix:max (%window-saved-yl window) y-start))
+                 (yu (fix:min (%window-saved-yu window) yu)))
+             (and (fix:< amount (fix:- yu yl))
+                  (screen-scroll-lines-up
+                   (%window-saved-screen window)
+                   (fix:+ (%window-saved-xl window)
+                          (%window-saved-x-start window))
+                   (fix:+ (%window-saved-xu window)
+                          (%window-saved-x-start window))
+                   (fix:+ yl (%window-saved-y-start window))
+                   (fix:+ yu (%window-saved-y-start window))
+                   amount))))))))
 
-(define-integrable (fix:max x y)
-  (if (fix:> x y) x y))
\ No newline at end of file
+(define (adjust-scrolled-inferiors! window inferiors y-start scrolled?)
+  (let ((y-size (window-y-size window)))
+    (let loop ((inferiors inferiors) (y-start y-start))
+      (if (not (null? inferiors))
+         (begin
+           (%set-inferior-y-start! (car inferiors) y-start)
+           (let ((y-end (fix:+ y-start (inferior-y-size (car inferiors)))))
+             (if (or (not scrolled?)
+                     (fix:<= y-end y-size))
+                 (inferior-needs-redisplay! (car inferiors)))
+             (loop (cdr inferiors) y-end)))))))
\ No newline at end of file
index 41c1dbba10d12fc08a76cb166a970b8d6db77328..d039ca2a2f9f833facdbaa868a937ad1ce5b6ac2 100644 (file)
@@ -1,6 +1,6 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/bufwin.scm,v 1.285 1990/10/05 23:32:36 cph Exp $
+;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/bufwin.scm,v 1.286 1990/11/02 03:22:50 cph Rel $
 ;;;
 ;;;    Copyright (c) 1986, 1989, 1990 Massachusetts Institute of Technology
 ;;;
 ;;; of that license should have been included along with this file.
 ;;;
 
-;;;; Buffer Windows:  Base
+;;;; Buffer Windows: Base
 
 (declare (usual-integrations))
 \f
-;;; The following instance variables contain marks which must -NEVER-
-;;; be passed to anyone who will keep a pointer to them.  The reason
-;;; is that the `mark-temporary!' operation is called on these marks,
-;;; which invalidates them as soon as some change happens to the
-;;; buffer.  Remember, you were warned!
+;;; The following instance variables contain permanent marks, which
+;;; must be copied if they are passed to someone outside the buffer
+;;; window abstraction, because they are modified by side-effect.
 ;;;
-;;; start-line-mark
+;;; current-start-mark
+;;; current-end-mark
 ;;; start-mark
-;;; end-mark
-;;; end-line-mark
+;;; start-line-mark
 ;;; start-changes-mark
 ;;; end-changes-mark
 ;;; start-clip-mark
 ;;; end-clip-mark
 
 (define-class buffer-window vanilla-window
-  (buffer point changes-daemon clip-daemon
-         cursor-inferior blank-inferior
-         line-inferiors last-line-inferior
-         start-line-mark start-mark end-mark end-line-mark
-         start-changes-mark end-changes-mark point-moved?
-         start-clip-mark end-clip-mark
-         saved-screen saved-x-start saved-y-start
-         saved-xl saved-xu saved-yl saved-yu
-         override-inferior truncate-lines? force-redraw?))
+  (
+   ;; The buffer being displayed in this window.
+   buffer
+
+   ;; The point marker in this window.
+   point
+
+   ;; If this flag is false, text lines that are too long to fit on
+   ;; a single window line are displayed with multiple window lines.
+   ;; If the flag is true, such text lines are truncated to single
+   ;; window lines.
+   truncate-lines?
+
+   ;; This is the inferior window (of class CURSOR-WINDOW) that
+   ;; displays the cursor for this window.
+   cursor-inferior
+
+   ;; This is the inferior window (of class BLANK-WINDOW) that keeps
+   ;; the bottom of the window clear when there is no text in it.
+   ;; This is only used when the end of the buffer is visible in the
+   ;; window.  When not in use, it is moved offscreen so the window
+   ;; clipping will prevent it from being updated.
+   blank-inferior
+
+   ;; This is normally #F.  However, when the normal display of the
+   ;; buffer is overridden by a one-line message, as is commonly done
+   ;; for the typein window, this variable contains the inferior
+   ;; window (of class LINE-WINDOW) that displays the message.
+   override-inferior
+
+   ;; A list of the inferior windows (of class LINE-WINDOW) that are
+   ;; currently displaying the portion of the buffer that is visible
+   ;; in this window.
+   line-inferiors
+
+   ;; This permanent mark records where the first line inferior
+   ;; starts.
+   current-start-mark
+
+   ;; This permanent mark records where the last line inferior ends.
+   current-end-mark
+\f
+   ;; This permanent mark is the smallest that is visible in the
+   ;; window.  If the window's start is not known, this is #F.
+   start-mark
+
+   ;; This permanent mark is at the beginning of the line containing
+   ;; START-MARK.  It is #F if START-MARK is.  Note that this is the
+   ;; same as CURRENT-START-MARK at the end of a display update, and
+   ;; is changed due to point motion and scrolling.
+   start-line-mark
+
+   ;; This is the Y coordinate of START-LINE-MARK.  It is undefined if
+   ;; START-LINE-MARK is #F, otherwise it is guaranteed to be
+   ;; non-positive.
+   start-line-y
+
+   ;; This contains the daemon that is invoked when insertions or
+   ;; deletions are performed on the buffer.
+   changes-daemon
+
+   ;; These variables delimit the region of the buffer that has been
+   ;; affected by insertions or deletions since the last display
+   ;; update.  If no changes have occurred, they are #F.
+   start-changes-mark
+   end-changes-mark
+
+   ;; This contains the daemon that is invoked when the buffer's
+   ;; display clipping is changed.
+   clip-daemon
+
+   ;; These variables delimit the region of the buffer that has been
+   ;; unaffected by clipping since the last display update.  If the
+   ;; clipping has not changed since then, they are #F.
+   start-clip-mark
+   end-clip-mark
+
+   ;; If true, this flag indicates that point has moved since the last
+   ;; time that START-LINE-MARK was set.
+   point-moved?
+
+   ;; If true, this flag indicates that the window should be entirely
+   ;; redrawn at the next display update.
+   force-redraw?
+
+   ;; These variables record where the last display update drew its
+   ;; output.  SAVED-SCREEN is the screen on which it occurred.
+   ;; SAVED-X-START and SAVED-Y-START is the position, in the screen's
+   ;; coordinates, at which the window was located.  SAVED-XL,
+   ;; SAVED-XU, SAVED-YL, and SAVED-YU (window's coordinates) delimit
+   ;; the rectangular portion of the window that was drawn.
+   saved-screen
+   saved-x-start
+   saved-y-start
+   saved-xl
+   saved-xu
+   saved-yl
+   saved-yu
+
+   ;; This variable, if not #F, is a procedure that is called at
+   ;; interesting times to generate a debugging trace.
+   debug-trace))
+\f
+;;;; Instance Variable Accessors
 
-(define-method buffer-window (:initialize! window window*)
-  (usual=> window :initialize! window*)
-  (set! cursor-inferior (make-inferior window cursor-window))
-  (set! blank-inferior (make-inferior window blank-window))
-  (set! changes-daemon (make-changes-daemon window))
-  (set! clip-daemon (make-clip-daemon window))
-  (set! override-inferior false)
-  (set! force-redraw? 'CENTER)
-  unspecific)
+(define-integrable (%window-buffer window)
+  (with-instance-variables buffer-window window () buffer))
 
-(define-method buffer-window (:kill! window)
-  (delete-window-buffer! window)
-  (usual=> window :kill!))
+(define-integrable (%window-group window)
+  (buffer-group (%window-buffer window)))
 
-(define-method buffer-window (:update-display! window screen x-start y-start
-                                              xl xu yl yu display-style)
-  (set! saved-screen screen)
-  (set! saved-x-start x-start) (set! saved-y-start y-start)
-  (set! saved-xl xl) (set! saved-xu xu) (set! saved-yl yl) (set! saved-yu yu)
-  (update-buffer-window! window screen x-start y-start
-                        xl xu yl yu display-style))
+(define-integrable (%set-window-buffer! window buffer*)
+  (with-instance-variables buffer-window window (buffer*)
+    (set! buffer buffer*)))
 
-(define-method buffer-window (:salvage! window)
-  (%set-buffer-point! buffer
-                     (make-mark (buffer-group buffer)
-                                (group-start-index (buffer-group buffer))))
-  (set! point (buffer-point buffer))
-  (window-modeline-event! superior 'SALVAGE)
-  (%window-redraw! window false))
-\f
-(define (set-buffer-window-size! window x y)
-  (with-instance-variables buffer-window window (x y)
-    (set! saved-screen false)
-    (let ((old-y y-size))
-      (usual=> window :set-size! x y)
-      ;; Preserve point y unless it is offscreen now.
-      (%window-setup-truncate-lines! window false)
-      (%window-force-redraw! window (and old-y (%window-cursor-y window))))))
-
-(define-method buffer-window :set-size!
-  set-buffer-window-size!)
+(define-integrable (%window-point window)
+  (with-instance-variables buffer-window window () point))
 
-(define-method buffer-window (:set-x-size! window x)
-  (set-buffer-window-size! window x y-size))
+(define-integrable (%window-point-index window)
+  (mark-index-integrable (%window-point window)))
 
-(define-method buffer-window (:set-y-size! window y)
-  (set-buffer-window-size! window x-size y))
-
-(define (%window-setup-truncate-lines! window redraw-type)
-  (with-instance-variables buffer-window window ()
-    (if (not (within-editor?))
-       (begin
-         (set! truncate-lines? (ref-variable truncate-lines))
-         unspecific)
-       (let ((new-truncate-lines?
-              (or (and (variable-local-value
-                        buffer
-                        (ref-variable-object truncate-partial-width-windows))
-                       (window-has-horizontal-neighbor? superior))
-                  (variable-local-value
-                   buffer
-                   (ref-variable-object truncate-lines)))))
-         (if (not (boolean=? truncate-lines? new-truncate-lines?))
-             (begin
-               (set! truncate-lines? new-truncate-lines?)
-               (if (and redraw-type (not force-redraw?))
-                   (%window-force-redraw! window redraw-type))))))))
-
-(define-variable-per-buffer truncate-lines
-  "*True means do not display continuation lines;
-give each line of text one screen line.
-Automatically becomes local when set in any fashion.
-
-Note that this is overridden by the variable
-truncate-partial-width-windows if that variable is true
-and this buffer is not full-screen width."
-  false)
-
-(define-variable truncate-partial-width-windows
-  "*True means truncate lines in all windows less than full screen wide."
-  true)
-
-(let ((setup-truncate-lines!
-       (lambda (variable)
-        variable                       ;ignore
-        (for-each window-setup-truncate-lines! (window-list)))))
-  (add-variable-assignment-daemon!
-   (ref-variable-object truncate-lines)
-   setup-truncate-lines!)
-  (add-variable-assignment-daemon!
-   (ref-variable-object truncate-partial-width-windows)
-   setup-truncate-lines!))
+(define-integrable (%set-window-point! window point*)
+  (with-instance-variables buffer-window window (point*)
+    (set! point point*)))
+
+(define-integrable (%set-window-point-index! window index)
+  (%set-window-point! window
+                     (%make-permanent-mark (%window-group window)
+                                           index
+                                           true)))
+
+(define-integrable (%window-truncate-lines? window)
+  (with-instance-variables buffer-window window () truncate-lines?))
+
+(define-integrable (%set-window-truncate-lines?! window truncate-lines?*)
+  (with-instance-variables buffer-window window (truncate-lines?*)
+    (set! truncate-lines? truncate-lines?*)))
+
+(define-integrable (%window-cursor-inferior window)
+  (with-instance-variables buffer-window window () cursor-inferior))
+
+(define-integrable (%set-window-cursor-inferior! window inferior)
+  (with-instance-variables buffer-window window (inferior)
+    (set! cursor-inferior inferior)))
+
+(define-integrable (%window-blank-inferior window)
+  (with-instance-variables buffer-window window () blank-inferior))
+
+(define-integrable (%set-window-blank-inferior! window inferior)
+  (with-instance-variables buffer-window window (inferior)
+    (set! blank-inferior inferior)))
+
+(define-integrable (%window-override-inferior window)
+  (with-instance-variables buffer-window window () override-inferior))
+
+(define-integrable (%set-window-override-inferior! window inferior)
+  (with-instance-variables buffer-window window (inferior)
+    (set! override-inferior inferior)))
 \f
-;;;; Group Operations
+(define-integrable (%window-line-inferiors window)
+  (with-instance-variables buffer-window window () line-inferiors))
 
-;;; These are identical to the operations of the same name used
-;;; elsewhere in the editor, except that they clip at the display clip
-;;; limits rather than the text clip limits.
+(define-integrable (%set-window-line-inferiors! window inferiors)
+  (with-instance-variables buffer-window window (inferiors)
+    (set! line-inferiors inferiors)))
 
-(define-integrable (group-start-index group)
-  (mark-index (group-display-start group)))
+(define-integrable (%window-current-start-mark window)
+  (with-instance-variables buffer-window window () current-start-mark))
 
-(define-integrable (group-end-index group)
-  (mark-index (group-display-end group)))
+(define-integrable (%window-current-start-index window)
+  (mark-index-integrable (%window-current-start-mark window)))
 
-(define-integrable (group-start-index? group index)
-  (not (fix:> index (group-start-index group))))
+(define-integrable (%set-window-current-start-mark! window mark)
+  (with-instance-variables buffer-window window (mark)
+    (set! current-start-mark mark)))
 
-(define-integrable (group-end-index? group index)
-  (not (fix:< index (group-end-index group))))
+(define-integrable (%window-current-end-mark window)
+  (with-instance-variables buffer-window window () current-end-mark))
 
-(define (line-start-index group index)
-  (let ((limit (group-start-index group)))
-    (or (%find-previous-newline group index limit)
-       limit)))
+(define-integrable (%window-current-end-index window)
+  (mark-index-integrable (%window-current-end-mark window)))
 
-(define (line-end-index group index)
-  (let ((limit (group-end-index group)))
-    (or (%find-next-newline group index limit)
-       limit)))
+(define-integrable (%set-window-current-end-mark! window mark)
+  (with-instance-variables buffer-window window (mark)
+    (set! current-end-mark mark)))
 
-(define (line-start-index? group index)
-  (or (group-start-index? group index)
-      (char=? (group-left-char group index) #\newline)))
+(define-integrable (%window-start-mark window)
+  (with-instance-variables buffer-window window () start-mark))
 
-(define (line-end-index? group index)
-  (or (group-end-index? group index)
-      (char=? (group-right-char group index) #\newline)))
+(define-integrable (%window-start-index window)
+  (mark-index-integrable (%window-start-mark window)))
 
-(define (clip-mark-to-display window mark)
+(define-integrable (%set-window-start-mark! window mark)
   (with-instance-variables buffer-window window (mark)
-    (if (not (mark? mark))
-       (error "Argument not a mark" mark))
-    (if (not (mark~ point mark))
-       (error "Mark not within displayed buffer" mark))
-    (let ((group (mark-group mark))
-         (index (mark-index mark)))
-      (cond ((group-start-index? group index) (group-display-start group))
-           ((group-end-index? group index) (group-display-end group))
-           (else mark)))))
+    (set! start-mark mark)))
+
+(define-integrable (%window-start-line-mark window)
+  (with-instance-variables buffer-window window () start-line-mark))
+
+(define-integrable (%window-start-line-index window)
+  (mark-index-integrable (%window-start-line-mark window)))
+
+(define-integrable (%set-window-start-line-mark! window mark)
+  (with-instance-variables buffer-window window (mark)
+    (set! start-line-mark mark)))
+
+(define-integrable (%window-start-line-y window)
+  (with-instance-variables buffer-window window () start-line-y))
+
+(define-integrable (%set-window-start-line-y! window y)
+  (with-instance-variables buffer-window window (y)
+    (set! start-line-y y)))
 \f
-;;;; Buffer and Point
+(define-integrable (%window-changes-daemon window)
+  (with-instance-variables buffer-window window () changes-daemon))
 
-(define-integrable (%window-buffer window)
-  (with-instance-variables buffer-window window ()
-    buffer))
-
-(define (%window-buffer-cursor-y window)
-  (with-instance-variables buffer-window window ()
-    (let ((py (buffer-cursor-y buffer)))
-      (and py
-          (begin
-            (set-buffer-cursor-y! buffer false)
-            (and (fix:= (car py) (mark-index point))
-                 (fix:< (cdr py) y-size)
-                 (cdr py)))))))
-
-(define (%set-window-buffer! window new-buffer)
-  (with-instance-variables buffer-window window (new-buffer)
-    (if (not (buffer? new-buffer)) (error "Argument not a buffer" new-buffer))
-    (set-buffer-cursor-y! buffer
-                         (let ((y (%window-cursor-y window)))
-                           (and y (cons (mark-index point) y))))
-    (delete-window-buffer! window)
-    (initial-buffer! window new-buffer)
-    (window-modeline-event! superior 'NEW-BUFFER)
-    (%window-force-redraw! window (%window-buffer-cursor-y window))))
-
-(define (initial-buffer! window new-buffer)
-  (with-instance-variables buffer-window window (new-buffer)
-    (set! buffer new-buffer)
-    (add-buffer-window! buffer superior)
-    (let ((group (buffer-group buffer)))
-      (add-group-delete-daemon! group changes-daemon)
-      (add-group-insert-daemon! group changes-daemon)
-      (add-group-clip-daemon! group clip-daemon)
-      (let ((point (mark-index (buffer-point buffer)))
-           (start (group-start-index group))
-           (end (group-end-index group)))
-       (cond ((fix:< point start)
-              (%set-buffer-point! buffer (make-mark group start)))
-             ((fix:> point end)
-              (%set-buffer-point! buffer (make-mark group end))))))
-    (set! point (buffer-point buffer))
-    unspecific))
-
-(define (delete-window-buffer! window)
-  (with-instance-variables buffer-window window ()
-    (let ((group (buffer-group buffer)))
-      (remove-group-delete-daemon! group changes-daemon)
-      (remove-group-insert-daemon! group changes-daemon)
-      (remove-group-clip-daemon! group clip-daemon))
-    (remove-buffer-window! buffer superior)))
+(define-integrable (%set-window-changes-daemon! window daemon)
+  (with-instance-variables buffer-window window (daemon)
+    (set! changes-daemon daemon)))
 
-(define-integrable (%window-point window)
-  (with-instance-variables buffer-window window ()
-    point))
+(define-integrable (%window-start-changes-mark window)
+  (with-instance-variables buffer-window window () start-changes-mark))
 
-(define (%set-window-point! window mark)
+(define-integrable (%window-start-changes-index window)
+  (mark-index-integrable (%window-start-changes-mark window)))
+
+(define-integrable (%set-window-start-changes-mark! window mark)
   (with-instance-variables buffer-window window (mark)
-    (%set-buffer-point! buffer mark)
-    (set! point (buffer-point buffer))
-    (set! point-moved? true)
-    (setup-redisplay-flags! redisplay-flags)))
-
-(define-integrable (%window-cursor window)
-  (with-instance-variables buffer-window window ()
-    (inferior-window cursor-inferior)))
-
-(define (%window-cursor-y window)
-  (with-instance-variables buffer-window window ()
-    (let ((y (inferior-y-start cursor-inferior)))
-      (and y (fix:< y y-size) y))))
+    (set! start-changes-mark mark)))
+
+(define-integrable (%window-end-changes-mark window)
+  (with-instance-variables buffer-window window () end-changes-mark))
+
+(define-integrable (%window-end-changes-index window)
+  (mark-index-integrable (%window-end-changes-mark window)))
+
+(define-integrable (%set-window-end-changes-mark! window mark)
+  (with-instance-variables buffer-window window (mark)
+    (set! end-changes-mark mark)))
+
+(define-integrable (%window-clip-daemon window)
+  (with-instance-variables buffer-window window () clip-daemon))
+
+(define-integrable (%set-window-clip-daemon! window daemon)
+  (with-instance-variables buffer-window window (daemon)
+    (set! clip-daemon daemon)))
+
+(define-integrable (%window-start-clip-mark window)
+  (with-instance-variables buffer-window window () start-clip-mark))
+
+(define-integrable (%window-start-clip-index window)
+  (mark-index-integrable (%window-start-clip-mark window)))
+
+(define-integrable (%set-window-start-clip-mark! window mark)
+  (with-instance-variables buffer-window window (mark)
+    (set! start-clip-mark mark)))
+
+(define-integrable (%window-end-clip-mark window)
+  (with-instance-variables buffer-window window () end-clip-mark))
+
+(define-integrable (%window-end-clip-index window)
+  (mark-index-integrable (%window-end-clip-mark window)))
+
+(define-integrable (%set-window-end-clip-mark! window mark)
+  (with-instance-variables buffer-window window (mark)
+    (set! end-clip-mark mark)))
+
+(define-integrable (%window-point-moved? window)
+  (with-instance-variables buffer-window window () point-moved?))
+
+(define-integrable (%set-window-point-moved?! window point-moved?*)
+  (with-instance-variables buffer-window window (point-moved?*)
+    (set! point-moved? point-moved?*)))
+
+(define-integrable (%window-force-redraw? window)
+  (with-instance-variables buffer-window window () force-redraw?))
+
+(define-integrable (%set-window-force-redraw?! window force-redraw?*)
+  (with-instance-variables buffer-window window (force-redraw?*)
+    (set! force-redraw? force-redraw?*)))
 \f
-;;;; Override Message
-
-;;; This is used to display messages over the typein window.
-
-(define (set-override-message! window message)
-  (with-instance-variables buffer-window window (message)
-    (if (not override-inferior)
-       (begin
-         (set! override-inferior (make-inferior window line-window))
-         (set! inferiors
-               (list override-inferior cursor-inferior blank-inferior))
-         (set-inferior-start! override-inferior 0 0)))
-    (let ((override-window (inferior-window override-inferior)))
-      (set-line-window-string! override-window message truncate-lines?)
-      (set-inferior-position!
-       cursor-inferior
-       (string-base:index->coordinates override-window
-                                      (string-length message))))
-    (set-blank-inferior-start! window (inferior-y-end override-inferior))))
-
-(define (clear-override-message! window)
-  (with-instance-variables buffer-window window ()
-    (if override-inferior
-       (begin
-         (set! override-inferior false)
-         (set! inferiors
-               (cons* cursor-inferior blank-inferior line-inferiors))
-         (set-inferior-position! cursor-inferior
-                                 (%window-mark->coordinates window point))
-         (blank-inferior-changed! window)
-         (for-each inferior-needs-redisplay! inferiors)))))
-
-(define (home-cursor! window)
-  (with-instance-variables buffer-window window ()
-    (screen-write-cursor! saved-screen saved-x-start saved-y-start)
-    (screen-flush! saved-screen)))
+(define-integrable (%window-saved-screen window)
+  (with-instance-variables buffer-window window () saved-screen))
+
+(define-integrable (%set-window-saved-screen! window screen)
+  (with-instance-variables buffer-window window (screen)
+    (set! saved-screen screen)))
+
+(define-integrable (%window-saved-x-start window)
+  (with-instance-variables buffer-window window () saved-x-start))
+
+(define-integrable (%set-window-saved-x-start! window x-start)
+  (with-instance-variables buffer-window window (x-start)
+    (set! saved-x-start x-start)))
+
+(define-integrable (%window-saved-y-start window)
+  (with-instance-variables buffer-window window () saved-y-start))
+
+(define-integrable (%set-window-saved-y-start! window y-start)
+  (with-instance-variables buffer-window window (y-start)
+    (set! saved-y-start y-start)))
+
+(define-integrable (%window-saved-xl window)
+  (with-instance-variables buffer-window window () saved-xl))
+
+(define-integrable (%set-window-saved-xl! window xl)
+  (with-instance-variables buffer-window window (xl)
+    (set! saved-xl xl)))
+
+(define-integrable (%window-saved-xu window)
+  (with-instance-variables buffer-window window () saved-xu))
+
+(define-integrable (%set-window-saved-xu! window xu)
+  (with-instance-variables buffer-window window (xu)
+    (set! saved-xu xu)))
+
+(define-integrable (%window-saved-yl window)
+  (with-instance-variables buffer-window window () saved-yl))
+
+(define-integrable (%set-window-saved-yl! window yl)
+  (with-instance-variables buffer-window window (yl)
+    (set! saved-yl yl)))
+
+(define-integrable (%window-saved-yu window)
+  (with-instance-variables buffer-window window () saved-yu))
+
+(define-integrable (%set-window-saved-yu! window yu)
+  (with-instance-variables buffer-window window (yu)
+    (set! saved-yu yu)))
+
+(define-integrable (%window-debug-trace window)
+  (with-instance-variables buffer-window window () debug-trace))
+
+(define-integrable (%set-window-debug-trace! window procedure)
+  (with-instance-variables buffer-window window (procedure)
+    (set! debug-trace procedure)))
 \f
-;;;; Inferiors
-
-(define (make-line-inferior window start end)
-  (with-instance-variables buffer-window window (start end)
-    (let ((inferior (make-inferior window line-window)))
-      (set-line-window-string! (inferior-window inferior)
-                              (group-extract-string (buffer-group buffer)
-                                                    start end)
-                              truncate-lines?)
-      inferior)))
+;;;; Narrowing
+
+(define-integrable (%window-group-start-mark window)
+  (group-display-start (%window-group window)))
+
+(define-integrable (%window-group-end-mark window)
+  (group-display-end (%window-group window)))
+
+(define-integrable (%window-group-start-index window)
+  (group-position->index-integrable
+   (%window-group window)
+   (mark-position (group-display-start (%window-group window)))))
+
+(define-integrable (%window-group-end-index window)
+  (group-position->index-integrable
+   (%window-group window)
+   (mark-position (group-display-end (%window-group window)))))
+
+(define-integrable (%window-group-start-index? window index)
+  (fix:<= index (%window-group-start-index window)))
+
+(define-integrable (%window-group-end-index? window index)
+  (fix:>= index (%window-group-end-index window)))
+
+(define-integrable (%window-line-start-index window index)
+  (let ((start (%window-group-start-index window)))
+    (or (%find-previous-newline (%window-group window) index start)
+       start)))
+
+(define-integrable (%window-line-end-index window index)
+  (let ((end (%window-group-end-index window)))
+    (or (%find-next-newline (%window-group window) index end)
+       end)))
+
+(define (%window-line-start-index? window index)
+  (or (%window-group-start-index? window index)
+      (char=? (string-ref (group-text (%window-group window))
+                         (fix:-1+ (group-index->position-integrable
+                                   (%window-group window)
+                                   index
+                                   false)))
+             #\newline)))
+
+(define (%window-line-end-index? window index)
+  (or (%window-group-end-index? window index)
+      (char=? (string-ref (group-text (%window-group window))
+                         (group-index->position-integrable
+                          (%window-group window)
+                          index
+                          true))
+             #\newline)))
 
-(define-integrable (first-line-inferior window)
-  (with-instance-variables buffer-window window ()
-    (car line-inferiors)))
-
-(define-integrable (line-inferior-length inferiors)
-  (fix:1+ (line-window-length (inferior-window (car inferiors)))))
-
-(define-integrable (blank-inferior-changed! window)
-  (with-instance-variables buffer-window window ()
-    (if (not override-inferior)
-       (set-blank-inferior-start! window
-                                  (inferior-y-end last-line-inferior)))))
-
-(define-integrable (set-blank-inferior-start! window y-end)
-  (with-instance-variables buffer-window window (y-end)
-    (if (fix:< y-end y-size)
-       (begin
-         (set-inferior-size! blank-inferior x-size (fix:- y-size y-end))
-         (set-inferior-start! blank-inferior 0 y-end))
-       (set-inferior-start! blank-inferior false false))))
-
-(define-integrable (set-line-inferiors! window inferiors start)
-  (with-instance-variables buffer-window window (inferiors start)
-    (set! line-inferiors inferiors)
-    (destroy-mark! start-line-mark)
-    (set! start-line-mark
-         (%make-permanent-mark (buffer-group buffer) start false))
-    unspecific))
-
-(define (line-inferiors-changed! window)
-  (with-instance-variables buffer-window window ()
-    (let loop ((inferiors line-inferiors) (start (mark-index start-line-mark)))
-      (if (null? (cdr inferiors))
-         (begin
-           (set! last-line-inferior (car inferiors))
-           (destroy-mark! end-line-mark)
-           (set! end-line-mark
-                 (let ((group (buffer-group buffer)))
-                   (%make-permanent-mark group
-                                         (line-end-index group start)
-                                         true))))
-         (loop (cdr inferiors)
-               (fix:+ start (line-inferior-length inferiors)))))
-    (set! inferiors
-         (if override-inferior
-             (list override-inferior cursor-inferior blank-inferior)
-             (cons* cursor-inferior blank-inferior line-inferiors)))
-    unspecific))
+(define (clip-mark-to-display window mark)
+  (if (not (mark? mark))
+      (error:illegal-datum mark 'CLIP-MARK-TO-DISPLAY))
+  (if (and (%window-point window)
+          (not (mark~ (%window-point window) mark)))
+      (error:datum-out-of-range mark 'CLIP-MARK-TO-DISPLAY))
+  (cond ((group-display-start-index? (mark-group mark) (mark-index mark))
+        (group-display-start (mark-group mark)))
+       ((group-display-end-index? (mark-group mark) (mark-index mark))
+        (group-display-end (mark-group mark)))
+       (else
+        mark)))
 \f
-(define (y->inferiors window y)
-  (with-instance-variables buffer-window window (y)
-    (define (loop previous-inferiors inferiors)
-      (cond ((fix:< y (inferior-y-start (car inferiors))) previous-inferiors)
-           ((null? (cdr inferiors))
-            (and (fix:< y (inferior-y-end (car inferiors)))
-                 inferiors))
-           (else (loop inferiors (cdr inferiors)))))
-    (loop false line-inferiors)))
-
-(define (index->inferiors window index)
-  (with-instance-variables buffer-window window (index)
-    ;; Assumes that (>= INDEX (MARK-INDEX START-LINE-MARK)).
-    (define (loop inferiors start)
-      (let ((new-start (fix:+ start (line-inferior-length inferiors))))
-       (if (fix:< index new-start)
-           inferiors
-           (and (not (null? (cdr inferiors)))
-                (loop (cdr inferiors) new-start)))))
-    (loop line-inferiors (mark-index start-line-mark))))
-
-(define (inferiors->index window inferiors)
-  (with-instance-variables buffer-window window (inferiors)
-    ;; Assumes that INFERIORS is a tail of LINE-INFERIORS.
-    (define (loop inferiors* start)
-      (if (eq? inferiors inferiors*)
-         start
-         (loop (cdr inferiors*)
-               (fix:+ start (line-inferior-length inferiors*)))))
-    (loop line-inferiors (mark-index start-line-mark))))
-
-(define (y->inferiors&index window y receiver)
-  (with-instance-variables buffer-window window (y receiver)
-    ;; This is used for scrolling.
-    (define (loop inferiors start previous-inferiors previous-start)
-      (cond ((fix:< y (inferior-y-start (car inferiors)))
-            (receiver previous-inferiors previous-start))
-           ((null? (cdr inferiors))
-            (and (fix:< y (inferior-y-end (car inferiors)))
-                 (receiver inferiors start)))
-           (else
-            (loop (cdr inferiors)
-                  (fix:+ start (line-inferior-length inferiors))
-                  inferiors
-                  start))))
-    (loop line-inferiors (mark-index start-line-mark) false false)))
-
-(define (start-changes-inferiors window)
-  (with-instance-variables buffer-window window ()
-    ;; Assumes that (MARK<= START-LINE-MARK START-CHANGES-MARK).
-    ;; Guarantees to return non-'() result.
-    (or (index->inferiors window (mark-index start-changes-mark))
-       (error "Can't find START-CHANGES"))))
-
-(define (end-changes-inferiors window)
-  (with-instance-variables buffer-window window ()
-    ;; Assumes that (MARK<= END-CHANGES-MARK END-LINE-MARK).
-    ;; Guarantees to return non-'() result.
-    (let ((index (mark-index end-changes-mark)))
-      (define (loop inferiors not-found)
-       (if (null? inferiors)
-           (not-found (mark-index end-line-mark))
-           (loop (cdr inferiors)
-             (lambda (end)
-               (let ((new-end (fix:- end (line-inferior-length inferiors))))
-                 (if (fix:< new-end index)
-                     inferiors
-                     (not-found new-end)))))))
-      (loop line-inferiors
-       (lambda (end)
-         end                           ;ignore
-         (error "Can't find END-CHANGES"))))))
+;;;; Utilities
+
+(define-integrable (%window-extract-string window start end)
+  (group-extract-string (%window-group window) start end))
+
+(define-integrable (%window-modeline-event! window type)
+  (window-modeline-event! (window-superior window) type))
+
+(define-integrable (set-mark-index! mark index)
+  (set-mark-position!
+   mark
+   (group-index->position-integrable (mark-group mark)
+                                    index
+                                    (mark-left-inserting? mark))))
+
+(define-integrable (fix:max x y)
+  (if (fix:> x y) x y))
+
+(define-integrable (fix:min x y)
+  (if (fix:< x y) x y))
 \f
-;;;; Changes
-
-(define (update-cursor! window if-not-visible)
-  (with-instance-variables buffer-window window (if-not-invisible)
-    (if (%window-mark-visible? window point)
-       (begin
-         (set-inferior-position! cursor-inferior
-                                 (%window-mark->coordinates window point))
-         (set! point-moved? false))
-       (if-not-visible window))))
-
-(define (maybe-recenter! window)
-  (with-instance-variables buffer-window window ()
-    (let ((threshold (ref-variable scroll-step))
-         (recenter!
-          (lambda ()
-            (%window-redraw! window (%window-y-center window)))))
-      (if (not (object-type? (ucode-type fixnum) threshold))
-         (error "Not a small integer" threshold))
-      (if (fix:zero? threshold)
-         (recenter!)
-         (if (fix:< (mark-index point) (mark-index start-mark))
-             (let ((limit
-                    (%window-coordinates->index window
-                                                0
-                                                (fix:- 0 threshold))))
-               (if (or (not limit)
-                       (not (fix:< (mark-index point) limit)))
-                   (%window-scroll-y-relative! window
-                                               (%window-point-y window))
-                   (recenter!)))
-             (let ((limit
-                    (%window-coordinates->index window
-                                                0
-                                                (fix:+ (window-y-size window)
-                                                       threshold))))
-               (if (or (not limit) (fix:< (mark-index point) limit))
-                   (%window-scroll-y-relative!
-                    window
-                    (fix:- (%window-point-y window)
-                           (fix:-1+ (window-y-size window))))
-                   (recenter!))))))))
+;;;; Standard Methods
 
-(define-variable scroll-step
-  "*The number of lines to try scrolling a window by when point moves out.
-If that fails to bring point back on screen, point is centered instead.
-If this is zero, point is always centered after it moves off screen."
-  0)
+(define-method buffer-window (:initialize! window window*)
+  (usual=> window :initialize! window*)
+  (%reset-window-structures! window)
+  (%clear-window-buffer-state! window))
+
+(define-method buffer-window (:kill! window)
+  (without-interrupts (lambda () (%unset-window-buffer! window)))
+  (usual=> window :kill!))
+
+(define-method buffer-window (:salvage! window)
+  (without-interrupts
+   (lambda ()
+     (%set-window-point-index! window (%window-group-start-index window))
+     (%set-window-point-moved?! window 'SINCE-START-SET)
+     (%reset-window-structures! window)
+     (buffer-window/redraw! window))))
+
+(define-method buffer-window (:set-size! window x y)
+  (if (%window-debug-trace window)
+      ((%window-debug-trace window) 'window window 'set-size! x y))
+  (buffer-window/redraw! window)
+  (set-window-size! window x y)
+  (%set-window-point-moved?! window 'SINCE-START-SET))
+
+(define-method buffer-window (:set-x-size! window x)
+  (if (%window-debug-trace window)
+      ((%window-debug-trace window) 'window window 'set-x-size! x))
+  (buffer-window/redraw! window)
+  (set-window-x-size! window x)
+  (%set-window-point-moved?! window 'SINCE-START-SET))
 
-(define (%window-force-redraw! window redraw-type)
-  (with-instance-variables buffer-window window ()
-    (set! force-redraw? (or redraw-type 'CENTER))
-    (setup-redisplay-flags! redisplay-flags)))
-
-(define (%window-redraw-preserving-start! window)
-  (with-instance-variables buffer-window window ()
-    (let ((group (mark-group start-mark))
-         (start-line (mark-index start-line-mark)))
-      (let ((start (if truncate-lines? start-line (mark-index start-mark)))
-           (end (line-end-index group start-line)))
-       (let ((inferior (make-line-inferior window start-line end)))
-         (set-inferior-start!
-          inferior
-          0
-          (fix:- 0
-                 (string-base:index->y (inferior-window inferior)
-                                       (fix:- start start-line))))
-         (set-line-inferiors!
-          window
-          (cons inferior (fill-bottom window (inferior-y-end inferior) end))
-          start)))))
-  (everything-changed! window maybe-recenter!))
+(define-method buffer-window (:set-y-size! window y)
+  (if (%window-debug-trace window)
+      ((%window-debug-trace window) 'window window 'set-y-size! y))
+  (buffer-window/redraw! window)
+  (set-window-y-size! window y)
+  (%set-window-point-moved?! window 'SINCE-START-SET))
 \f
-(define (%window-redraw! window y)
-  (with-instance-variables buffer-window window (y)
-    (redraw-screen! window
-                   (if (not y)
-                       (%window-y-center window)
-                       (begin
-                         (if (or (fix:< y 0)
-                                 (not (fix:< y y-size)))
-                             (error "Attempt to scroll point off window" y))
-                         y))))
-  (everything-changed! window
-    (lambda (w)
-      (error "%WINDOW-REDRAW! left point offscreen -- get a wizard" w))))
-
-(define (redraw-screen! window y)
-  (with-instance-variables buffer-window window (y)
-    (let ((group (mark-group point))
-         (index (mark-index point)))
-      (let ((start (line-start-index group index)))
-       (let ((inferior
-              (make-line-inferior window start (line-end-index group index))))
-         (set-inferior-start!
-          inferior
-          0
-          (fix:- y
-                 (string-base:index->y (inferior-window inferior)
-                                       (fix:- index start))))
-         (fill-top! window (list inferior) start true))))))
-
-(define (everything-changed! window if-not-visible)
-  (with-instance-variables buffer-window window (if-not-visible)
-    (no-outstanding-changes! window)
-    (line-inferiors-changed! window)
-    (blank-inferior-changed! window)
-    (start-mark-changed! window)
-    (end-mark-changed! window)
-    (update-cursor! window if-not-visible)))
-
-(define (maybe-marks-changed! window inferiors y-end)
-  (with-instance-variables buffer-window window (inferiors y-end)
-    (no-outstanding-changes! window)
-    (if (and (eq? inferiors line-inferiors)
-            (fix:negative? (inferior-y-start (car inferiors))))
-       (start-mark-changed! window))
-    (if (and (null? (cdr inferiors))
-            (fix:> y-end y-size))
-       (end-mark-changed! window))
-    (update-cursor! window maybe-recenter!)))
-
-(define (no-outstanding-changes! window)
-  (with-instance-variables buffer-window window ()
-    (destroy-mark! start-changes-mark)
-    (set! start-changes-mark false)
-    (destroy-mark! end-changes-mark)
-    (set! end-changes-mark false)
-    (destroy-mark! start-clip-mark)
-    (set! start-clip-mark false)
-    (destroy-mark! end-clip-mark)
-    (set! end-clip-mark false)
-    (set! force-redraw? false)
-    unspecific))
+;;;; Update
+
+(define (buffer-window:update-display! window screen x-start y-start
+                                      xl xu yl yu display-style)
+  ;; Assumes that interrupts are disabled.
+  (if (%window-debug-trace window)
+      ((%window-debug-trace window) 'window window ':update-display!
+                                   screen x-start y-start xl xu yl yu
+                                   display-style))
+  (%set-window-saved-screen! window screen)
+  (%set-window-saved-x-start! window x-start)
+  (%set-window-saved-y-start! window y-start)
+  (%set-window-saved-xl! window xl)
+  (%set-window-saved-xu! window xu)
+  (%set-window-saved-yl! window yl)
+  (%set-window-saved-yu! window yu)
+  (update-buffer-window! window screen x-start y-start xl xu yl yu
+                        display-style))
+
+(define-method buffer-window :update-display!
+  buffer-window:update-display!)
+
+(define (buffer-window/direct-update! window display-style)
+  (if (%window-debug-trace window)
+      ((%window-debug-trace window) 'window window 'direct-update!
+                                   display-style))
+  (and (%window-saved-screen window)
+       (with-screen-in-update (%window-saved-screen window) display-style
+        (lambda ()
+          (let ((finished?
+                 (update-buffer-window! window
+                                        (%window-saved-screen window)
+                                        (%window-saved-x-start window)
+                                        (%window-saved-y-start window)
+                                        (%window-saved-xl window)
+                                        (%window-saved-xu window)
+                                        (%window-saved-yl window)
+                                        (%window-saved-yu window)
+                                        display-style)))
+            (if finished?
+                (set-car! (window-redisplay-flags window) false))
+            finished?)))))
+
+(define (update-buffer-window! window screen x-start y-start xl xu yl yu
+                              display-style)
+  (recompute-image! window)
+  (and (if (%window-override-inferior window)
+          (update-inferior! (%window-override-inferior window)
+                            screen x-start y-start xl xu yl yu display-style
+                            string-base:update-display!)
+          (update-inferiors! (%window-line-inferiors window)
+                             screen x-start y-start xl xu yl yu
+                             display-style string-base:update-display!))
+       (update-inferior! (%window-blank-inferior window)
+                        screen x-start y-start xl xu yl yu display-style
+                        blank-window:update-display!)
+       (update-inferior! (%window-cursor-inferior window)
+                        screen x-start y-start xl xu yl yu display-style
+                        cursor-window:update-display!)))
+
+(define (buffer-window/redraw! window)
+  (if (%window-debug-trace window)
+      ((%window-debug-trace window) 'window window 'force-redraw!))
+  (without-interrupts
+   (lambda ()
+     (%set-window-force-redraw?! window true)
+     (%clear-window-incremental-redisplay-state! window)
+     (window-needs-redisplay! window))))
+
+(define (buffer-window/cursor-enable! window)
+  (if (%window-debug-trace window)
+      ((%window-debug-trace window) 'window window 'cursor-enable!))
+  (=> (inferior-window (%window-cursor-inferior window)) :enable!))
+
+(define (buffer-window/cursor-disable! window)
+  (if (%window-debug-trace window)
+      ((%window-debug-trace window) 'window window 'cursor-disable!))
+  (=> (inferior-window (%window-cursor-inferior window)) :disable!))
+\f
+;;;; Window State
+
+(define (%reset-window-structures! window)
+  (set-window-inferiors! window '())
+  (%set-window-cursor-inferior! window (make-inferior window cursor-window))
+  (%set-window-blank-inferior! window (make-inferior window blank-window))
+  (%set-window-override-inferior! window false)
+  (%set-window-changes-daemon! window (make-changes-daemon window))
+  (%set-window-clip-daemon! window (make-clip-daemon window))
+  (%set-window-debug-trace! window false))
+
+(define (%clear-window-buffer-state! window)
+  (%set-window-buffer! window false)
+  (%set-window-point! window false)
+  (%set-window-truncate-lines?! window false)
+  (if (%window-start-line-mark window)
+      (clear-start-mark! window))
+  (%set-window-point-moved?! window false)
+  (%clear-window-incremental-redisplay-state! window))
+
+(define (%clear-window-incremental-redisplay-state! window)
+  (%set-window-line-inferiors! window '())
+  (set-window-inferiors! window
+                        (if (%window-override-inferior window)
+                            (list (%window-override-inferior window)
+                                  (%window-cursor-inferior window)
+                                  (%window-blank-inferior window))
+                            (list (%window-cursor-inferior window)
+                                  (%window-blank-inferior window))))
+  (if (%window-current-start-mark window)
+      (begin
+       (mark-temporary! (%window-current-start-mark window))
+       (mark-temporary! (%window-current-end-mark window))
+       (%set-window-current-start-mark! window false)
+       (%set-window-current-end-mark! window false)))
+  (%set-window-saved-screen! window false)
+  (%clear-window-outstanding-changes! window))
+
+(define-integrable (%clear-window-outstanding-changes! window)
+  (if (%window-start-changes-mark window)
+      (begin
+       (mark-temporary! (%window-start-changes-mark window))
+       (mark-temporary! (%window-end-changes-mark window))
+       (%set-window-start-changes-mark! window false)
+       (%set-window-end-changes-mark! window false)))
+  (if (%window-start-clip-mark window)
+      (begin
+       (mark-temporary! (%window-start-clip-mark window))
+       (mark-temporary! (%window-end-clip-mark window))
+       (%set-window-start-clip-mark! window false)
+       (%set-window-end-clip-mark! window false))))
 \f
-(define (start-mark-changed! window)
-  (with-instance-variables buffer-window window ()
-    (destroy-mark! start-mark)
-    (set! start-mark
-         (%make-permanent-mark
-          (buffer-group buffer)
-          (fix:+ (mark-index start-line-mark)
-                 (let ((inferior (first-line-inferior window)))
-                   (string-base:coordinates->index
-                    (inferior-window inferior)
-                    0
-                    (fix:- 0 (inferior-y-start inferior)))))
-          false))
-    (window-modeline-event! superior 'START-MARK-CHANGED!)))
-
-(define (end-mark-changed! window)
-  (with-instance-variables buffer-window window ()
-    (destroy-mark! end-mark)
-    (set! end-mark
-         (let ((group (buffer-group buffer)))
-           (%make-permanent-mark
-            group
-            (fix:+ (line-start-index group (mark-index end-line-mark))
-                   (string-base:coordinates->index
-                    (inferior-window last-line-inferior)
-                    (fix:-1+ x-size)
-                    (fix:-1+
-                     (fix:- (min y-size (inferior-y-end last-line-inferior))
-                            (inferior-y-start last-line-inferior)))))
-            true)))
-    (window-modeline-event! superior 'END-MARK-CHANGED!)))
-
-(define (destroy-mark! mark)
-  (if mark
-      (mark-temporary! mark)))
+;;;; Buffer and Point
 
-(define-integrable (%window-start-index window)
-  (with-instance-variables buffer-window window ()
-    (mark-index start-mark)))
+(define-integrable (buffer-window/buffer window)
+  (%window-buffer window))
+
+(define (buffer-window/set-buffer! window new-buffer)
+  ;; Interrupts must be disabled when this is called.
+  (if (%window-debug-trace window)
+      ((%window-debug-trace window) 'window window 'set-buffer! new-buffer))
+  (if (not (buffer? new-buffer))
+      (error:illegal-datum new-buffer 'set-window-buffer!))
+  (if (%window-buffer window)
+      (%unset-window-buffer! window))
+  (%set-window-buffer! window new-buffer)
+  (let ((group (%window-group window))
+       (changes-daemon (%window-changes-daemon window)))
+    (add-group-delete-daemon! group changes-daemon)
+    (add-group-insert-daemon! group changes-daemon)
+    (add-group-clip-daemon! group (%window-clip-daemon window))
+    (%set-window-point-index! window (mark-index (group-point group))))
+  (if (buffer-display-start new-buffer)
+      (set-new-coordinates! window
+                           (mark-index (buffer-display-start new-buffer))
+                           0
+                           false))
+  (buffer-window/redraw! window))
+
+(define (%unset-window-buffer! window)
+  ;; Interrupts must be disabled when this is called.
+  (let ((buffer (%window-buffer window)))
+    (if (%window-debug-trace window)
+       ((%window-debug-trace window) 'window window 'unset-buffer! buffer))
+    (set-buffer-display-start!
+     buffer
+     (mark-permanent! (buffer-window/start-mark window)))
+    (%set-buffer-point! buffer (buffer-window/point window)))
+  (let ((group (%window-group window))
+       (changes-daemon (%window-changes-daemon window)))
+    (remove-group-delete-daemon! group changes-daemon)
+    (remove-group-insert-daemon! group changes-daemon)
+    (remove-group-clip-daemon! group (%window-clip-daemon window)))
+  (%clear-window-buffer-state! window))
+
+(define-integrable (buffer-window/point window)
+  (%window-point window))
+
+(define (buffer-window/set-point! window mark)
+  (let ((mark (clip-mark-to-display window mark)))
+    (if (%window-debug-trace window)
+       ((%window-debug-trace window) 'window window 'set-point! mark))
+    (without-interrupts
+     (lambda ()
+       (%set-window-point-index! window (mark-index mark))
+       (%set-window-point-moved?! window 'SINCE-START-SET)
+       (%set-buffer-point! (%window-buffer window) mark)
+       (window-needs-redisplay! window)))))
+\f
+;;;; Start Mark
+
+(define (buffer-window/start-mark window)
+  (guarantee-start-mark! window)
+  (mark-temporary-copy (%window-start-mark window)))
+
+(define (buffer-window/set-start-mark! window mark force?)
+  (if (%window-debug-trace window)
+      ((%window-debug-trace window) 'window window 'set-start-mark! mark))
+  (set-new-coordinates! window
+                       (mark-index (clip-mark-to-display window mark))
+                       0
+                       (and force? (buffer-window/y-center window))))
+
+(define (buffer-window/scroll-y-relative! window y-delta)
+  (if (not (fix:= y-delta 0))
+      (begin
+       (if (%window-debug-trace window)
+           ((%window-debug-trace window) 'window window 'scroll-y-relative!
+                                         y-delta))
+       (guarantee-start-mark! window)
+       ;; if (> Y-DELTA 0) and line inferiors valid, use them.
+       (set-new-coordinates! window
+                             (%window-start-line-index window)
+                             (fix:- (%window-start-line-y window) y-delta)
+                             (if (fix:> y-delta 0)
+                                 0
+                                 (fix:- (window-y-size window) 1))))))
+
+(define (set-new-coordinates! window index y point-y)
+  (with-values (lambda () (predict-start-line window index y))
+    (lambda (start y-start)
+      (cond ((predict-index-visible? window start y-start
+                                    (%window-point-index window))
+            (without-interrupts
+             (lambda ()
+               (set-start-mark! window start y-start))))
+           (point-y
+            (without-interrupts
+             (lambda ()
+               (%set-window-point-index!
+                window
+                (or (predict-index window start y-start 0 point-y)
+                    (%window-group-end-index window)))
+               (set-start-mark! window start y-start))))))))
+
+(define (buffer-window/scroll-y-absolute! window y-point)
+  (if (%window-debug-trace window)
+      ((%window-debug-trace window) 'window window 'scroll-y-absolute!
+                                   y-point))
+  (if (not (and (fix:<= 0 y-point)
+               (fix:< y-point (window-y-size window))))
+      (error:datum-out-of-range y-point 'window-scroll-y-absolute!))
+  (with-values
+      (lambda ()
+       (predict-start-line window (%window-point-index window) y-point))
+    (lambda (start y-start)
+      (without-interrupts
+       (lambda ()
+        (set-start-mark! window start y-start))))))
+\f
+(define (set-start-mark! window start-line y-start)
+  (if (fix:= y-start 0)
+      (if (%window-start-line-mark window)
+         (begin
+           (set-mark-index! (%window-start-line-mark window) start-line)
+           (if (not (eq? (%window-start-line-mark window)
+                         (%window-start-mark window)))
+               (begin
+                 (mark-temporary! (%window-start-mark window))
+                 (%set-window-start-mark! window
+                                          (%window-start-line-mark window)))))
+         (let ((mark
+                (%make-permanent-mark (%window-group window)
+                                      start-line
+                                      false)))
+           (%set-window-start-line-mark! window mark)
+           (%set-window-start-mark! window mark)))
+      (let ((start (predict-start-index window start-line y-start)))
+       (if (%window-start-line-mark window)
+           (begin
+             (set-mark-index! (%window-start-line-mark window) start-line)
+             (if (eq? (%window-start-line-mark window)
+                      (%window-start-mark window))
+                 (%set-window-start-mark!
+                  window
+                  (%make-permanent-mark (%window-group window) start false))
+                 (set-mark-index! (%window-start-mark window) start)))
+           (let ((group (%window-group window)))
+             (%set-window-start-line-mark!
+              window
+              (%make-permanent-mark group start-line false))
+             (%set-window-start-mark!
+              window
+              (%make-permanent-mark group start false))))))
+  (%set-window-start-line-y! window y-start)
+  (if (eq? (%window-point-moved? window) 'SINCE-START-SET)
+      (%set-window-point-moved?! window true))
+  (window-needs-redisplay! window))
+
+(define-integrable (clear-start-mark! window)
+  (mark-temporary! (%window-start-line-mark window))
+  (mark-temporary! (%window-start-mark window))
+  (%set-window-start-line-mark! window false)
+  (%set-window-start-mark! window false)
+  (%set-window-start-line-y! window 0))
+\f
+(define (guarantee-start-mark! window)
+  (without-interrupts (lambda () (%guarantee-start-mark! window))))
+
+(define (%guarantee-start-mark! window)
+  (let ((point-at!
+        (lambda (y)
+          (with-values
+              (lambda ()
+                (predict-start-line window (%window-point-index window) y))
+            (lambda (start y-start)
+              (set-start-mark! window start y-start))))))
+    (let ((recenter! (lambda () (point-at! (buffer-window/y-center window)))))
+      (cond ((not (%window-start-line-mark window))
+            (recenter!))
+           ((eq? (%window-point-moved? window) 'SINCE-START-SET)
+            (let ((y
+                   (predict-y window
+                              (%window-start-line-index window)
+                              (%window-start-line-y window)
+                              (%window-point-index window))))
+              (cond ((fix:< y 0)
+                     (let ((y (fix:+ y (ref-variable scroll-step))))
+                       (if (fix:< y 0)
+                           (recenter!)
+                           (point-at! y))))
+                    ((fix:>= y (window-y-size window))
+                     (let ((y (fix:- y (ref-variable scroll-step))))
+                       (if (fix:>= y (window-y-size window))
+                           (recenter!)
+                           (point-at! y)))))))))))
 
-(define-integrable (%window-end-index window)
-  (with-instance-variables buffer-window window ()
-    (mark-index end-mark)))
+(define-variable scroll-step
+  "*The number of lines to try scrolling a window by when point moves out.
+If that fails to bring point back on screen, point is centered instead.
+If this is zero, point is always centered after it moves off screen."
+  0)
 
-(define-integrable (%window-mark-visible? window mark)
-  (with-instance-variables buffer-window window (mark)
-    (and (mark<= start-mark mark)
-        (mark<= mark end-mark))))
+(define-variable-value-validity-test (ref-variable-object scroll-step)
+  (lambda (scroll-step)
+    (and (fix:fixnum? scroll-step)
+        (fix:>= scroll-step 0))))
 
-(define (%window-y-center window)
-  (with-instance-variables buffer-window window ()
+(define (buffer-window/y-center window)
+  (let ((y-size (window-y-size window)))
     (let ((result
-          (integer-round
-           (* y-size
-              (inexact->exact (round (ref-variable cursor-centering-point))))
-           100)))
-      (cond ((fix:< result 0) 0)
-           ((fix:< result y-size) result)
-           (else (fix:-1+ y-size))))))
+          (round->exact
+           (* y-size (/ (ref-variable cursor-centering-point) 100)))))
+      (if (< result y-size)
+         result
+         (- y-size 1)))))
 
 (define-variable cursor-centering-point
   "The distance from the top of the window at which to center the point.
 This number is a percentage, where 0 is the window's top and 100 the bottom."
-  50)
\ No newline at end of file
+  50)
+
+(define-variable-value-validity-test
+  (ref-variable-object cursor-centering-point)
+  (lambda (value)
+    (and (real? value)
+        (<= 0 value 100))))
+\f
+;;;; Line Inferiors
+
+(define-class line-window string-base
+  ())
+
+(define-integrable (make-line-inferior window start end)
+  (%make-line-inferior window (%window-extract-string window start end)))
+
+(define (%make-line-inferior window string)
+  (let ((window* (make-object line-window))
+       (flags (cons false (window-redisplay-flags window))))
+    (let ((inferior (%make-inferior window* false false flags)))
+      (set-window-inferiors! window (cons inferior (window-inferiors window)))
+      (%set-window-superior! window* window)
+      (set-window-inferiors! window* '())
+      (%set-window-redisplay-flags! window* flags)
+      (%set-window-x-size! window* (window-x-size window))
+      (let ((*image (string->image string 0)))
+       (%set-window-y-size! window*
+                            (column->y-size (image-column-size *image)
+                                            (window-x-size window)
+                                            (%window-truncate-lines? window)))
+       (with-instance-variables line-window window*
+                                (*image %window-truncate-lines? window)
+         (set! image *image)
+         (set! truncate-lines? (%window-truncate-lines? window))))
+      (string-base:refresh! window*)
+      (%set-inferior-x-start! inferior 0)
+      inferior)))
+
+(define-integrable (line-window-image window)
+  (with-instance-variables line-window window () image))
+
+(define-integrable (line-window-string window)
+  (image-string (line-window-image window)))
+
+(define-integrable (line-window-length window)
+  (string-length (line-window-string window)))
+
+(define-integrable (line-inferior-length inferior)
+  (fix:+ (line-window-length (inferior-window inferior)) 1))
+
+(define (buffer-window/override-message window)
+  (let ((inferior (%window-override-inferior window)))
+    (and inferior
+        (line-window-string (inferior-window inferior)))))
+
+(define (buffer-window/set-override-message! window message)
+  (if (%window-debug-trace window)
+      ((%window-debug-trace window) 'window window 'set-override-message!
+                                   message))
+  (without-interrupts
+   (lambda ()
+     (let ((inferior (%make-line-inferior window message)))
+       (%set-window-override-inferior! window inferior)
+       (set-inferior-start! inferior 0 0)
+       (set-inferior-position!
+       (%window-cursor-inferior window)
+       (string-base:index->coordinates (inferior-window inferior)
+                                       (string-length message))))
+     (inferiors-changed! window))))
+
+(define (buffer-window/clear-override-message! window)
+  (if (%window-override-inferior window)
+      (begin
+       (if (%window-debug-trace window)
+           ((%window-debug-trace window) 'window window
+                                         'clear-override-message!))
+       (without-interrupts
+        (lambda ()
+          (%set-window-override-inferior! window false)
+          (update-cursor! window)
+          (inferiors-changed! window)
+          (for-each-inferior window inferior-needs-redisplay!))))))
+\f
+;;;; Update Finalization
+
+(define (set-line-inferiors! window inferiors)
+  (%set-window-line-inferiors! window inferiors)
+  (inferiors-changed! window)
+  (%clear-window-outstanding-changes! window)
+  (update-cursor! window)
+  (%window-modeline-event! window 'SET-LINE-INFERIORS))
+
+(define-integrable (set-current-end-index! window end)
+  (if (%window-current-start-mark window)
+      (begin
+       (set-mark-position! (%window-current-start-mark window)
+                           (mark-position (%window-start-line-mark window)))
+       (set-mark-index! (%window-current-end-mark window) end))
+      (begin
+       (%set-window-current-start-mark!
+        window
+        (mark-permanent-copy (%window-start-line-mark window)))
+       (%set-window-current-end-mark!
+        window
+        (%make-permanent-mark (%window-group window) end true)))))
+
+(define (inferiors-changed! window)
+  (let ((update-blank-inferior
+        (lambda (last-inferior)
+          (let ((y-end (%inferior-y-end last-inferior))
+                (inferior (%window-blank-inferior window)))
+            (if (fix:< y-end (window-y-size window))
+                (begin
+                  (%set-window-x-size! (inferior-window inferior)
+                                       (window-x-size window))
+                  (%set-window-y-size! (inferior-window inferior)
+                                       (fix:- (window-y-size window) y-end))
+                  (%set-inferior-x-start! inferior 0)
+                  (%set-inferior-y-start! inferior y-end)
+                  (setup-redisplay-flags!
+                   (inferior-redisplay-flags inferior)))
+                (begin
+                  (%set-inferior-x-start! inferior false)
+                  (%set-inferior-y-start! inferior false)))))))
+    (cond ((%window-override-inferior window)
+          (set-window-inferiors! window
+                                 (list (%window-override-inferior window)
+                                       (%window-cursor-inferior window)
+                                       (%window-blank-inferior window)))
+          (update-blank-inferior (%window-override-inferior window)))
+         ((not (null? (%window-line-inferiors window)))
+          (set-window-inferiors! window
+                                 (cons* (%window-cursor-inferior window)
+                                        (%window-blank-inferior window)
+                                        (%window-line-inferiors window)))
+          (update-blank-inferior
+           (car (last-pair (%window-line-inferiors window)))))
+         (else
+          (set-window-inferiors! window
+                                 (list (%window-cursor-inferior window)
+                                       (%window-blank-inferior window)))))))
+
+(define (update-cursor! window)
+  (let ((xy (buffer-window/point-coordinates window)))
+    (if (not (and (fix:<= 0 (car xy))
+                 (fix:< (car xy) (window-x-size window))
+                 (fix:<= 0 (cdr xy))
+                 (fix:< (cdr xy) (window-y-size window))))
+       (error "point not visible at end of redisplay"))
+    (set-inferior-position! (%window-cursor-inferior window) xy)))
\ No newline at end of file
index 18ddf231f6fa2498232b6881c2c33d0d0f124f44..fafe8a40f1d336c47e98040050b3bbda1406a786 100644 (file)
@@ -1,8 +1,8 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/bufwiu.scm,v 1.12 1989/08/14 09:22:07 cph Exp $
+;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/bufwiu.scm,v 1.13 1990/11/02 03:23:02 cph Rel $
 ;;;
-;;;    Copyright (c) 1986, 1989 Massachusetts Institute of Technology
+;;;    Copyright (c) 1986, 1989, 1990 Massachusetts Institute of Technology
 ;;;
 ;;;    This material was developed by the Scheme project at the
 ;;;    Massachusetts Institute of Technology, Department of
 ;;; of that license should have been included along with this file.
 ;;;
 
-;;;; Buffer Windows:  Image Update
+;;;; Buffer Windows: Image Update
 
 (declare (usual-integrations))
 \f
-;;;; Insert/Delete/Clip
-
-;;; It is assumed that the insert daemon is called after the insertion
-;;; has been performed, and the delete daemon before the deletion has
-;;; been performed.  It is also assumed that interrupts are disabled.
+;;;; Insert/Delete
 
 (define (make-changes-daemon window)
+  ;; It is assumed that the insert daemon is called after the
+  ;; insertion has been performed, and the delete daemon before the
+  ;; deletion has been performed.  It is also assumed that interrupts
+  ;; are disabled.
   (lambda (group start end)
-    (with-instance-variables buffer-window window (group start end)
-      (let ((start (group-index->position group start false))
-           (end (group-index->position group end true)))
-       (cond ((not start-changes-mark)
-              (set! start-changes-mark
-                    (%make-permanent-mark group start false))
-              (set! end-changes-mark (%make-permanent-mark group end true)))
-             ((fix:< start (mark-position start-changes-mark))
-              (set-mark-position! start-changes-mark start))
-             ((fix:> end (mark-position end-changes-mark))
-              (set-mark-position! end-changes-mark end)))
-       (if (and (not (car redisplay-flags))
-                (not (fix:< end (mark-position start-line-mark)))
-                (not (fix:> start (mark-position end-mark))))
-           (setup-redisplay-flags! redisplay-flags))))))
-
-;;; It is assumed that the clip daemon is called before the clipping
-;;; has been performed, so that we can get the old clipping limits.
+    (if (%window-debug-trace window)
+       ((%window-debug-trace window) 'window window 'change-daemon
+                                     group start end))
+    ;; Record changes that intersect the current line inferiors.
+    (if (and (not (%window-force-redraw? window))
+            (fix:<= (%window-current-start-index window) end)
+            (fix:<= start (%window-current-end-index window)))
+       ;; We can compare marks by their positions here because
+       ;; the marks being compared have the same
+       ;; LEFT-INSERTING? flag.
+       (let ((start
+              (group-index->position-integrable group start false))
+             (end (group-index->position-integrable group end true)))
+         (if (not (%window-start-changes-mark window))
+             (begin
+               (%set-window-start-changes-mark!
+                window
+                (%%make-permanent-mark group start false))
+               (%set-window-end-changes-mark!
+                window
+                (%%make-permanent-mark group end true)))
+             (begin
+               (if (fix:< start
+                          (mark-position
+                           (%window-start-changes-mark window)))
+                   (set-mark-position!
+                    (%window-start-changes-mark window)
+                    start))
+               (if (fix:> end
+                          (mark-position
+                           (%window-end-changes-mark window)))
+                   (set-mark-position! (%window-end-changes-mark window)
+                                       end))))
+         (window-needs-redisplay! window)))
+    ;; If this change affects where the window starts, choose a
+    ;; new place to start it.
+    (if (%window-start-line-mark window)
+       (begin
+         (if (let ((wlstart (%window-start-line-index window))
+                   (wstart (%window-start-index window)))
+               (and (if (fix:= wlstart wstart)
+                        (fix:< start wstart)
+                        (fix:<= start wstart))
+                    (fix:<= wlstart end)))
+             (begin
+               (clear-start-mark! window)
+               (window-needs-redisplay! window)))
+         (if (and (not (eq? (%window-point-moved? window)
+                            'SINCE-START-SET))
+                  (let ((point (%window-point-index window)))
+                    (and (fix:<= start point)
+                         (fix:<= point end))))
+             (%set-window-point-moved?! window 'SINCE-START-SET))))))
+\f
+;;;; Clip
 
 (define (make-clip-daemon window)
+  ;; It is assumed that the clip daemon is called before the clipping
+  ;; has been performed.  It is also assumed that interrupts are
+  ;; disabled.
   (lambda (group start end)
-    (with-instance-variables buffer-window window (group start end)
-      (if (not start-clip-mark)
-         (begin
-           (set! start-clip-mark (group-display-start group))
-           (set! end-clip-mark (group-display-end group))))
-      (if (not (car redisplay-flags))
-         (let ((start (group-index->position group start false))
-               (end (group-index->position group end true))
-               (window-start (mark-position start-line-mark))
-               (window-end (mark-position end-mark)))
-           (if (or (fix:> start window-start)
-                   (fix:< end window-end)
-                   (and (fix:< start window-start)
-                        (fix:= window-start (mark-position start-clip-mark)))
-                   (and (fix:> end window-end)
-                        (fix:= window-end (mark-position end-clip-mark))))
-               (setup-redisplay-flags! redisplay-flags)))))))
-
-(define (update-buffer-window! window screen x-start y-start
-                              xl xu yl yu display-style)
-  ;; The primary update entry.
-  (recompute-image! window)
-  (update-inferiors! window screen x-start y-start xl xu yl yu display-style))
-
-(define (maybe-recompute-image! window)
-  (with-instance-variables buffer-window window ()
-    ;; Used to guarantee everything updated before certain operations.
-    (if (car redisplay-flags)
-       (recompute-image! window))))
+    (if (not (%window-force-redraw? window))
+       (begin
+         (if (%window-debug-trace window)
+             ((%window-debug-trace window) 'window window 'clip-daemon
+                                           group start end))
+         (if (not (%window-start-clip-mark window))
+             (begin
+               (%set-window-start-clip-mark!
+                window
+                (%make-permanent-mark group
+                                      (group-display-start-index group)
+                                      true))
+               (%set-window-end-clip-mark!
+                window
+                (%make-permanent-mark group
+                                      (group-display-end-index group)
+                                      false))))
+         (let ((start (group-index->position-integrable group start true))
+               (end (group-index->position-integrable group end false)))
+           ;; We can compare marks by their positions here because the
+           ;; marks being compared have the same LEFT-INSERTING? flag.
+           (if (fix:> start (mark-position (%window-start-clip-mark window)))
+               (set-mark-position! (%window-start-clip-mark window) start))
+           (if (fix:< end (mark-position (%window-end-clip-mark window)))
+               (set-mark-position! (%window-end-clip-mark window) end)))
+         (if (and (not (window-needs-redisplay? window))
+                  (or (fix:>= (%window-start-clip-index window)
+                              (%window-current-start-index window))
+                      (fix:<= (%window-end-clip-index window)
+                              (%window-current-end-index window))))
+             (window-needs-redisplay! window))))
+    (if (and (%window-start-line-mark window)
+            (or (fix:>= start (%window-start-line-index window))
+                (fix:< end (%window-start-index window))))
+       (begin
+         (clear-start-mark! window)
+         (window-needs-redisplay! window)))))
 \f
-(define (recompute-image! window)
-  (with-instance-variables buffer-window window ()
-    (without-interrupts (lambda () (%recompute-image! window)))))
+;;;; Update
 
-(define (%recompute-image! window)
-  (with-instance-variables buffer-window window ()
-    (cond ((not force-redraw?)
-          (let ((group (mark-group start-mark))
-                (start-line (mark-index start-line-mark))
-                (start (mark-index start-mark))
-                (end (mark-index end-mark))
-                (point-index (mark-index point)))
-            (if start-clip-mark
-                (let ((new-clip-start (group-start-index group))
-                      (new-clip-end (group-end-index group)))
-                  (cond ((fix:< point-index new-clip-start)
-                         (%set-buffer-point! buffer
-                                             (group-display-start group))
-                         (set! point (buffer-point buffer)))
-                        ((fix:> point-index new-clip-end)
-                         (%set-buffer-point! buffer (group-display-end group))
-                         (set! point (buffer-point buffer))))
-                  (cond ((fix:> new-clip-start start-line)
-                         (%window-redraw! window false))
-                        ((or (fix:< new-clip-end end)
-                             (and (fix:< new-clip-start start-line)
-                                  (fix:= start-line
-                                         (mark-index start-clip-mark)))
-                             (and (fix:> new-clip-end end)
-                                  (fix:= end (mark-index end-clip-mark))))
-                         (%window-redraw! window
-                                          (and (not start-changes-mark)
-                                               (not (fix:< point-index start))
-                                               (not (fix:> point-index end))
-                                               (%window-point-y window))))
-                        (else
-                         (destroy-mark! start-clip-mark)
-                         (set! start-clip-mark false)
-                         (destroy-mark! end-clip-mark)
-                         (set! end-clip-mark false)))))
-            (if start-changes-mark
-                (let ((start-changes (mark-index start-changes-mark))
-                      (end-changes (mark-index end-changes-mark)))
-                  (if (and (not (fix:< end-changes start-line))
-                           (not (fix:> start-changes end)))
-                      (if (not (fix:> start-changes start))
-                          (if (fix:< end-changes end)
-                              (recompute-image!:top-changed window)
-                              (%window-redraw! window false))
-                          (if (not (fix:< end-changes end))
-                              (recompute-image!:bottom-changed window)
-                              (recompute-image!:middle-changed window)))
-                      (begin
-                        (destroy-mark! start-changes-mark)
-                        (set! start-changes-mark false)
-                        (destroy-mark! end-changes-mark)
-                        (set! end-changes-mark false))))))
-          (if point-moved?
-              (update-cursor! window maybe-recenter!)))
-         ((eq? 'START force-redraw?)
-          (%window-redraw-preserving-start! window))
-         ((eq? 'POINT force-redraw?)
-          (%window-redraw! window (%window-point-y window)))
-         ((eq? 'BUFFER-CURSOR-Y force-redraw?)
-          (%window-redraw! window (%window-buffer-cursor-y window)))
-         ((eq? 'CENTER force-redraw?)
-          (%window-redraw! window (%window-y-center window)))
-         ((and (object-type? (ucode-type fixnum) force-redraw?)
-               (not (fix:negative? force-redraw?))
-               (fix:< force-redraw? y-size))
-          (%window-redraw! window force-redraw?))
-         (else
-          (%window-redraw! window (%window-y-center window))))))
-\f
-(define (recompute-image!:top-changed window)
-  (with-instance-variables buffer-window window ()
-    (let ((inferiors (end-changes-inferiors window))
-         (group (mark-group end-changes-mark))
-         (index (mark-index end-changes-mark)))
-      (let ((start-index (line-start-index group index)))
-       (set-line-window-string!
-        (inferior-window (car inferiors))
-        (group-extract-string group start-index (line-end-index group index))
-        truncate-lines?)
-       (fill-top! window inferiors start-index true)))
-    (everything-changed! window maybe-recenter!)))
+(define (recompute-image! window)
+  (%guarantee-start-mark! window)
+  (if (%window-force-redraw? window)
+      (begin
+       (%set-window-force-redraw?! window false)
+       (preserve-nothing! window))
+      (let ((start (%window-current-start-index window))
+           (end (%window-current-end-index window)))
+       (cond ((and (%window-start-clip-mark window)
+                   (let ((start-clip (%window-start-clip-index window))
+                         (end-clip (%window-end-clip-index window)))
+                     (or (and (fix:<= start start-clip)
+                              (fix:<= (%window-group-start-index window)
+                                      end))
+                         (and (fix:<= end-clip end)
+                              (fix:<= start
+                                      (%window-group-end-index window))))))
+              (preserve-nothing! window))
+             ((%window-start-changes-mark window)
+              (let ((start-changes
+                     (let ((start-changes
+                            (%window-start-changes-index window)))
+                       (%window-line-start-index window start-changes)))
+                    (end-changes
+                     (let ((end-changes (%window-end-changes-index window)))
+                       (%window-line-end-index window end-changes))))
+                (if (fix:<= start-changes start)
+                    (if (fix:< end-changes end)
+                        (preserve-contiguous-region!
+                         window
+                         (cdr
+                          (changed-inferiors-tail
+                           (%window-line-inferiors window)
+                           end
+                           end-changes))
+                         (fix:+ end-changes 1))
+                        (preserve-nothing! window))
+                    (if (fix:< end-changes end)
+                        (preserve-top-and-bottom! window
+                                                  start start-changes
+                                                  end-changes end)
+                        (let ((inferiors (%window-line-inferiors window)))
+                          (set-cdr! (unchanged-inferiors-tail inferiors
+                                                              start
+                                                              start-changes)
+                                    '())
+                          (preserve-contiguous-region! window
+                                                       inferiors
+                                                       start))))))
+             (else
+              (preserve-all! window start))))))
 
-(define (recompute-image!:bottom-changed window)
-  (with-instance-variables buffer-window window ()
-    (let ((inferiors (start-changes-inferiors window))
-         (group (mark-group start-changes-mark))
-         (index (mark-index start-changes-mark)))
-      (let ((end-index (line-end-index group index)))
-       (set-line-window-string!
-        (inferior-window (car inferiors))
-        (group-extract-string group (line-start-index group index) end-index)
-        truncate-lines?)
-       (set-cdr! inferiors
-                 (fill-bottom window
-                              (inferior-y-end (car inferiors))
-                              end-index))))
-    (everything-changed! window maybe-recenter!)))
+(define-integrable (preserve-nothing! window)
+  (set-line-inferiors!
+   window
+   (generate-line-inferiors window
+                           (%window-start-line-index window)
+                           (%window-start-line-y window))))
 \f
-(define (recompute-image!:middle-changed window)
-  (with-instance-variables buffer-window window ()
-    (let ((start-inferiors (start-changes-inferiors window))
-         (end-inferiors (end-changes-inferiors window))
-         (group (buffer-group buffer))
-         (start-index (mark-index start-changes-mark))
-         (end-index (mark-index end-changes-mark)))
-      (let ((start-start (line-start-index group start-index))
-           (start-end (line-end-index group start-index))
-           (end-start (line-start-index group end-index))
-           (end-end (line-end-index group end-index)))
-       (if (eq? start-inferiors end-inferiors)
-           (if (fix:= start-start end-start)
+(define (preserve-contiguous-region! window inferiors start)
+  (let ((wlstart (%window-start-line-index window))
+       (wlsy (%window-start-line-y window)))
+    (set-line-inferiors!
+     window
+     (with-values
+        (lambda ()
+          (scroll-lines! window
+                         inferiors
+                         start
+                         (predict-y window wlstart wlsy start)))
+       (lambda (inferiors start)
+        (if (null? inferiors)
+            (generate-line-inferiors window wlstart wlsy)
+            (fill-edges! window inferiors start)))))))
 
-  ;; In this case, the changed region was a single line before the
-  ;; changes, and is still a single line now.  All we need do is redraw
-  ;; the line and then scroll the rest up or down if the y-size of the
-  ;; line has been changed.
-  (let ((y-end (inferior-y-end (car start-inferiors))))
-    (set-line-window-string!
-     (inferior-window (car start-inferiors))
-     (group-extract-string group start-start start-end)
-     truncate-lines?)
-    (let ((y-end* (inferior-y-end (car start-inferiors))))
-      (if (fix:= y-end y-end*)
-         (maybe-marks-changed! window start-inferiors y-end*)
-         (begin
-           (set-cdr! start-inferiors
-                     (cond ((fix:< y-end y-end*)
-                            (scroll-lines-down! window
-                                                (cdr start-inferiors)
-                                                y-end*))
-                           ((not (null? (cdr start-inferiors)))
-                            (scroll-lines-up! window
-                                              (cdr start-inferiors)
-                                              y-end*
-                                              (fix:1+ start-end)))
-                           (else
-                            (fill-bottom window y-end* start-end))))
-           (everything-changed! window maybe-recenter!)))))
+(define-integrable (fill-edges! window inferiors start)
+  (fill-top window (fill-bottom! window inferiors start) start))
 
-  ;; Here, the changed region used to be a single line, and now is
-  ;; several, so we need to insert a bunch of new lines.
-  (begin
-   (set-line-window-string! (inferior-window (car start-inferiors))
-                           (group-extract-string group start-start start-end)
-                           truncate-lines?)
-   (set-cdr! start-inferiors
-            (if (null? (cdr start-inferiors))
-                (fill-bottom window
-                             (inferior-y-end (car start-inferiors))
-                             start-end)
-                (fill-middle! window
-                              (inferior-y-end (car start-inferiors))
-                              start-end
-                              (cdr start-inferiors)
-                              (fix:1+ end-end))))
-   (everything-changed! window maybe-recenter!))
-  )
-;;; continued on next page...
+(define (preserve-all! window start)
+  (let ((wlstart (%window-start-line-index window))
+       (wlsy (%window-start-line-y window))
+       (inferiors (%window-line-inferiors window)))
+    (let ((scroll-down
+          (lambda (y-start)
+            (set-line-inferiors!
+             window
+             (let ((inferiors (scroll-lines-down! window inferiors y-start)))
+               (if (null? inferiors)
+                   (generate-line-inferiors window wlstart wlsy)
+                   (begin
+                     (let ((end
+                            (let loop ((inferiors inferiors) (start start))
+                              (if (null? (cdr inferiors))
+                                  (%window-line-end-index window start)
+                                  (loop (cdr inferiors)
+                                        (fix:+ start
+                                               (line-inferior-length
+                                                (car inferiors))))))))
+                       ;; SET-CURRENT-END-INDEX! is integrable
+                       (set-current-end-index! window end))
+                     (fill-top window inferiors start)))))))
+         (scroll-up
+          (lambda (y-start)
+            (set-line-inferiors!
+             window
+             (with-values
+                 (lambda () (scroll-lines-up! window inferiors start y-start))
+               (lambda (inferiors start)
+                 (if (null? inferiors)
+                     (generate-line-inferiors window wlstart wlsy)
+                     (fill-bottom! window inferiors start))))))))
+      (cond ((fix:= wlstart start)
+            (let ((y-start (inferior-y-start (car inferiors))))
+              (cond ((fix:= wlsy y-start)
+                     (%clear-window-outstanding-changes! window)
+                     (if (%window-point-moved? window)
+                         (begin
+                           (%set-window-point-moved?! window false)
+                           (update-cursor! window))))
+                    ((fix:< wlsy y-start)
+                     (scroll-up wlsy))
+                    (else
+                     (scroll-down wlsy)))))
+           ((fix:< wlstart start)
+            (scroll-down (predict-y window wlstart wlsy start)))
+           (else
+            (scroll-up (predict-y window wlstart wlsy start)))))))
 \f
-;;; ...continued from previous page
-
-  (if (fix:= start-start end-start)
+(define (preserve-top-and-bottom! window start start-changes end-changes end)
+  (let ((wlstart (%window-start-line-index window))
+       (wlsy (%window-start-line-y window))
+       (top-inferiors (%window-line-inferiors window)))
+    (let* ((top-tail
+           (unchanged-inferiors-tail top-inferiors start start-changes))
+          (middle-tail
+           (changed-inferiors-tail (cdr top-tail) end end-changes))
+          (bottom-inferiors (cdr middle-tail)))
+      (set-cdr! top-tail '())
+      (set-cdr! middle-tail '())
+      (with-values
+         (lambda ()
+           (scroll-lines! window
+                          top-inferiors
+                          start
+                          (predict-y window wlstart wlsy start)))
+       (lambda (top-inferiors top-start)
+         (with-values
+             (lambda ()
+               (let ((bottom-start (fix:+ end-changes 1)))
+                 (scroll-lines! window
+                                bottom-inferiors
+                                bottom-start
+                                (predict-y window wlstart wlsy
+                                           bottom-start))))
+           (lambda (bottom-inferiors bottom-start)
+             (set-line-inferiors!
+              window
+              (if (null? top-inferiors)
+                  (if (null? bottom-inferiors)
+                      (generate-line-inferiors window wlstart wlsy)
+                      (fill-edges! window bottom-inferiors bottom-start))
+                  (if (null? bottom-inferiors)
+                      (fill-edges! window top-inferiors top-start)
+                      (fill-top window
+                                (fill-middle! window
+                                              top-inferiors
+                                              top-start
+                                              (fill-bottom! window
+                                                            bottom-inferiors
+                                                            bottom-start)
+                                              bottom-start)
+                                top-start)))))))))))
 
-  ;; The changed region used to be multiple lines and is now just one.
-  ;; We must scroll the bottom of the screen up to fill in.
-  (begin
-   (set-line-window-string! (inferior-window (car start-inferiors))
-                           (group-extract-string group start-start start-end)
-                           truncate-lines?)
-   (set-cdr! start-inferiors
-            (if (null? (cdr end-inferiors))
-                (fill-bottom window
-                             (inferior-y-end (car start-inferiors))
-                             start-end)
-                (scroll-lines-up! window
-                                  (cdr end-inferiors)
-                                  (inferior-y-end (car start-inferiors))
-                                  (fix:1+ start-end))))
-   (everything-changed! window maybe-recenter!))
+(define (changed-inferiors-tail inferiors end end-changes)
+  (let find-end
+      ((inferiors inferiors)
+       (find-end-changes
+       (lambda (end)
+         end
+         (error "can't find END-CHANGES"))))
+    (if (null? inferiors)
+       (find-end-changes end)
+       (find-end (cdr inferiors)
+                 (lambda (end)
+                   (if (fix:= end end-changes)
+                       inferiors
+                       (find-end-changes
+                        (fix:- end
+                               (line-inferior-length (car inferiors))))))))))
 
-  ;; The most general case, we must refill the center of the screen.
-  (begin
-    (set-line-window-string!
-     (inferior-window (car start-inferiors))
-     (group-extract-string group start-start start-end)
-     truncate-lines?)
-    (let ((old-y-end (inferior-y-end (car end-inferiors))))
-      (set-line-window-string! (inferior-window (car end-inferiors))
-                              (group-extract-string group end-start end-end)
-                              truncate-lines?)
-      (let ((y-end (inferior-y-end (car end-inferiors)))
-           (tail (cdr end-inferiors)))
-       (cond ((fix:> y-end old-y-end)
-              (set-cdr! end-inferiors (scroll-lines-down! window tail y-end)))
-             ((fix:< y-end old-y-end)
-              (set-cdr! end-inferiors
-                        (scroll-lines-up! window
-                                          tail
-                                          y-end
-                                          (fix:1+ end-end)))))))
-    (set-cdr! start-inferiors
-             (fill-middle! window
-                           (inferior-y-end (car start-inferiors))
-                           start-end
-                           end-inferiors
-                           end-start))
-    (everything-changed! window maybe-recenter!))
-
-  ))))))
+(define (unchanged-inferiors-tail inferiors start start-changes)
+  (let loop ((inferiors inferiors) (start start))
+    (let ((start-next (fix:+ start (line-inferior-length (car inferiors)))))
+      (cond ((fix:>= start-next start-changes)
+            inferiors)
+           ((null? (cdr inferiors))
+            (error "can't find START-CHANGES"))
+           (else
+            (loop (cdr inferiors) start-next))))))
 \f
-;;;; Direct Update/Output Support
+;;;; Direct Output
 
 ;;; The direct output procedures are hairy and should be used only
 ;;; under restricted conditions.  In particular, the cursor may not be
 ;;; modifiable, and the modeline must already show that it has been
 ;;; modified.  None of the procedures may be used if the window needs
 ;;; redisplay.
-;;; They must be called without interrupts.
 
-(define (%window-direct-update! window display-style)
-  (with-instance-variables buffer-window window (display-style)
-    (if (not saved-screen)
-       (error "Window needs normal redisplay -- can't direct update" window))
-    (and (with-screen-in-update! saved-screen
-          (lambda ()
-            (update-buffer-window! window saved-screen
-                                   saved-x-start saved-y-start
-                                   saved-xl saved-xu saved-yl saved-yu
-                                   display-style)))
-        (begin
-          (set-car! redisplay-flags false)
-          true))))
+(define (buffer-window/needs-redisplay? window)
+  (if (or (window-needs-redisplay? window)
+         (not (%window-saved-screen window))
+         (screen-needs-update? (%window-saved-screen window)))
+      true
+      false))
+
+(define (buffer-window/direct-output-forward-char! window)
+  (if (%window-debug-trace window)
+      ((%window-debug-trace window) 'window window
+                                   'direct-output-forward-char!))
+  (without-interrupts
+   (lambda ()
+     (%set-window-point-index! window (fix:+ (%window-point-index window) 1))
+     (let ((x-start
+           (fix:1+ (inferior-x-start (%window-cursor-inferior window))))
+          (y-start (inferior-y-start (%window-cursor-inferior window))))
+       (screen-direct-output-move-cursor
+       (%window-saved-screen window)
+       (fix:+ (%window-saved-x-start window) x-start)
+       (fix:+ (%window-saved-y-start window) y-start))
+       (%set-inferior-x-start! (%window-cursor-inferior window) x-start)))))
 
-(define (%direct-output-forward-character! window)
-  (with-instance-variables buffer-window window ()
-   (%set-buffer-point! buffer (mark1+ point))
-   (set! point (buffer-point buffer))
-   (let ((x-start (fix:1+ (inferior-x-start cursor-inferior)))
-        (y-start (inferior-y-start cursor-inferior)))
-     (screen-write-cursor! saved-screen
-                          (fix:+ saved-x-start x-start)
-                          (fix:+ saved-y-start y-start))
-     (screen-flush! saved-screen)
-     (%set-inferior-x-start! cursor-inferior x-start))))
+(define (buffer-window/direct-output-backward-char! window)
+  (if (%window-debug-trace window)
+      ((%window-debug-trace window) 'window window
+                                   'direct-output-backward-char!))
+  (without-interrupts
+   (lambda ()
+     (%set-window-point-index! window (fix:- (%window-point-index window) 1))
+     (let ((x-start
+           (fix:-1+ (inferior-x-start (%window-cursor-inferior window))))
+          (y-start (inferior-y-start (%window-cursor-inferior window))))
+       (screen-direct-output-move-cursor
+       (%window-saved-screen window)
+       (fix:+ (%window-saved-x-start window) x-start)
+       (fix:+ (%window-saved-y-start window) y-start))
+       (%set-inferior-x-start! (%window-cursor-inferior window) x-start)))))
 
-(define (%direct-output-backward-character! window)
-  (with-instance-variables buffer-window window ()
-   (%set-buffer-point! buffer (mark-1+ point))
-   (set! point (buffer-point buffer))
-   (let ((x-start (fix:-1+ (inferior-x-start cursor-inferior)))
-        (y-start (inferior-y-start cursor-inferior)))
-     (screen-write-cursor! saved-screen
-                          (fix:+ saved-x-start x-start)
-                          (fix:+ saved-y-start y-start))
-     (screen-flush! saved-screen)
-     (%set-inferior-x-start! cursor-inferior x-start))))
+(define (buffer-window/home-cursor! window)
+  (if (%window-debug-trace window)
+      ((%window-debug-trace window) 'window window 'home-cursor!))
+  (if (and (%window-saved-screen window)
+          (fix:<= (%window-saved-xl window) 0)
+          (fix:< 0 (%window-saved-xu window))
+          (fix:<= (%window-saved-yl window) 0)
+          (fix:< 0 (%window-saved-yu window)))
+      (without-interrupts
+       (lambda ()
+        (screen-direct-output-move-cursor (%window-saved-screen window)
+                                          (%window-saved-x-start window)
+                                          (%window-saved-y-start window))))))
 \f
-(define (%direct-output-insert-char! window char)
-  (with-instance-variables buffer-window window (char)
-   (let ((x-start (inferior-x-start cursor-inferior))
-        (y-start (inferior-y-start cursor-inferior)))
-     (let ((x (fix:+ saved-x-start x-start))
-          (y (fix:+ saved-y-start y-start)))
-       (screen-write-char! saved-screen x y char)
-       (screen-write-cursor! saved-screen (fix:1+ x) y)
-       (screen-flush! saved-screen))
-     (line-window-direct-output-insert-char!
-      (inferior-window (car (y->inferiors window y-start)))
-      x-start
-      char)
-     (%set-inferior-x-start! cursor-inferior (fix:1+ x-start)))))
+(define (buffer-window/direct-output-insert-char! window char)
+  (if (%window-debug-trace window)
+      ((%window-debug-trace window) 'window window
+                                   'direct-output-insert-char! char))
+  (without-interrupts
+   (lambda ()
+     (%group-insert-char! (%window-group window)
+                         (%window-point-index window)
+                         char)
+     (let ((x-start (inferior-x-start (%window-cursor-inferior window)))
+          (y-start (inferior-y-start (%window-cursor-inferior window))))
+       (screen-direct-output-char
+       (%window-saved-screen window)
+       (fix:+ (%window-saved-x-start window) x-start)
+       (fix:+ (%window-saved-y-start window) y-start)
+       char
+       false)
+       (string-base:direct-output-insert-char!
+       (direct-output-line-window window y-start)
+       x-start
+       char)
+       (%set-inferior-x-start! (%window-cursor-inferior window)
+                              (fix:+ x-start 1))))))
 
-(define (%direct-output-insert-newline! window)
-  (with-instance-variables buffer-window window ()
-   (let ((y-start (fix:1+ (inferior-y-start cursor-inferior))))
-     (let ((inferior (make-inferior window line-window)))
-       (%set-inferior-x-start! inferior 0)
-       (%set-inferior-y-start! inferior y-start)
-       (set-cdr! (last-pair line-inferiors) (list inferior))
-       (set! last-line-inferior inferior)
-       (line-window-direct-output-insert-newline!
-       (inferior-window inferior)))
-     (let ((y-end (fix:1+ y-start)))
-       (if (fix:< y-end y-size)
-          (begin
-            (%set-inferior-y-size! blank-inferior (fix:- y-size y-end))
-            (%set-inferior-y-start! blank-inferior y-end))
-          (begin
-            (%set-inferior-x-start! blank-inferior false)
-            (%set-inferior-y-start! blank-inferior false))))
-     (%set-inferior-x-start! cursor-inferior 0)
-     (%set-inferior-y-start! cursor-inferior y-start)
-     (screen-write-cursor! saved-screen
-                          saved-x-start
-                          (fix:+ saved-y-start y-start))
-     (screen-flush! saved-screen))))
+(define (buffer-window/direct-output-insert-substring! window string start end)
+  (if (%window-debug-trace window)
+      ((%window-debug-trace window) 'window window
+                                   'direct-output-insert-substring!
+                                   (string-copy string) start end))
+  (without-interrupts
+   (lambda ()
+     (%group-insert-substring! (%window-group window)
+                              (%window-point-index window)
+                              string start end)
+     (let ((x-start (inferior-x-start (%window-cursor-inferior window)))
+          (y-start (inferior-y-start (%window-cursor-inferior window)))
+          (length (fix:- end start)))
+       (screen-direct-output-substring
+       (%window-saved-screen window)
+       (fix:+ (%window-saved-x-start window) x-start)
+       (fix:+ (%window-saved-y-start window) y-start)
+       string start end
+       false)
+       (string-base:direct-output-insert-substring!
+       (direct-output-line-window window y-start)
+       x-start
+       string start end)
+       (%set-inferior-x-start! (%window-cursor-inferior window)
+                              (fix:+ x-start length))))))
 
-(define (%direct-output-insert-substring! window string start end)
-  (with-instance-variables buffer-window window (string start end)
-   (let ((x-start (inferior-x-start cursor-inferior))
-        (y-start (inferior-y-start cursor-inferior))
-        (length (fix:- end start)))
-     (let ((x (fix:+ saved-x-start x-start))
-          (y (fix:+ saved-y-start y-start)))
-       (screen-write-substring! saved-screen x y string start end)
-       (screen-write-cursor! saved-screen (fix:+ x length) y)
-       (screen-flush! saved-screen))
-     (line-window-direct-output-insert-substring!
-      (inferior-window (car (y->inferiors window y-start)))
-      x-start
-      string start end)
-     (%set-inferior-x-start! cursor-inferior (fix:+ x-start length)))))
\ No newline at end of file
+(define (direct-output-line-window window y)
+  (let loop ((inferiors (%window-line-inferiors window)))
+    (if (fix:< y (%inferior-y-end (car inferiors)))
+       (inferior-window (car inferiors))
+       (loop (cdr inferiors)))))
+\f
+(define (buffer-window/direct-output-insert-newline! window)
+  (if (%window-debug-trace window)
+      ((%window-debug-trace window) 'window window
+                                   'direct-output-insert-newline!))
+  (without-interrupts
+   (lambda ()
+     (%group-insert-char! (%window-group window)
+                         (%window-point-index window)
+                         #\newline)
+     (let ((y-start
+           (fix:+ (inferior-y-start (%window-cursor-inferior window)) 1)))
+       (let ((inferior (make-inferior window line-window)))
+        (%set-inferior-x-start! inferior 0)
+        (%set-inferior-y-start! inferior y-start)
+        (%set-window-x-size! (inferior-window inferior)
+                             (window-x-size window))
+        (set-cdr! (last-pair (%window-line-inferiors window)) (list inferior))
+        (string-base:direct-output-insert-newline!
+         (inferior-window inferior)))
+       (let ((inferior (%window-blank-inferior window))
+            (y-end (fix:+ y-start 1)))
+        (if (fix:< y-end (window-y-size window))
+            (begin
+              (%set-inferior-y-size! inferior
+                                     (fix:- (window-y-size window) y-end))
+              (%set-inferior-y-start! inferior y-end))
+            (begin
+              (%set-inferior-x-start! inferior false)
+              (%set-inferior-y-start! inferior false))))
+       (%set-inferior-x-start! (%window-cursor-inferior window) 0)
+       (%set-inferior-y-start! (%window-cursor-inferior window) y-start)
+       (screen-direct-output-move-cursor (%window-saved-screen window)
+                                        (%window-saved-x-start window)
+                                        (fix:+ (%window-saved-y-start window)
+                                               y-start))))))
\ No newline at end of file
index 6ca54950bd8397b40087196fd1cfeedfa5181962..dcc3da2c6fcdd95afe6b247cdc8fe8aad2f4cdbf 100644 (file)
@@ -1,8 +1,8 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/bufwmc.scm,v 1.7 1989/08/14 09:22:12 cph Exp $
+;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/bufwmc.scm,v 1.8 1990/11/02 03:23:08 cph Rel $
 ;;;
-;;;    Copyright (c) 1986, 1989 Massachusetts Institute of Technology
+;;;    Copyright (c) 1986, 1989, 1990 Massachusetts Institute of Technology
 ;;;
 ;;;    This material was developed by the Scheme project at the
 ;;;    Massachusetts Institute of Technology, Department of
 ;;; of that license should have been included along with this file.
 ;;;
 
-;;;; Buffer Windows:  Mark <-> Coordinate Maps
+;;;; Buffer Windows: Mark <-> Coordinate Maps
 
 (declare (usual-integrations))
 \f
-(define-integrable (%window-mark->x window mark)
-  (car (%window-mark->coordinates window mark)))
-
-(define-integrable (%window-mark->y window mark)
-  (cdr (%window-mark->coordinates window mark)))
-
-(define (%window-point-x window)
-  (with-instance-variables buffer-window window ()
-    (car (%window-mark->coordinates window point))))
-
-(define (%window-point-y window)
-  (with-instance-variables buffer-window window ()
-    (cdr (%window-mark->coordinates window point))))
-
-(define (%window-point-coordinates window)
-  (with-instance-variables buffer-window window ()
-    (%window-mark->coordinates window point)))
-
-(define-integrable (%window-mark->coordinates window mark)
-  (%window-index->coordinates window (mark-index mark)))
-
-(define (%window-coordinates->mark window x y)
-  (with-instance-variables buffer-window window (x y)
-    (let ((index (%window-coordinates->index window x y)))
-      (and index (make-mark (buffer-group buffer) index)))))
-
-(define (%window-index->coordinates window index)
-  (with-instance-variables buffer-window window (index)
-    (let ((group (buffer-group buffer)))
-      (define (search-upwards end y-end)
-       (let ((start (line-start-index group end)))
-         (let ((columns (group-column-length group start end 0)))
-           (let ((y-start
-                  (fix:- y-end
-                         (column->y-size columns x-size truncate-lines?))))
-             (if (fix:> start index)
-                 (search-upwards (fix:-1+ start) y-start)
-                 (done start columns y-start))))))
-
-      (define (search-downwards start y-start)
-       (let ((end (line-end-index group start)))
-         (let ((columns (group-column-length group start end 0)))
-           (if (fix:> index end)
-               (search-downwards (fix:1+ end)
-                                 (fix:+ y-start
-                                        (column->y-size columns
-                                                        x-size
-                                                        truncate-lines?)))
-               (done start columns y-start)))))
-
-      (define-integrable (done start columns y-start)
-       (let ((xy
-              (column->coordinates columns
-                                   x-size
-                                   truncate-lines?
-                                   (group-column-length group
-                                                        start
-                                                        index
-                                                        0))))
-         (cons (car xy) (fix:+ (cdr xy) y-start))))
-
-      (let ((start (mark-index start-line-mark))
-           (end (mark-index end-line-mark)))
-       (cond ((fix:< index start)
-              (search-upwards (fix:-1+ start)
-                              (inferior-y-start
-                               (first-line-inferior window))))
-             ((fix:> index end)
-              (search-downwards (fix:1+ end)
-                                (inferior-y-end last-line-inferior)))
-             (else
-              (let ((start (line-start-index group index)))
-                (done start
-                      (group-column-length group start
-                                           (line-end-index group index) 0)
-                      (inferior-y-start
-                       (car (index->inferiors window index)))))))))))
+(define-integrable (buffer-window/mark->x window mark)
+  (buffer-window/index->x window (mark-index mark)))
+
+(define-integrable (buffer-window/mark->y window mark)
+  (buffer-window/index->y window (mark-index mark)))
+
+(define-integrable (buffer-window/mark->coordinates window mark)
+  (buffer-window/index->coordinates window (mark-index mark)))
+
+(define-integrable (buffer-window/point-x window)
+  (buffer-window/index->x window (%window-point-index window)))
+
+(define-integrable (buffer-window/point-y window)
+  (buffer-window/index->y window (%window-point-index window)))
+
+(define-integrable (buffer-window/point-coordinates window)
+  (buffer-window/index->coordinates window (%window-point-index window)))
+
+(define (buffer-window/index->x window index)
+  (if (and (line-inferiors-valid? window)
+          (line-inferiors-contain-index? window index))
+      (with-values (lambda () (find-inferior-containing-index window index))
+       (lambda (inferior start)
+         (fix:+ (inferior-x-start inferior)
+                (string-base:index->x (inferior-window inferior)
+                                      (fix:- index start)))))
+      (let ((start (%window-line-start-index window index)))
+       (%window-column->x window
+                          (%window-line-columns window start index)
+                          (%window-column-length window start index 0)))))
+
+(define (buffer-window/index->y window index)
+  (if (and (line-inferiors-valid? window)
+          (line-inferiors-contain-index? window index))
+      (with-values (lambda () (find-inferior-containing-index window index))
+       (lambda (inferior start)
+         (fix:+ (inferior-y-start inferior)
+                (string-base:index->y (inferior-window inferior)
+                                      (fix:- index start)))))
+      (begin
+       (guarantee-start-mark! window)
+       (predict-y window
+                  (%window-start-line-index window)
+                  (%window-start-line-y window)
+                  index))))
+
+(define (buffer-window/index->coordinates window index)
+  (if (and (line-inferiors-valid? window)
+          (line-inferiors-contain-index? window index))
+      (with-values (lambda () (find-inferior-containing-index window index))
+       (lambda (inferior start)
+         (let ((xy
+                (string-base:index->coordinates (inferior-window inferior)
+                                                (fix:- index start))))
+           (cons (fix:+ (car xy) (inferior-x-start inferior))
+                 (fix:+ (cdr xy) (inferior-y-start inferior))))))
+      (begin
+       (guarantee-start-mark! window)
+       (let ((start (%window-line-start-index window index)))
+         (let ((xy
+                (%window-column->coordinates
+                 window
+                 (%window-line-columns window start index)
+                 (%window-column-length window start index 0))))
+           (cons (car xy)
+                 (fix:+ (cdr xy)
+                        (predict-y window
+                                   (%window-start-line-index window)
+                                   (%window-start-line-y window)
+                                   start))))))))
+\f
+(define (buffer-window/coordinates->mark window x y)
+  (let ((index (buffer-window/coordinates->index window x y)))
+    (and index
+        (make-mark (%window-group window) index))))
+
+(define (buffer-window/coordinates->index window x y)
+  (with-values
+      (lambda ()
+       (if (line-inferiors-valid? window)
+           (find-inferior-containing-y window y)
+           (values false false)))
+    (lambda (inferior start)
+      (if inferior
+         (fix:+ start
+                (string-base:coordinates->index
+                 (inferior-window inferior)
+                 x
+                 (fix:- y (inferior-y-start inferior))))
+         (begin
+           (guarantee-start-mark! window)
+           (predict-index window
+                          (%window-start-line-index window)
+                          (%window-start-line-y window)
+                          x
+                          y))))))
+
+(define (buffer-window/mark-visible? window mark)
+  ;; True iff cursor at this position would be on-screen.
+  (let ((index (mark-index mark)))
+    (if (line-inferiors-valid? window)
+       (and (line-inferiors-contain-index? window index)
+            (fix:<= (%window-start-index window) index)
+            (with-values
+                (lambda () (find-inferior-containing-index window index))
+              (lambda (inferior start)
+                (let ((limit
+                       (fix:- (window-y-size window)
+                              (inferior-y-start inferior))))
+                  (or (fix:< (inferior-y-size inferior) limit)
+                      (fix:< (string-base:index->y (inferior-window inferior)
+                                                   (fix:- index start))
+                             limit))))))
+       (begin
+         (guarantee-start-mark! window)
+         (predict-index-visible? window
+                                 (%window-start-line-index window)
+                                 (%window-start-line-y window)
+                                 index)))))
+\f
+(define-integrable (line-inferiors-valid? window)
+  (and (not (%window-start-changes-mark window))
+       (not (%window-start-clip-mark window))
+       (not (%window-point-moved? window))
+       (not (%window-force-redraw? window))
+       (%window-start-line-mark window)
+       (fix:= (mark-position (%window-start-line-mark window))
+             (mark-position (%window-current-start-mark window)))))
+
+(define-integrable (line-inferiors-contain-index? window index)
+  (and (fix:<= (%window-current-start-index window) index)
+       (fix:<= index (%window-current-end-index window))))
+
+(define (find-inferior-containing-index window index)
+  (let loop
+      ((inferiors (%window-line-inferiors window))
+       (start (%window-current-start-index window)))
+    (let ((start* (fix:+ start (line-inferior-length (car inferiors)))))
+      (if (fix:< index start*)
+         (values (car inferiors) start)
+         (loop (cdr inferiors) start*)))))
+
+(define (find-inferior-containing-y window y)
+  (let ((inferiors (%window-line-inferiors window)))
+    (if (fix:< y (inferior-y-start (car inferiors)))
+       (values false false)
+       (let loop
+           ((inferiors inferiors)
+            (start (%window-current-start-index window)))
+         (cond ((fix:< y (%inferior-y-end (car inferiors)))
+                (values (car inferiors) start))
+               ((null? (cdr inferiors))
+                (values false false))
+               (else
+                (loop (cdr inferiors)
+                      (fix:+ start
+                             (line-inferior-length (car inferiors))))))))))
 \f
-(define (%window-coordinates->index window x y)
-  (with-instance-variables buffer-window window (x y)
-    (let ((group (buffer-group buffer)))
-      (define (search-upwards start y-end)
-       (and (not (group-start-index? group start))
-            (let ((end (fix:-1+ start)))
-              (let ((start (line-start-index group end)))
-                (let ((y-start (fix:- y-end (y-delta start end))))
-                  (if (fix:> y-start y)
-                      (search-upwards start y-start)
-                      (done start end y-start)))))))
-
-      (define (search-downwards end y-start)
-       (and (not (group-end-index? group end))
-            (let ((start (fix:1+ end)))
-              (let ((end (line-end-index group start)))
-                (let ((y-end (fix:+ y-start (y-delta start end))))
-                  (if (fix:< y y-end)
-                      (done start end y-start)
-                      (search-downwards end y-end)))))))
-
-      (define-integrable (y-delta start end)
-       (column->y-size (group-column-length group start end 0)
-                       x-size
-                       truncate-lines?))
-
-      (define (done start end y-start)
-       (let ((column-size (group-column-length group start end 0)))
-         (if (and truncate-lines? (fix:= x (fix:-1+ x-size)))
-             column-size
-             (group-column->index group start end 0
-                                  (min (coordinates->column x
-                                                            (fix:- y y-start)
-                                                            x-size)
-                                       column-size)))))
-
-      (let ((start (inferior-y-start (first-line-inferior window)))
-           (end (inferior-y-end last-line-inferior)))
-       (cond ((fix:< y start)
-              (search-upwards (mark-index start-line-mark) start))
-             ((not (fix:< y end))
-              (search-downwards (mark-index end-line-mark) end))
-             (else
-              (y->inferiors&index window y
-                (lambda (inferiors index)
-                  (done index
-                        (line-end-index group index)
-                        (inferior-y-start (car inferiors)))))))))))
\ No newline at end of file
+(define (predict-y window start y index)
+  ;; Assuming that the character at index START appears at coordinate
+  ;; Y, return the coordinate for the character at INDEX.  START is
+  ;; assumed to be a line start.
+  (cond ((fix:= index start)
+        y)
+       ((fix:< index start)
+        (let loop ((start start) (y y))
+          (let* ((end (fix:- start 1))
+                 (start (%window-line-start-index window end))
+                 (columns (%window-column-length window start end 0))
+                 (y (fix:- y (%window-column->y-size window columns))))
+            (if (fix:< index start)
+                (loop start y)
+                (fix:+ y (%window-line-y window columns start index))))))
+       (else
+        (let loop ((start start) (y y))
+          (let* ((end (%window-line-end-index window start))
+                 (columns (%window-column-length window start end 0)))
+            (if (fix:> index end)
+                (loop (fix:+ end 1)
+                      (fix:+ y (%window-column->y-size window columns)))
+                (fix:+ y (%window-line-y window columns start index))))))))
+
+(define (predict-index-visible? window start y index)
+  (and (fix:>= index start)
+       (let ((y-size (window-y-size window)))
+        (let loop ((start start) (y y))
+          (and (fix:< y y-size)
+               (let* ((end (%window-line-end-index window start))
+                      (columns (%window-column-length window start end 0)))
+                 (if (fix:> index end)
+                     (loop (fix:+ end 1)
+                           (fix:+ y (%window-column->y-size window columns)))
+                     (let ((y
+                            (fix:+
+                             y
+                             (%window-line-y window columns start index))))
+                       (and (fix:<= 0 y) (fix:< y y-size))))))))))
+
+(define (predict-index window start y-start x y)
+  ;; Assumes that START is a line start.
+  (if (fix:< y y-start)
+      (let loop ((start start) (y-start y-start))
+       (and (not (%window-group-start-index? window start))
+            (let* ((end (fix:- start 1))
+                   (start (%window-line-start-index window end))
+                   (columns (%window-column-length window start end 0))
+                   (y-start
+                    (fix:- y-start (%window-column->y-size window columns))))
+              (if (fix:< y y-start)
+                  (loop start y-start)
+                  (%window-coordinates->index window start end columns
+                                              x (fix:- y y-start))))))
+      (let loop ((start start) (y-start y-start))
+       (let* ((end (%window-line-end-index window start))
+              (columns (%window-column-length window start end 0))
+              (y-end
+               (fix:+ y-start (%window-column->y-size window columns))))
+         (if (fix:>= y y-end)
+             (and (not (%window-group-end-index? window end))
+                  (loop (fix:+ end 1) y-end))
+             (%window-coordinates->index window start end columns
+                                         x (fix:- y y-start)))))))
+\f
+(define (predict-start-line window index y)
+  (let ((start (%window-line-start-index window index)))
+    (let ((y
+          (fix:- y
+                 (%window-line-y window
+                                 (%window-line-columns window start index)
+                                 start
+                                 index))))
+      (cond ((fix:= y 0)
+            (values start y))
+           ((fix:< y 0)
+            (let loop ((start start) (y y))
+              (let* ((end (%window-line-end-index window start))
+                     (columns (%window-column-length window start end 0))
+                     (y-end
+                      (fix:+ y (%window-column->y-size window columns))))
+                (if (and (fix:<= y-end 0)
+                         (not (%window-group-end-index? window end)))
+                    (loop (fix:+ end 1) y-end)
+                    (values start y)))))
+           (else
+            (let loop ((start start) (y y))
+              (if (%window-group-start-index? window start)
+                  (values start 0)
+                  (let* ((end (fix:- start 1))
+                         (start (%window-line-start-index window end))
+                         (columns (%window-column-length window start end 0))
+                         (y-start
+                          (fix:- y (%window-column->y-size window columns))))
+                    (if (fix:<= y-start 0)
+                        (values start y-start)
+                        (loop start y-start))))))))))
+
+(define (predict-start-index window start y-start)
+  ;; Assumes (AND (%WINDOW-LINE-START-INDEX? WINDOW START) (<= Y-START 0))
+  (if (fix:= 0 y-start)
+      start
+      (let ((end (%window-line-end-index window start))
+           (y (fix:- 0 y-start)))
+       (let ((length (%window-column-length window start end 0)))
+         (let ((index
+                (%window-coordinates->index window start end length 0 y)))
+           (if (let ((xy
+                      (%window-index->coordinates window start length index)))
+                 (and (fix:= (car xy) 0)
+                      (fix:= (cdr xy) y)))
+               index
+               (fix:+ index 1)))))))
+
+(define (compute-start-index inferior start)
+  (let ((y-start (inferior-y-start inferior)))
+    (if (fix:= 0 y-start)
+       start
+       (let ((window (inferior-window inferior))
+             (y (fix:- 0 y-start)))
+         (let ((index (string-base:coordinates->index window 0 y)))
+           (if (let ((xy (string-base:index->coordinates window index)))
+                 (and (fix:= (car xy) 0)
+                      (fix:= (cdr xy) y)))
+               (fix:+ start index)
+               (fix:+ (fix:+ start index) 1)))))))
+\f
+(define-integrable (%window-column-length window start end column)
+  (group-column-length (%window-group window) start end column))
+
+(define-integrable (%window-column->index window start end column-start column)
+  (group-column->index (%window-group window) start end column-start column))
+
+(define-integrable (%window-line-columns window start index)
+  (%window-column-length window start (%window-line-end-index window index) 0))
+
+(define-integrable (%window-line-y window columns start index)
+  (%window-column->y window
+                    columns
+                    (%window-column-length window start index 0)))
+
+(define-integrable (%window-column->y-size window column-size)
+  (column->y-size column-size
+                 (window-x-size window)
+                 (%window-truncate-lines? window)))
+
+(define-integrable (%window-column->x window column-size column)
+  (column->x column-size
+            (window-x-size window)
+            (%window-truncate-lines? window)
+            column))
+
+(define-integrable (%window-column->y window column-size column)
+  (column->y column-size
+            (window-x-size window)
+            (%window-truncate-lines? window)
+            column))
+
+(define-integrable (%window-column->coordinates window column-size column)
+  (column->coordinates column-size
+                      (window-x-size window)
+                      (%window-truncate-lines? window)
+                      column))
+
+(define (%window-coordinates->index window start end column-length x y)
+  (%window-column->index
+   window start end 0
+   (let ((column (coordinates->column x y (window-x-size window))))
+     (if (fix:< column column-length)
+        column
+        column-length))))
+
+(define-integrable (%window-index->coordinates window start column-length
+                                              index)
+  (%window-column->coordinates window
+                              column-length
+                              (%window-column-length window start index 0)))
\ No newline at end of file
index d6f8db7b0e24fd54accee1e6fcf2230ea62ac755..6999c42755bad3c22d1d44fa2f423e161771f695 100644 (file)
@@ -1,8 +1,8 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/comman.scm,v 1.62 1989/08/11 11:50:16 cph Exp $
+;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/comman.scm,v 1.63 1990/11/02 03:23:13 cph Rel $
 ;;;
-;;;    Copyright (c) 1986, 1989 Massachusetts Institute of Technology
+;;;    Copyright (c) 1986, 1989, 1990 Massachusetts Institute of Technology
 ;;;
 ;;;    This material was developed by the Scheme project at the
 ;;;    Massachusetts Institute of Technology, Department of
   value
   buffer-local?
   initial-value
-  assignment-daemons)
+  assignment-daemons
+  value-validity-test)
 
 (unparser/set-tagged-vector-method!
  %variable-tag
     (vector-set! variable variable-index:buffer-local? buffer-local?)
     (vector-set! variable variable-index:initial-value value)
     (vector-set! variable variable-index:assignment-daemons '())
+    (vector-set! variable variable-index:value-validity-test false)
     variable))
 
 (define-integrable (%set-variable-value! variable value)
-  (vector-set! variable variable-index:value value)
-  unspecific)
+  (vector-set! variable variable-index:value value))
 
 (define-integrable (make-variable-buffer-local! variable)
-  (vector-set! variable variable-index:buffer-local? true)
-  unspecific)
+  (vector-set! variable variable-index:buffer-local? true))
 \f
+(define (define-variable-value-validity-test variable test)
+  (vector-set! variable variable-index:value-validity-test test))
+
+(define (check-variable-value-validity! variable value)
+  (if (not (variable-value-valid? variable value))
+      (error:illegal-datum value 'CHECK-VARIABLE-VALUE-VALIDITY)))
+
+(define (variable-value-valid? variable value)
+  (or (not (variable-value-validity-test variable))
+      ((variable-value-validity-test variable) value)))
+
 (define (add-variable-assignment-daemon! variable daemon)
   (let ((daemons (variable-assignment-daemons variable)))
     (if (not (memq daemon daemons))
-       (begin
-         (vector-set! variable
-                      variable-index:assignment-daemons
-                      (cons daemon daemons))
-         unspecific))))
+       (vector-set! variable
+                    variable-index:assignment-daemons
+                    (cons daemon daemons)))))
 
 (define (invoke-variable-assignment-daemons! variable)
   (for-each (lambda (daemon) (daemon variable))
       (make-local-binding! variable value)
       (without-interrupts
        (lambda ()
+        (check-variable-value-validity! variable value)
         (%set-variable-value! variable value)
         (invoke-variable-assignment-daemons! variable)))))
 
index 25fe0fed3b0774fd91e32661245117fb5cb7843f..044bc9ec8c06b6e7a81bd7cc75cea8d9d00f7f9e 100644 (file)
@@ -1,8 +1,8 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/comwin.scm,v 1.138 1989/06/21 10:31:40 cph Rel $
+;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/comwin.scm,v 1.139 1990/11/02 03:23:19 cph Rel $
 ;;;
-;;;    Copyright (c) 1985, 1989 Massachusetts Institute of Technology
+;;;    Copyright (c) 1985, 1989, 1990 Massachusetts Institute of Technology
 ;;;
 ;;;    This material was developed by the Scheme project at the
 ;;;    Massachusetts Institute of Technology, Department of
 
 (define-integrable (set-window-next! window window*)
   (with-instance-variables combination-leaf-window window (window*)
-    (set! next-window window*)
-    unspecific))
+    (set! next-window window*)))
 
 (define-integrable (window-previous window)
   (with-instance-variables combination-leaf-window window ()
 
 (define-integrable (set-window-previous! window window*)
   (with-instance-variables combination-leaf-window window (window*)
-    (set! previous-window window*)
-    unspecific))
+    (set! previous-window window*)))
 
 (define (link-windows! previous next)
   (set-window-previous! next previous)
   (set-window-next! previous next))
-\f
+
 (define-class combination-window combination-leaf-window
   (vertical? child))
 
 
 (define-integrable (set-combination-vertical! window v)
   (with-instance-variables combination-window window (v)
-    (set! vertical? v)
-    unspecific))
+    (set! vertical? v)))
 
 (define-integrable (combination-child window)
   (with-instance-variables combination-window window ()
 
 (define-integrable (check-leaf-window window name)
   (if (not (leaf? window))
-      (error "Not a leaf window" name window)))
+      (error:illegal-datum window name)))
 \f
 ;;;; Leaf Ordering
 
 (define (window0 window)
   (if (not (and (object? window)
                (subclass? (object-class window) combination-leaf-window)))
-      (error "WINDOW0: Window neither combination nor leaf" window))
+      (error:illegal-datum window 'WINDOW0))
   (window-leftmost-leaf (window-root window)))
 \f
 (define (%window1+ leaf)
 
 (define (window-split-horizontally! leaf #!optional n)
   (check-leaf-window leaf 'WINDOW-SPLIT-HORIZONTALLY!)
-  (let ((n
-        (if (or (default-object? n) (not n))
-            (quotient (window-x-size leaf) 2)
-            n))
-       (x (window-x-size leaf))
-       (y (window-y-size leaf)))
-    (let ((n* (- x n))
-         (new (allocate-leaf! leaf false)))
-      (let ((combination (window-superior leaf)))
-       (inferior-start (window-inferior combination leaf)
-         (lambda (x y)
-           (set-inferior-start! (window-inferior combination new)
-                                (+ x n)
-                                y))))
-      (if (or (< n (=> leaf :minimum-x-size))
-             (< n* (=> new :minimum-x-size)))
-         (begin
-           (deallocate-leaf! new)
-           false)
-         (begin
-           (=> leaf :set-x-size! n)
-           (=> new :set-size! n* y)
-           new)))))
+  (without-interrupts
+   (lambda ()
+     (let ((n
+           (if (or (default-object? n) (not n))
+               (quotient (window-x-size leaf) 2)
+               n))
+          (x (window-x-size leaf))
+          (y (window-y-size leaf)))
+       (let ((n* (- x n))
+            (new (allocate-leaf! leaf false)))
+        (let ((combination (window-superior leaf)))
+          (inferior-start (window-inferior combination leaf)
+            (lambda (x y)
+              (set-inferior-start! (window-inferior combination new)
+                                   (+ x n)
+                                   y))))
+        (if (or (< n (=> leaf :minimum-x-size))
+                (< n* (=> new :minimum-x-size)))
+            (begin
+              (deallocate-leaf! new)
+              false)
+            (begin
+              (=> leaf :set-x-size! n)
+              (=> new :set-size! n* y)
+              new)))))))
 
 (define (window-split-vertically! leaf #!optional n)
   (check-leaf-window leaf 'WINDOW-SPLIT-VERTICALLY!)
-  (let ((n
-        (if (or (default-object? n) (not n))
-            (quotient (window-y-size leaf) 2)
-            n))
-       (x (window-x-size leaf))
-       (y (window-y-size leaf)))
-    (let ((n* (- y n))
-         (new (allocate-leaf! leaf true)))
-      (let ((combination (window-superior leaf)))
-       (inferior-start (window-inferior combination leaf)
-         (lambda (x y)
-           (set-inferior-start! (window-inferior combination new)
-                                x
-                                (+ y n)))))
-      (if (or (< n (=> leaf :minimum-y-size))
-             (< n* (=> new :minimum-y-size)))
-         (begin
-           (deallocate-leaf! new)
-           false)
-         (begin
-           (=> leaf :set-y-size! n)
-           (=> new :set-size! x n*)
-           new)))))
+  (without-interrupts
+   (lambda ()
+     (let ((n
+           (if (or (default-object? n) (not n))
+               (quotient (window-y-size leaf) 2)
+               n))
+          (x (window-x-size leaf))
+          (y (window-y-size leaf)))
+       (let ((n* (- y n))
+            (new (allocate-leaf! leaf true)))
+        (let ((combination (window-superior leaf)))
+          (inferior-start (window-inferior combination leaf)
+            (lambda (x y)
+              (set-inferior-start! (window-inferior combination new)
+                                   x
+                                   (+ y n)))))
+        (if (or (< n (=> leaf :minimum-y-size))
+                (< n* (=> new :minimum-y-size)))
+            (begin
+              (deallocate-leaf! new)
+              false)
+            (begin
+              (=> leaf :set-y-size! n)
+              (=> new :set-size! x n*)
+              new)))))))
 \f
 (define (allocate-leaf! leaf v)
   (let ((superior (window-superior leaf)))
 
 (define (window-delete! leaf)
   (check-leaf-window leaf 'WINDOW-DELETE!)
-  (let ((superior (window-superior leaf))
-       (next (window-next leaf))
-       (previous (window-previous leaf))
-       (x-size (window-x-size leaf))
-       (y-size (window-y-size leaf)))
-    (if (not (combination? superior))
-       (editor-error "Window has no neighbors; can't delete"))
-    (unlink-leaf! leaf)
-    (let ((value
-          (let ((adjust-size!
-                 (lambda (window)
-                   (if (combination-vertical? superior)
-                       (=> window :set-y-size!
-                           (+ (window-y-size window) y-size))
-                       (=> window :set-x-size!
-                           (+ (window-x-size window) x-size))))))
-            (cond (next
-                   (adjust-size! next)
-                   (let ((inferior (window-inferior superior next)))
-                     (if (combination-vertical? superior)
-                         (set-inferior-y-start! inferior
-                                                (- (inferior-y-start inferior)
-                                                   y-size))
-                         (set-inferior-x-start! inferior
-                                                (- (inferior-x-start inferior)
-                                                   x-size))))
-                   next)
-                  (previous
-                   (adjust-size! previous)
-                   previous)
-                  (else
-                   (error "combination with single child" superior))))))
-      (maybe-delete-combination! superior)
-      (if (current-window? leaf)
-         (select-window value)))))
+  (without-interrupts
+   (lambda ()
+     (let ((superior (window-superior leaf))
+          (next (window-next leaf))
+          (previous (window-previous leaf))
+          (x-size (window-x-size leaf))
+          (y-size (window-y-size leaf)))
+       (if (not (combination? superior))
+          (editor-error "Window has no neighbors; can't delete"))
+       (let ((adjust-size!
+             (lambda (window)
+               (if (current-window? leaf)
+                   (select-window window))
+               (unlink-leaf! leaf)
+               (if (combination-vertical? superior)
+                   (=> window :set-y-size!
+                       (+ (window-y-size window) y-size))
+                   (=> window :set-x-size!
+                       (+ (window-x-size window) x-size))))))
+        (cond (next
+               (adjust-size! next)
+               (let ((inferior (window-inferior superior next)))
+                 (if (combination-vertical? superior)
+                     (set-inferior-y-start!
+                      inferior
+                      (- (inferior-y-start inferior) y-size))
+                     (set-inferior-x-start!
+                      inferior
+                      (- (inferior-x-start inferior) x-size)))))
+              (previous
+               (adjust-size! previous))
+              (else
+               (error "combination with single child" superior))))
+       (maybe-delete-combination! superior)))))
 \f
 (define (unlink-leaf! leaf)
   (let ((combination (window-superior leaf))
        (next (window-next leaf))
        (previous (window-previous leaf)))
-    (delete-inferior! combination leaf)
     (=> leaf :kill!)
+    (delete-inferior! combination leaf)
     (if previous
        (set-window-next! previous next)
        (set-combination-child! combination next))
 \f
 ;;;; Sizing
 
-(define (window-grow! leaf delta
-                     vertical? size min-size
-                     set-w-size! start set-start!)
-  (check-leaf-window leaf 'WINDOW-GROW!)
-  (let ((leaf
-        (let loop ((leaf leaf))
-          (let ((combination (window-superior leaf)))
-            (cond ((not (combination? combination))
-                   (editor-error "Can't grow this window "
-                                 (if vertical? "vertically" "horizontally")))
-                  ((boolean=? vertical? (combination-vertical? combination))
-                   leaf)
-                  (else
-                   (loop combination)))))))
-    (let ((new-size (+ (size leaf) delta))
-         (combination (window-superior leaf))
-         (next (window-next leaf))
-         (previous (window-previous leaf)))
-      (if (> new-size (size combination))
-         (begin
-           (set! new-size (size combination))
-           (set! delta (- new-size (size leaf)))))
-      (cond ((< new-size (min-size leaf))
-            (window-delete! leaf))
-           ((and next (>= (- (size next) delta) (min-size next)))
-            (let ((inferior (window-inferior combination next)))
-              (set-start! inferior (+ (start inferior) delta)))
-            (set-w-size! next (- (size next) delta))
-            (set-w-size! leaf new-size))
-           ((and previous
-                 (>= (- (size previous) delta) (min-size previous)))
-            (let ((inferior (window-inferior combination leaf)))
-              (set-start! inferior (- (start inferior) delta)))
-            (set-w-size! previous (- (size previous) delta))
-            (set-w-size! leaf new-size))
-           (else
-            (scale-combination-inferiors! combination
-                                          (- (size combination) new-size)
-                                          leaf vertical? size min-size
-                                          set-w-size! set-start!)
-            ;; Scaling may have deleted all other inferiors.
-            ;; If so, leaf has replaced combination.
-            (set-w-size! leaf
-                         (if (eq? combination (window-superior leaf))
-                             new-size
-                             (size combination))))))))
+(define (window-grow! vertical? size min-size set-w-size! start set-start!
+                     scale-combination-inferiors!)
+  (lambda (leaf delta)
+    (check-leaf-window leaf 'WINDOW-GROW!)
+    (without-interrupts
+     (lambda ()
+       (let ((leaf
+             (let loop ((leaf leaf))
+               (let ((combination (window-superior leaf)))
+                 (if (not (combination? combination))
+                     (editor-error "Can't grow this window "
+                                   (if vertical?
+                                       "vertically"
+                                       "horizontally")))
+                 (if (boolean=? vertical? (combination-vertical? combination))
+                     leaf
+                     (loop combination))))))
+        (let ((new-size (+ (size leaf) delta))
+              (combination (window-superior leaf))
+              (next (window-next leaf))
+              (previous (window-previous leaf)))
+          (if (> new-size (size combination))
+              (begin
+                (set! new-size (size combination))
+                (set! delta (- new-size (size leaf)))))
+          (cond ((< new-size (min-size leaf))
+                 (window-delete! leaf))
+                ((and next (>= (- (size next) delta) (min-size next)))
+                 (let ((inferior (window-inferior combination next)))
+                   (set-start! inferior (+ (start inferior) delta)))
+                 (set-w-size! next (- (size next) delta))
+                 (set-w-size! leaf new-size))
+                ((and previous
+                      (>= (- (size previous) delta) (min-size previous)))
+                 (let ((inferior (window-inferior combination leaf)))
+                   (set-start! inferior (- (start inferior) delta)))
+                 (set-w-size! previous (- (size previous) delta))
+                 (set-w-size! leaf new-size))
+                (else
+                 (scale-combination-inferiors! combination
+                                               (- (size combination) new-size)
+                                               leaf)
+                 ;; Scaling may have deleted all other inferiors.
+                 ;; If so, leaf has replaced combination.
+                 (set-w-size! leaf
+                              (if (eq? combination (window-superior leaf))
+                                  new-size
+                                  (size combination)))))))))))
+
+;;; (SCALE-COMBINATION-INFERIORS! COMBINATION NEW-ROOM EXCEPT)
+
+;;; Change all of the inferiors of COMBINATION (except EXCEPT) to use
+;;; NEW-ROOM's worth of space.  EXCEPT, if given, should not be
+;;; changed in size, but should be moved if its neighbors change.  It
+;;; is assumed that EXCEPT is given only for case where the
+;;; combination's VERTICAL? flag is the same as V.
+
+;;; General strategy:
+
+;;; If the window is growing, we can simply change the sizes of the
+;;; inferiors.  However, if it is shrinking, we must be more careful
+;;; because some or all of the inferiors can be deleted.  So in that
+;;; case, before any sizes are changed, we find those inferiors that
+;;; will be deleted and delete them.  If we delete all of the
+;;; inferiors, then we are done: this window has also been deleted.
+;;; Otherwise, we can then perform all of the changes, knowing that no
+;;; window will grow too small.
+\f
+(define (scale-combination-inferiors! v size min-size set-w-size! set-start!)
+  (lambda (combination new-room except)
+    (let ((kernel
+          (lambda (old-room collect-deletions change-inferiors)
+            (cond ((< old-room new-room)
+                   (change-inferiors))
+                  ((> old-room new-room)
+                   (for-each window-delete! (collect-deletions))
+                   (if (not (null? (window-inferiors combination)))
+                       (change-inferiors))))))
+         (child (combination-child combination))
+         (c-size (size combination)))
+      (if (not (eq? (combination-vertical? combination) v))
+         (kernel
+          c-size
+          (lambda ()
+            (let loop ((window child))
+              (let ((deletions
+                     (if (window-next window)
+                         (loop (window-next window))
+                         '())))
+                (if (< new-room (min-size window))
+                    (cons window deletions)
+                    deletions))))
+          (lambda ()
+            (let loop ((window child))
+              (set-w-size! window new-room)
+              (if (window-next window)
+                  (loop (window-next window))))))
+         (let ((old-room (if except (- c-size (size except)) c-size)))
+           (kernel
+            old-room
+            (lambda ()
+              (let loop
+                  ((window child) (old-room old-room) (new-room new-room))
+                (cond ((eq? window except)
+                       (if (window-next window)
+                           (loop (window-next window) old-room new-room)
+                           '()))
+                      ((not (window-next window))
+                       (if (< new-room (min-size window))
+                           (list window)
+                           '()))
+                      (else
+                       (let* ((old-s (size window))
+                              (new-s (quotient (* old-s new-room) old-room))
+                              (deletions
+                               (loop (window-next window)
+                                     (- old-room old-s)
+                                     (- new-room new-s))))
+                         (if (< new-s (min-size window))
+                             (cons window deletions)
+                             deletions))))))
+            (lambda ()
+              (let loop
+                  ((window child)
+                   (start 0)
+                   (old-room old-room)
+                   (new-room new-room))
+                (set-start! (window-inferior combination window) start)
+                (cond ((eq? window except)
+                       (if (window-next window)
+                           (loop (window-next window)
+                                 start
+                                 old-room
+                                 new-room)))
+                      ((not (window-next window))
+                       (set-w-size! window new-room))
+                      (else
+                       (let* ((old-s (size window))
+                              (new-s (quotient (* old-s new-room) old-room)))
+                         (set-w-size! window new-s)
+                         (loop (window-next window)
+                               (+ start new-s)
+                               (- old-room old-s)
+                               (- new-room new-s)))))))))))))
 \f
-(define (window-grow-horizontally! leaf delta)
-  (window-grow! leaf delta false
-               window-x-size window-min-x-size
-               send-window-x-size! inferior-x-start set-inferior-x-start!))
-
-(define (window-grow-vertically! leaf delta)
-  (window-grow! leaf delta true
-               window-y-size window-min-y-size
-               send-window-y-size! inferior-y-start set-inferior-y-start!))
-
-(define (scale-combination-inferiors-x! combination x except)
-  (scale-combination-inferiors! combination x except false
-                               window-x-size window-min-x-size
-                               send-window-x-size! set-inferior-x-start!))
-
-(define (scale-combination-inferiors-y! combination y except)
-  (scale-combination-inferiors! combination y except true
-                               window-y-size window-min-y-size
-                               send-window-y-size! set-inferior-y-start!))
-
 (define (window-min-x-size window)
   (=> window :minimum-x-size))
 
 (define (send-window-y-size! window y)
   (=> window :set-y-size! y))
 
+(define scale-combination-inferiors-x!
+  (scale-combination-inferiors! false window-x-size window-min-x-size
+                               send-window-x-size! set-inferior-x-start!))
+
+(define scale-combination-inferiors-y!
+  (scale-combination-inferiors! true window-y-size window-min-y-size
+                               send-window-y-size! set-inferior-y-start!))
+
+(define window-grow-horizontally!
+  (window-grow! false window-x-size window-min-x-size send-window-x-size!
+               inferior-x-start set-inferior-x-start!
+               scale-combination-inferiors-x!))
+
+(define window-grow-vertically!
+  (window-grow! true window-y-size window-min-y-size send-window-y-size!
+               inferior-y-start set-inferior-y-start!
+               scale-combination-inferiors-y!))
+
 (define-method combination-window (:minimum-x-size combination)
   (=> (window-leftmost-leaf combination) :minimum-x-size))
 
   (inferior-containing-coordinates combination x y leaf?))
 
 (define-method combination-leaf-window (:leaf-containing-coordinates leaf x y)
-  (values leaf x y))
-\f
-(define (scale-combination-inferiors! combination new-room except
-                                     v size min-size set-w-size! set-start!)
-  ;; Change all of the inferiors of COMBINATION (except EXCEPT) to
-  ;; use NEW-ROOM's worth of space.  EXCEPT, if given, should not be
-  ;; changed in size, but should be moved if its neighbors change.
-  ;; It is assumed that EXCEPT is given only for case where the
-  ;; combination's VERTICAL? flag is the same as V.
-
-  ;; General strategy:
-  ;; If the window is growing, we can simply change the sizes of the
-  ;; inferiors.  However, if it is shrinking, we must be more careful
-  ;; because some or all of the inferiors can be deleted.  So in that
-  ;; case, before any sizes are changed, we find those inferiors that
-  ;; will be deleted and delete them.  If we delete all of the
-  ;; inferiors, then we are done: this window has also been deleted.
-  ;; Otherwise, we can then perform all of the changes, knowing that
-  ;; no window will grow too small.
-
-  (let ((kernel
-        (lambda (old-room collect-deletions change-inferiors)
-          (cond ((< old-room new-room)
-                 (change-inferiors))
-                ((> old-room new-room)
-                 (for-each window-delete! (collect-deletions))
-                 (if (not (null? (window-inferiors combination)))
-                     (change-inferiors))))))
-       (child (combination-child combination))
-       (c-size (size combination)))
-    (if (not (eq? (combination-vertical? combination) v))
-       (kernel
-        c-size
-        (lambda ()
-          (let loop ((window child))
-            (let ((deletions
-                   (if (window-next window)
-                       (loop (window-next window))
-                       '())))
-              (if (< new-room (min-size window))
-                  (cons window deletions)
-                  deletions))))
-        (lambda ()
-          (let loop ((window child))
-            (set-w-size! window new-room)
-            (if (window-next window)
-                (loop (window-next window))))))
-       (let ((old-room (if except (- c-size (size except)) c-size)))
-         (kernel
-          old-room
-          (lambda ()
-            (let loop ((window child) (old-room old-room) (new-room new-room))
-              (cond ((eq? window except)
-                     (if (window-next window)
-                         (loop (window-next window) old-room new-room)
-                         '()))
-                    ((not (window-next window))
-                     (if (< new-room (min-size window))
-                         (list window)
-                         '()))
-                    (else
-                     (let* ((old-s (size window))
-                            (new-s (quotient (* old-s new-room) old-room))
-                            (deletions
-                             (loop (window-next window)
-                                   (- old-room old-s)
-                                   (- new-room new-s))))
-                       (if (< new-s (min-size window))
-                           (cons window deletions)
-                           deletions))))))
-          (lambda ()
-            (let loop
-                ((window child)
-                 (start 0)
-                 (old-room old-room)
-                 (new-room new-room))
-              (set-start! (window-inferior combination window) start)
-              (cond ((eq? window except)
-                     (if (window-next window)
-                         (loop (window-next window) start old-room new-room)))
-                    ((not (window-next window))
-                     (set-w-size! window new-room))
-                    (else
-                     (let* ((old-s (size window))
-                            (new-s (quotient (* old-s new-room) old-room)))
-                       (set-w-size! window new-s)
-                       (loop (window-next window)
-                             (+ start new-s)
-                             (- old-room old-s)
-                             (- new-room new-s))))))))))))
\ No newline at end of file
+  (values leaf x y))
\ No newline at end of file
index 391d8dafcac1f1eb2c8dee5e8f40267510b3f9c0..f9a661dc51dcf69c5f1f363924ddff81a093a168 100644 (file)
@@ -1,6 +1,6 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/debuge.scm,v 1.39 1990/06/20 23:02:09 cph Exp $
+;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/debuge.scm,v 1.40 1990/11/02 03:23:28 cph Rel $
 ;;;
 ;;;    Copyright (c) 1986, 1989, 1990 Massachusetts Institute of Technology
 ;;;
                      (and (y-or-n? "Save buffer "
                                    (buffer-name buffer)
                                    " (Y or N)? ")
-                          (begin
-                            (newline)
-                            (write-string "Filename: ")
-                            (->pathname
-                             (input-port/normal-mode (current-input-port)
-                                                     read)))))
+                          (->pathname (prompt-for-expression "Filename"))))
                     ((integer? (pathname-version pathname))
                      (pathname-new-version pathname 'NEWEST))
                     (else
   (let ((entry (assq name (class-instance-transforms (object-class object)))))
     (if entry
        (vector-set! object (cdr entry) value)
-       (error "Not a valid instance-variable name" name))))
\ No newline at end of file
+       (error "Not a valid instance-variable name" name))))
+
+;;;; Screen Trace
+
+(define trace-output '())
+
+(define (debug-tracer . args)
+  (set! trace-output (cons args trace-output))
+  unspecific)
+
+(define (screen-trace #!optional screen)
+  (let ((screen
+        (if (default-object? screen)
+            (begin
+              (if (not edwin-editor)
+                  (error "no screen to trace"))
+              (editor-selected-screen edwin-editor))
+            screen)))
+    (set! trace-output '())
+    (for-each (lambda (window)
+               (set-window-debug-trace! window debug-tracer))
+             (screen-window-list screen))
+    (set-screen-debug-trace! screen debug-tracer)))
+
+(define (screen-untrace #!optional screen)
+  (let ((screen
+        (if (default-object? screen)
+            (begin
+              (if (not edwin-editor)
+                  (error "no screen to trace"))
+              (editor-selected-screen edwin-editor))
+            screen)))
+    (for-each (lambda (window)
+               (set-window-debug-trace! window false))
+             (screen-window-list screen))
+    (set-screen-debug-trace! screen false)
+    (let ((result trace-output))
+      (set! trace-output '())
+      (map list->vector (reverse! result)))))
\ No newline at end of file
index ed9770d9705eaaf910964d533da5184da8cc4411..88009e0f6c846d3dc6391bdb74f94ac3e9c121b8 100644 (file)
@@ -1,6 +1,6 @@
 #| -*-Scheme-*-
 
-$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/decls.scm,v 1.14 1990/10/09 16:23:47 cph Exp $
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/decls.scm,v 1.15 1990/11/02 03:23:33 cph Rel $
 
 Copyright (c) 1989, 1990 Massachusetts Institute of Technology
 
@@ -85,7 +85,6 @@ MIT in each case. |#
              "clscon"
              "clsmac"
              "comtab"
-             "cterm"
              "display"
              "image"
              "macros"
@@ -99,11 +98,13 @@ MIT in each case. |#
              "simple"
              "strpad"
              "strtab"
+             "termcap"
              "utils"
              "winout"
              "winren"
              "xform"
              "xterm"))
+  (sf-global "tterm" "termcap")
   (for-each sf-edwin
            '("argred"
              "autold"
@@ -170,15 +171,14 @@ MIT in each case. |#
   (for-each sf-class
            '("comwin"
              "modwin"
-             "buffrm"
              "edtfrm"))
   (sf-edwin "grpops" "struct")
   (sf-edwin "regops" "struct")
   (sf-edwin "motion" "struct")
   (sf-class "window" "class")
   (sf-class "utlwin" "window" "class")
-  (sf-class "linwin" "window" "class")
-  (sf-class "bufwin" "window" "class" "struct")
-  (sf-class "bufwfs" "bufwin" "window" "class" "struct")
-  (sf-class "bufwiu" "bufwin" "window" "class" "struct")
-  (sf-class "bufwmc" "bufwin" "window" "class" "struct"))
\ No newline at end of file
+  (sf-class "bufwin" "window" "class" "buffer" "struct")
+  (sf-class "bufwfs" "bufwin" "window" "class" "buffer" "struct")
+  (sf-class "bufwiu" "bufwin" "window" "class" "buffer" "struct")
+  (sf-class "bufwmc" "bufwin" "window" "class" "buffer" "struct")
+  (sf-class "buffrm" "bufwin" "window" "class" "struct"))
\ No newline at end of file
index f3fa0340bff715fd44337be19f7b925fd043eadc..69bf51de1ba37a806f1c7497b58b95c758257d38 100644 (file)
@@ -1,6 +1,6 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/display.scm,v 1.2 1990/10/09 16:23:54 cph Exp $
+;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/display.scm,v 1.3 1990/11/02 03:23:38 cph Rel $
 ;;;
 ;;;    Copyright (c) 1989, 1990 Massachusetts Institute of Technology
 ;;;
@@ -60,7 +60,7 @@
   (operation/available? false read-only true)
   (operation/make-screen false read-only true)
   (operation/make-input-port false read-only true)
-  (operation/with-interrupt-source false read-only true)
+  (operation/with-display-grabbed false read-only true)
   (operation/with-interrupts-enabled false read-only true)
   (operation/with-interrupts-disabled false read-only true))
 
@@ -69,7 +69,7 @@
                           available?
                           make-screen
                           make-input-port
-                          with-interrupt-source
+                          with-display-grabbed
                           with-interrupts-enabled
                           with-interrupts-disabled)
   (let ((display-type
@@ -78,7 +78,7 @@
                             available?
                             make-screen
                             make-input-port
-                            with-interrupt-source
+                            with-display-grabbed
                             with-interrupts-enabled
                             with-interrupts-disabled)))
     (set! display-types (cons display-type display-types))
@@ -95,8 +95,8 @@
 (define (display-type/make-input-port display-type screen)
   ((display-type/operation/make-input-port display-type) screen))
 
-(define (display-type/with-interrupt-source display-type thunk)
-  ((display-type/operation/with-interrupt-source display-type) thunk))
+(define (display-type/with-display-grabbed display-type thunk)
+  ((display-type/operation/with-display-grabbed display-type) thunk))
 
 (define (display-type/with-interrupts-enabled display-type thunk)
   ((display-type/operation/with-interrupts-enabled display-type) thunk))
index 7669738e4fa314b432c9f7e647598b1d1fbc725c..5d5f4cd7b3a153478315568102a5f8540b11f5f1 100644 (file)
@@ -51,8 +51,6 @@
               syntax-table/system-internal)
     ("comwin"  (edwin window combination)
               class-syntax-table)
-    ("cterm"   (edwin console-screen)
-              syntax-table/system-internal)
     ("curren"  (edwin)
               edwin-syntax-table)
     ("debug"   (edwin debugger)
               edwin-syntax-table)
     ("linden"  (edwin lisp-indentation)
               edwin-syntax-table)
-    ("linwin"  (edwin window)
-              class-syntax-table)
     ("loadef"  (edwin)
               edwin-syntax-table)
     ("lspcom"  (edwin)
               edwin-syntax-table)
     ("tags"    (edwin tags)
               edwin-syntax-table)
+    ("termcap" (edwin console-screen)
+              syntax-table/system-internal)
     ("texcom"  (edwin)
               edwin-syntax-table)
     ("things"  (edwin)
               edwin-syntax-table)
     ("tparse"  (edwin)
               edwin-syntax-table)
+    ("tterm"   (edwin console-screen)
+              syntax-table/system-internal)
     ("tximod"  (edwin)
               edwin-syntax-table)
     ("undo"    (edwin undo)
index 6195c6bf71e1df7cc56c2746dc3a6d34ea5021d4..d5a719ad3c792184f3da30cee038fbc43057c63c 100644 (file)
@@ -1,6 +1,6 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/editor.scm,v 1.197 1990/10/09 16:24:08 cph Exp $
+;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/editor.scm,v 1.198 1990/11/02 03:23:48 cph Exp $
 ;;;
 ;;;    Copyright (c) 1986, 1989, 1990 Massachusetts Institute of Technology
 ;;;
 \f
 (define (edit)
   (if (not edwin-editor)
-      (apply create-editor create-editor-args))
+      (create-editor))
   (call-with-current-continuation
    (lambda (continuation)
      (fluid-let ((editor-abort continuation)
-                (*auto-save-keystroke-count* 0))
-       (within-editor edwin-editor
-        (lambda ()
-          (with-current-local-bindings!
-            (lambda ()
-              (bind-condition-handler '() internal-error-handler
-                (lambda ()
-                  (dynamic-wind
-                   (lambda () (update-screens! true))
-                   (lambda ()
-                     (let ((cmdl (nearest-cmdl))
-                           (message (cmdl-message/null)))
-                       (let ((input-port (cmdl/input-port cmdl)))
-                         (input-port/immediate-mode input-port
-                           (lambda ()
-                             (make-cmdl cmdl
-                                        input-port
-                                        (cmdl/output-port cmdl)
-                                        (lambda (cmdl)
-                                          cmdl ;ignore
-                                          (top-level-command-reader
-                                           edwin-initialization)
-                                          message)
-                                        false
-                                        message))))))
-                   (lambda () unspecific)))))))))))
+                (*auto-save-keystroke-count* 0)
+                (current-editor edwin-editor)
+                (recursive-edit-continuation false)
+                (recursive-edit-level 0))
+       (editor-grab-display edwin-editor
+        (lambda (with-editor-ungrabbed)
+          (let ((message (cmdl-message/null)))
+            (push-cmdl (lambda (cmdl)
+                         cmdl ;ignore
+                         (top-level-command-reader edwin-initialization)
+                         message)
+                       false
+                       message
+                       (editor-spawn-child-cmdl with-editor-ungrabbed))))))))
   (if edwin-finalization (edwin-finalization))
   unspecific)
 
-(define create-editor-args (list 'X))
+(define (editor-grab-display editor receiver)
+  (display-type/with-display-grabbed (editor-display-type editor)
+    (lambda (with-display-ungrabbed)
+      (with-current-local-bindings!
+       (lambda ()
+         (let ((enter
+                (lambda ()
+                  (let ((screen (selected-screen)))
+                    (screen-enter! screen)
+                    (update-screen! screen true))))
+               (exit (lambda () (screen-exit! (selected-screen)))))
+           (dynamic-wind enter
+                         (lambda ()
+                           (receiver
+                            (lambda (thunk)
+                              (dynamic-wind exit
+                                            (lambda ()
+                                              (with-display-ungrabbed thunk))
+                                            enter))))
+                         exit)))))))
+
+(define (editor-spawn-child-cmdl with-editor-ungrabbed)
+  (lambda (editor-cmdl input-port output-port driver state message spawn-child)
+    (with-editor-ungrabbed
+     (lambda ()
+       (make-cmdl editor-cmdl
+                 (if (eq? input-port (cmdl/input-port editor-cmdl))
+                     (cmdl/input-port (cmdl/parent editor-cmdl))
+                     input-port)
+                 (if (eq? output-port (cmdl/output-port editor-cmdl))
+                     (cmdl/output-port (cmdl/parent editor-cmdl))
+                     output-port)
+                 driver
+                 state
+                 message
+                 spawn-child)))))
+
+(define (within-editor?)
+  (not (unassigned? current-editor)))
+
 (define editor-abort)
 (define edwin-editor false)
+(define current-editor)
 
 ;; Set this before entering the editor to get something done after the
 ;; editor's dynamic environment is initialized, but before the command
 ;; reset and then reenter the editor.
 (define edwin-finalization false)
 \f
-(define (create-editor display-type-name . make-screen-args)
-  (reset-editor)
-  (initialize-typein!)
-  (initialize-typeout!)
-  (initialize-syntax-table!)
-  (initialize-command-reader!)
-  (set! edwin-editor
-       (make-editor "Edwin"
-                    (name->display-type display-type-name)
-                    make-screen-args))
-  (set! edwin-initialization
-       (lambda ()
-         (set! edwin-initialization false)
-         (with-editor-interrupts-disabled standard-editor-initialization)))
-  unspecific)
-
-(define (reset-editor)
-  (without-interrupts
-   (lambda ()
-     (if edwin-editor
-        (begin
-          (for-each (lambda (screen)
-                      (screen-discard! screen))
-                    (editor-screens edwin-editor))
-          (set! edwin-editor false)
-          (set! *previous-popped-up-buffer* (object-hash false))
-          (set! *previous-popped-up-window* (object-hash false))
-          unspecific)))))
+(define create-editor-args
+  (list false))
 
-(define (reset-editor-windows)
-  (for-each (lambda (screen)
-             (send (screen-root-window screen) ':salvage!))
-           (editor-screens edwin-editor)))
+(define (create-editor . args)
+  (let ((args
+        (if (null? args)
+            create-editor-args
+            (begin
+              (set! create-editor-args args)
+              args))))
+    (reset-editor)
+    (initialize-typein!)
+    (initialize-typeout!)
+    (initialize-syntax-table!)
+    (initialize-command-reader!)
+    (set! edwin-editor
+         (make-editor "Edwin"
+                      (let ((name (car args)))
+                        (cond (name
+                               (name->display-type name))
+                              ((display-type/available? console-display-type)
+                               console-display-type)
+                              ((display-type/available? x-display-type)
+                               x-display-type)
+                              (else
+                               (error "can't find usable display type"))))
+                      (cdr args)))
+    (set! edwin-initialization
+         (lambda ()
+           (set! edwin-initialization false)
+           (with-editor-interrupts-disabled standard-editor-initialization)))
+    unspecific))
 
 (define (standard-editor-initialization)
   (if (not init-file-loaded?)
        (let ((filename (os/init-file-name)))
          (if (file-exists? filename)
              (load-edwin-file filename '(EDWIN) true)))
-       (set! init-file-loaded? true)
-       unspecific))
+       (set! init-file-loaded? true)))
   (if (not (ref-variable inhibit-startup-message))
       (let ((window (current-window)))
        (let ((buffer (window-buffer window)))
@@ -173,23 +199,24 @@ with the contents of the startup message."
 
 ")
 \f
-;;;; Recursive Edit Levels
-
-(define (within-editor editor thunk)
-  (fluid-let ((current-editor editor)
-             (recursive-edit-continuation false)
-             (recursive-edit-level 0))
-    (dynamic-wind
-     (lambda ()
-       (screen-enter! (selected-screen)))
-     (lambda ()
-       (display-type/with-interrupt-source (editor-display-type editor)
-                                          thunk))
-     (lambda ()
-       (screen-exit! (selected-screen))))))
+(define (reset-editor)
+  (without-interrupts
+   (lambda ()
+     (if edwin-editor
+        (begin
+          (for-each (lambda (screen)
+                      (screen-discard! screen))
+                    (editor-screens edwin-editor))
+          (set! edwin-editor false)
+          (set! init-file-loaded? false)
+          (set! *previous-popped-up-buffer* (object-hash false))
+          (set! *previous-popped-up-window* (object-hash false))
+          unspecific)))))
 
-(define (within-editor?)
-  (not (unassigned? current-editor)))
+(define (reset-editor-windows)
+  (for-each (lambda (screen)
+             (send (screen-root-window screen) ':salvage!))
+           (editor-screens edwin-editor)))
 
 ;;; There is a problem with recursive edits and multiple screens.
 ;;; When you switch screens the recursive edit aborts. The problem
@@ -225,32 +252,32 @@ with the contents of the startup message."
 
 (define recursive-edit-continuation)
 (define recursive-edit-level)
-(define current-editor)
 \f
-;;;; Internal Errors
-
 (define (internal-error-handler condition)
   (and (not (condition/internal? condition))
        (error? condition)
-       (if (ref-variable debug-on-internal-error)
-          (begin
-            (debug-scheme-error condition)
-            (message "Scheme error")
-            (%editor-error))
-          (exit-editor-and-signal-error condition))))
+       (cond ((ref-variable debug-on-internal-error)
+             (debug-scheme-error condition)
+             (message "Scheme error")
+             (%editor-error))
+            (debug-internal-errors?
+             (signal-error condition))
+            (else
+             (exit-editor-and-signal-error condition)))))
 
 (define-variable debug-on-internal-error
   "True means enter debugger if error is signalled while the editor is running.
 This does not affect editor errors or evaluation errors."
   false)
 
+(define debug-internal-errors?
+  false)
+
 (define (exit-editor-and-signal-error condition)
   (within-continuation editor-abort
     (lambda ()
       (signal-error condition))))
 
-;;;; C-g Interrupts
-
 (define (^G-signal)
   (let ((continuations *^G-interrupt-continuations*))
     (if (not (pair? continuations))
index 78b6f13f96299206e0297da4ee0deba520aa67b4..8a03c9c067e3ba942dc00cbf831899a9b904f2f6 100644 (file)
@@ -1,6 +1,6 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/edtfrm.scm,v 1.82 1990/10/06 00:15:44 cph Exp $
+;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/edtfrm.scm,v 1.83 1990/11/02 03:23:54 cph Rel $
 ;;;
 ;;;    Copyright (c) 1985, 1989, 1990 Massachusetts Institute of Technology
 ;;;
@@ -54,7 +54,6 @@
    typein-inferior
    selected-window
    cursor-window
-   select-time
    properties))
 
 (define (make-editor-frame root-screen main-buffer typein-buffer)
        (set! typein-inferior (find-inferior inferiors typein-window))
        (set! selected-window main-window)
        (set! cursor-window main-window)
-       (set! select-time 2)
-       (set-window-select-time! main-window 1)
-       (=> (window-cursor main-window) :enable!))
+       (window-cursor-enable! main-window))
       (set-editor-frame-size! window x-size y-size))
     window))
 
 (define (editor-frame-update-display! window display-style)
   ;; Returns true if update is successfully completed (or unnecessary).
+  ;; Assumes that interrupts are disabled.
   (with-instance-variables editor-frame window (display-style)
-    (with-screen-in-update! screen
-      (lambda ()
-       (if (and (not display-style)
-                (not (car redisplay-flags)))
-           true
-           (let ((finished?
-                  (update-inferiors! window screen 0 0
-                                     0 x-size 0 y-size
-                                     display-style)))
-             (if finished?
-                 (set-car! redisplay-flags false))
-             finished?))))))
+    (if (and (not display-style)
+            (not (car redisplay-flags)))
+       true
+       (let ((finished?
+              (window-update-display! window screen 0 0 0 x-size 0 y-size
+                                      display-style)))
+         (if finished?
+             (set-car! redisplay-flags false))
+         finished?))))
 
 (define (set-editor-frame-size! window x y)
   (with-instance-variables editor-frame window (x y)
   (with-instance-variables editor-frame window (window*)
     (if (not (buffer-frame? window*))
        (error "Attempt to select non-window" window*))
-    (=> (window-cursor cursor-window) :disable!)
+    (window-cursor-disable! cursor-window)
     (set! selected-window window*)
-    (set-window-select-time! window* select-time)
-    (set! select-time (1+ select-time))
+    (set-window-select-time! window* (increment-select-time!))
     (set! cursor-window window*)
-    (=> (window-cursor cursor-window) :enable!)))
+    (window-cursor-enable! window*)))
 
 (define (editor-frame-select-cursor! window window*)
   (with-instance-variables editor-frame window (window*)
     (if (not (buffer-frame? window*))
        (error "Attempt to select non-window" window*))
-    (=> (window-cursor cursor-window) :disable!)
+    (window-cursor-disable! cursor-window)
     (set! cursor-window window*)
-    (=> (window-cursor cursor-window) :enable!)))
+    (window-cursor-enable! cursor-window)))
 
 (define-method editor-frame (:button-event! editor-frame button x y)
   (with-values
index 2b52f962e68d29f1ff3b2ec175a0ec37adca35c6..d92124360acc599739d1f76a2cf162be9da37738 100644 (file)
@@ -1,6 +1,6 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/edtstr.scm,v 1.11 1990/10/09 16:24:14 cph Exp $
+;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/edtstr.scm,v 1.12 1990/11/02 03:23:59 cph Rel $
 ;;;
 ;;;    Copyright (c) 1989, 1990 Massachusetts Institute of Technology
 ;;;
 (define-structure (editor (constructor %make-editor))
   (name false read-only true)
   (display-type false read-only true)
-  (screens false)
+  (screens '())
   (selected-screen false)
   (bufferset false read-only true)
   (kill-ring false read-only true)
   (char-history false read-only true)
   (input-port false read-only true)
-  (button-event false))
+  (button-event false)
+  (select-time 1))
 
 (define (make-editor name display-type make-screen-args)
   (let ((initial-buffer (make-buffer initial-buffer-name initial-buffer-mode)))
@@ -70,7 +71,8 @@
                    (make-ring 10)
                    (make-ring 100)
                    (display-type/make-input-port display-type screen)
-                   false))))
+                   false
+                   1))))
 
 (define-integrable (current-display-type)
   (editor-display-type current-editor))
 
 (define-integrable (current-char-history)
   (editor-char-history current-editor))
+
+(define (increment-select-time!)
+  (let ((time (editor-select-time current-editor)))
+    (set-editor-select-time! current-editor (1+ time))
+    time))
 \f
 (define-structure (button-event (conc-name button-event/))
   (window false read-only true)
index 9b7628ce3571122eb23112670b47f2fa88f205a8..78e961dd469ce10d3a279c0622aa5451e09e1bd0 100644 (file)
@@ -1,5 +1,5 @@
 ;;; -*-Scheme-*-
-;;; $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/edwin.ldr,v 1.10 1990/10/09 16:24:19 cph Exp $
+;;; $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/edwin.ldr,v 1.11 1990/11/02 03:24:04 cph Rel $
 ;;; program to load package contents
 ;;; **** This program (unlike most .ldr files) is not generated by a program.
 
@@ -38,7 +38,6 @@
     (let ((environment (->environment '(EDWIN WINDOW))))
       (load "window" environment)
       (load "utlwin" environment)
-      (load "linwin" environment)
       (load "bufwin" environment)
       (load "bufwfs" environment)
       (load "bufwiu" environment)
@@ -51,7 +50,8 @@
       (load "xterm" env)
       ((access initialize-package! env)))
     (let ((env (->environment '(EDWIN CONSOLE-SCREEN))))
-      (load "cterm" env)
+      (load "termcap" env)
+      (load "tterm" env)
       ((access initialize-package! env)))    
     (load "edtstr" environment)
     (load "editor" environment)
index 41efac4edbf7f9f7504858816331d6f3fe17d918..d8426d5eae0a1ffb8ee13ab8bdc2d8382dc658ae 100644 (file)
@@ -1,6 +1,6 @@
 #| -*-Scheme-*-
 
-$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/edwin.pkg,v 1.20 1990/10/09 16:24:23 cph Exp $
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/edwin.pkg,v 1.21 1990/11/02 03:24:09 cph Exp $
 
 Copyright (c) 1989, 1990 Massachusetts Institute of Technology
 
@@ -192,11 +192,12 @@ MIT in each case. |#
          editor-display-types)
   (export (edwin)
          display-type?
+         display-type/available?
          display-type/make-input-port
          display-type/make-screen
          display-type/multiple-screens?
          display-type/name
-         display-type/with-interrupt-source
+         display-type/with-display-grabbed
          display-type/with-interrupts-disabled
          display-type/with-interrupts-enabled
          make-display-type
@@ -208,41 +209,41 @@ MIT in each case. |#
   (export (edwin)
          initialize-screen-root-window!
          screen-beep
+         screen-clear-rectangle
+         screen-direct-output-char
+         screen-direct-output-move-cursor
+         screen-direct-output-substring
          screen-discard!
          screen-enter!
          screen-exit!
-         screen-flush!
-         screen-highlight?
          screen-in-update?
          screen-modeline-event!
+         screen-move-cursor
+         screen-needs-update?
+         screen-output-char
+         screen-output-substring
          screen-root-window
+         screen-scroll-lines-down
+         screen-scroll-lines-up
          screen-select-cursor!
          screen-select-window!
          screen-selected-window
-         screen-scroll-lines-down!
-         screen-scroll-lines-up!
          screen-state
          screen-typein-window
          screen-window-list
          screen-window0
-         screen-write-char!
-         screen-write-cursor!
-         screen-write-substring!
-         screen-write-substrings!
          screen-x-size
          screen-y-size
+         set-screen-debug-trace!
          set-screen-root-window!
-         subscreen-clear!
          update-screen!
          window-screen
-         with-screen-in-update!
-         with-screen-inverse-video!)
+         with-screen-in-update)
   (export (edwin console-screen)
          make-screen)
   (export (edwin x-screen)
          make-screen
-         set-screen-x-size!
-         set-screen-y-size!))
+         set-screen-size!))
 
 (define-package (edwin x-screen)
   (files "xterm")
@@ -271,10 +272,17 @@ MIT in each case. |#
          update-xterm-screen-names!))
 
 (define-package (edwin console-screen)
-  (files "cterm")
+  (files "termcap" "tterm")
   (parent (edwin))
   (export (edwin)
          console-display-type)
+  (import (runtime primitive-io)
+         channel-type=terminal?
+         terminal-get-state
+         terminal-output-baud-rate
+         terminal-raw-input
+         terminal-raw-output
+         terminal-set-state)
   (import (runtime interrupt-handler)
          hook/^g-interrupt)
   (initialization (initialize-package!)))
@@ -282,7 +290,6 @@ MIT in each case. |#
 (define-package (edwin window)
   (files "window"
         "utlwin"
-        "linwin"
         "bufwin"
         "bufwfs"
         "bufwiu"
@@ -297,6 +304,7 @@ MIT in each case. |#
          edwin-variable$scroll-step
          edwin-variable$truncate-lines
          edwin-variable$truncate-partial-width-windows
+         set-window-debug-trace!
          set-window-point!
          set-window-start-mark!
          window-buffer
@@ -308,14 +316,12 @@ MIT in each case. |#
          window-direct-output-insert-newline!
          window-direct-output-insert-substring!
          window-direct-update!
-         window-end-index
          window-home-cursor!
          window-mark->coordinates
          window-mark->x
          window-mark->y
          window-mark-visible?
          window-modeline-event!
-         window-needs-redisplay?
          window-override-message
          window-point
          window-point-coordinates
@@ -323,13 +329,12 @@ MIT in each case. |#
          window-point-y
          window-root-window
          window-redraw!
-         window-redraw-preserving-point!
          window-scroll-y-absolute!
          window-scroll-y-relative!
          window-select-time
          window-set-override-message!
          window-setup-truncate-lines!
-         window-start-index
+         window-start-mark
          window-y-center)
   (export (edwin screen)
          editor-frame-screen
index 279451f469399fa03c62858c84f7f8785445a493..f1060aaa1d859543ea790eb8fe647bd035013c2d 100644 (file)
@@ -43,7 +43,6 @@
   (read-class-definitions "window")
   (read-class-definitions "utlwin")
   (read-class-definitions "modwin")
-  (read-class-definitions "linwin")
   (read-class-definitions "bufwin")
   (read-class-definitions "comwin")
   (read-class-definitions "buffrm")
index 6f2eb6711d1822620b81b726827e6a2a32dbc858..8cedd5d46046e96c4ab1b0f5d1962b26cc69a8c7 100644 (file)
@@ -1,8 +1,8 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/hlpcom.scm,v 1.92 1989/08/14 09:30:57 cph Exp $
+;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/hlpcom.scm,v 1.93 1990/11/02 03:24:19 cph Exp $
 ;;;
-;;;    Copyright (c) 1986, 1989 Massachusetts Institute of Technology
+;;;    Copyright (c) 1986, 1989, 1990 Massachusetts Institute of Technology
 ;;;
 ;;;    This material was developed by the Scheme project at the
 ;;;    Massachusetts Institute of Technology, Department of
@@ -216,7 +216,10 @@ If you want VALUE to be a string, you must surround it with doublequotes."
             (string-append "Set " (variable-name-string variable) " to value")
             (variable-value variable)))))
   (lambda (variable value)
-    (set-variable-value! (name->variable variable) value)))
+    (let ((variable (name->variable variable)))
+      (if (not (variable-value-valid? variable value))
+         (editor-error "illegal value for variable:" value))
+      (set-variable-value! variable value))))
 
 (define-command make-local-variable
   "Make a variable have a local value in the current buffer."
@@ -227,7 +230,10 @@ If you want VALUE to be a string, you must surround it with doublequotes."
             (string-append "Set " (variable-name-string variable) " to value")
             (variable-value variable)))))
   (lambda (variable value)
-    (make-local-binding! (name->variable variable) value)))
+    (let ((variable (name->variable variable)))
+      (if (not (variable-value-valid? variable value))
+         (editor-error "illegal value for variable:" value))
+      (make-local-binding! variable value))))
 
 (define-command kill-local-variable
   "Make a variable use its global value in the current buffer."
index 30d202c16616f1d063e4bb1c2ce9af807644b470..d762b80eb8a2f47dc7853570dc4a3cb86239b181 100644 (file)
@@ -1,6 +1,6 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/image.scm,v 1.125 1989/08/14 09:22:37 cph Exp $
+;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/image.scm,v 1.126 1990/11/02 03:24:25 cph Rel $
 ;;;
 ;;;    Copyright (c) 1986, 1989 Massachusetts Institute of Technology
 ;;;
 
 (define (image-direct-output-insert-char! image char)
   (vector-set! image 0 (string-append-char (vector-ref image 0) char))
-  (vector-set! image 4 (fix:1+ (vector-ref image 4)))
-  unspecific)
+  (vector-set! image 4 (fix:1+ (vector-ref image 4))))
 
 (define (image-direct-output-insert-substring! image string start end)
   (vector-set! image 0
               (string-append-substring (vector-ref image 0)
                                        string start end))
-  (vector-set! image 4 (fix:+ (vector-ref image 4) (fix:- end start)))
-  unspecific)
+  (vector-set! image 4 (fix:+ (vector-ref image 4) (fix:- end start))))
 \f
 (define (image-representation image)
   (let ((string (image-string image))
           (string-start (image-start-index image))
           (result-start 0))
        (cond ((null? parse)
-              (substring-move-right! string string-start string-end
-                                     result result-start))
+              (substring-move-left! string string-start string-end
+                                    result result-start))
              ((string? (car parse))
               (let ((size (string-length (car parse))))
-                (substring-move-right! (car parse) 0 size result result-start)
+                (substring-move-left! (car parse) 0 size result result-start)
                 (loop (cdr parse)
                       (fix:1+ string-start)
                       (fix:+ result-start size))))
              ((number? (car parse))
-              (substring-move-right! string string-start (car parse)
-                                     result result-start)
+              (substring-move-left! string string-start (car parse)
+                                    result result-start)
               (loop (cdr parse)
                     (car parse)
                     (fix:+ result-start (fix:- (car parse) string-start))))
              (else
-              (error "Bad parse element" (car parse)))))
-      result)))
+              (error "Bad parse element" (car parse))))))
+    result))
 
 (define (image-index->column image index)
   (let loop
           (error "Bad parse element" (car parse))))))
 
 (define (image-column->index image column)
+  ;; If COLUMN falls in the middle of a multi-column character, the
+  ;; index returned is that of the character.  Thinking of the index
+  ;; as a pointer between characters, the value is the pointer to the
+  ;; left of the multi-column character.  Only if COLUMN reaches
+  ;; across the character will the right-hand pointer be returned.
+  ;; Various things depend on this.
   (let loop
       ((parse (image-parse image))
        (start (image-start-index image))
 
 (define (substring-column->index string start end start-column column
                                 #!optional if-lose)
+  ;; If COLUMN falls in the middle of a multi-column character, the
+  ;; index returned is that of the character.  Thinking of the index
+  ;; as a pointer between characters, the value is the pointer to the
+  ;; left of the multi-column character.  Only if COLUMN reaches
+  ;; across the character will the right-hand pointer be returned.
+  ;; Various things depend on this.
   (if (fix:zero? column)
       start
       (let loop ((i start) (c start-column) (left (fix:- column start-column)))
 ;;;; Parsing
 
 (define (parse-substring-for-image string start end start-column receiver)
-  (let loop ((start start) (column start-column) (receiver receiver))
-    (let ((index
-          (substring-find-next-char-in-set string start end
-                                           char-set:not-graphic)))
-      (if (not index)
-         (receiver '() (fix:+ column (fix:- end start)))
-         (let ((column (fix:+ column (fix:- index start))))
-           (let ((representation
-                  (char-representation (string-ref string index) column)))
-             (loop (fix:1+ index)
-                   (fix:+ column (string-length representation))
-                   (lambda (parse column-size)
-                     (receiver (if (fix:= index start)
-                                   (cons representation parse)
-                                   (cons index (cons representation parse)))
-                               column-size)))))))))
+  (let ((column-size))
+    (let ((parse
+          (let loop ((start start) (column start-column))
+            (let ((index
+                   (substring-find-next-char-in-set string start end
+                                                    char-set:not-graphic)))
+              (if (not index)
+                  (begin
+                    (set! column-size (fix:+ column (fix:- end start)))
+                    '())
+                  (let ((column (fix:+ column (fix:- index start))))
+                    (let ((representation
+                           (char-representation (string-ref string index)
+                                                column)))
+                      (let ((parse
+                             (loop (fix:1+ index)
+                                   (fix:+ column
+                                          (string-length representation)))))
+                        (if (fix:= index start)
+                            (cons representation parse)
+                            (cons index (cons representation parse)))))))))))
+      (receiver parse column-size))))
 
 (define char-column-length)
 (define char-representation)
         "\370" "\371" "\372" "\373" "\374" "\375" "\376" "\377")))
   (set! char-representation
        (lambda (char column)
-         (if (char=? char #\Tab)
-             (vector-ref tab-display-images (remainder column 8))
-             (vector-ref display-images (char->ascii char)))))
+         (if (char=? char #\tab)
+             (vector-ref tab-display-images (fix:remainder column 8))
+             (vector-ref display-images (char->integer char)))))
   (let ((tab-display-lengths (vector-map tab-display-images string-length))
        (display-lengths (vector-map display-images string-length)))
     (set! char-column-length
          (lambda (char column)
-           (if (char=? char #\Tab)
-               (vector-ref tab-display-lengths (remainder column 8))
-               (vector-ref display-lengths (char->ascii char)))))
+           (if (char=? char #\tab)
+               (vector-ref tab-display-lengths (fix:remainder column 8))
+               (vector-ref display-lengths (char->integer char)))))
     unspecific))
\ No newline at end of file
index 5c5b222bb7b44c7d6427ddaba8f39a94f1bc44a8..f665d00cdde1ed62e8b15f7c0503ac14cb683737 100644 (file)
@@ -1,6 +1,6 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/modlin.scm,v 1.4 1990/10/09 16:24:36 cph Exp $
+;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/modlin.scm,v 1.5 1990/11/02 03:24:31 cph Rel $
 ;;;
 ;;;    Copyright (c) 1989, 1990 Massachusetts Institute of Technology
 ;;;
@@ -266,18 +266,23 @@ If #F, the normal method is used."
       ((#\s)
        "no processes")
       ((#\p)
-       (if (window-mark-visible? window (buffer-start buffer))
-          (if (window-mark-visible? window (buffer-end buffer))
-              "All" "Top")
-          (if (window-mark-visible? window (buffer-end buffer))
-              "Bottom"
+       (if (let ((end (buffer-end buffer)))
+            (or (window-mark-visible? window end)
+                (and (line-start? end)
+                     (not (group-start? end))
+                     (window-mark-visible? window (mark-1+ end)))))
+          (if (window-mark-visible? window (buffer-start buffer))
+              "All"
+              "Bottom")
+          (if (window-mark-visible? window (buffer-start buffer))
+              "Top"
               (string-append
                (string-pad-left
                 (number->string
                  (min
                   (let ((start (mark-index (buffer-start buffer))))
                     (integer-round
-                     (* 100 (- (window-start-index window) start))
+                     (* 100 (- (mark-index (window-start-mark window)) start))
                      (- (mark-index (buffer-end buffer)) start)))
                   99))
                 2)
index 3750ffcee583e78d3af072c2282cfe575bf53cbb..998824075f4256bd28e99f1c86e0a0c498790310 100644 (file)
@@ -1,6 +1,6 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/modwin.scm,v 1.34 1990/10/05 13:32:48 cph Exp $
+;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/modwin.scm,v 1.35 1990/11/02 03:24:36 cph Rel $
 ;;;
 ;;;    Copyright (c) 1986, 1989, 1990 Massachusetts Institute of Technology
 ;;;
 ;;;; Modeline Window
 
 (declare (usual-integrations))
-
+\f
 (define-class modeline-window vanilla-window ())
 
 (define-method modeline-window (:initialize! window window*)
   (usual=> window :initialize! window*)
   (set! y-size 1))
 
-(define-method modeline-window (:update-display! window screen x-start y-start
-                                                xl xu yl yu display-style)
+(define (modeline-window:update-display! window screen x-start y-start
+                                        xl xu yl yu display-style)
   display-style                                ;ignore
   (if (< yl yu)
-      (let ((thunk
-            (lambda ()
-              (screen-write-substring!
-               screen x-start y-start
-               (string-pad-right (modeline-string superior) x-size #\-)
-               xl xu))))
-       (if (variable-local-value
-            (window-buffer superior)
-            (ref-variable-object mode-line-inverse-video))
-           (with-screen-inverse-video! screen thunk)
-           (thunk))))
+      (let ((superior (window-superior window)))
+       (screen-output-substring
+        screen x-start y-start
+        (string-pad-right (modeline-string superior)
+                          (window-x-size window)
+                          #\space)
+        xl xu
+        (variable-local-value
+         (window-buffer superior)
+         (ref-variable-object mode-line-inverse-video)))))
   true)
 
+(define-method modeline-window :update-display!
+  modeline-window:update-display!)
+
 (define-variable mode-line-inverse-video
   "*True means use inverse video, or other suitable display mode, for the mode line."
   true)
index 2f241ba680568d990f7e0526443c5cfc084e5572..93f21506e718aef7c832ee50bbbbe3b7b9dd5a29 100644 (file)
@@ -1,6 +1,8 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    Copyright (c) 1989 Massachusetts Institute of Technology
+;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/rename.scm,v 1.4 1990/11/02 03:24:41 cph Rel $
+;;;
+;;;    Copyright (c) 1989, 1990 Massachusetts Institute of Technology
 ;;;
 ;;;    This material was developed by the Scheme project at the
 ;;;    Massachusetts Institute of Technology, Department of
@@ -43,7 +45,7 @@
 ;;;; Edwin Interpackage Renames
 
 (declare (usual-integrations))
-\f
+
 (let ((global (->environment '()))
       (edwin (->environment '(edwin)))
       (window (->environment '(edwin window))))
@@ -57,4 +59,5 @@
     (e<-w 'window? 'buffer-frame?)
     (e<-w 'window-x-size 'buffer-frame-x-size)
     (e<-w 'window-y-size 'buffer-frame-y-size)
+    (e<-w 'window-needs-redisplay? 'buffer-frame-needs-redisplay?)
     (e<-w '%set-window-buffer! 'set-window-buffer!)))
\ No newline at end of file
index 0c1cb13e80f118c38fea6eb82eefb3d6cf45766e..5e8db254aa3de70079f3af8ea7cf9687efbd2422 100644 (file)
@@ -1,6 +1,6 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/screen.scm,v 1.84 1990/10/09 16:24:41 cph Exp $
+;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/screen.scm,v 1.85 1990/11/02 03:24:45 cph Rel $
 ;;;
 ;;;    Copyright (c) 1989, 1990 Massachusetts Institute of Technology
 ;;;
                   (constructor make-screen
                                (state
                                 operation/beep
+                                operation/clear-line!
+                                operation/clear-rectangle!
+                                operation/clear-screen!
                                 operation/discard!
                                 operation/enter!
                                 operation/exit!
-                                operation/finish-update!
                                 operation/flush!
-                                operation/inverse-video!
                                 operation/modeline-event!
-                                operation/normal-video!
+                                operation/preempt-update?
                                 operation/scroll-lines-down!
                                 operation/scroll-lines-up!
-                                operation/start-update!
-                                operation/subscreen-clear!
-                                operation/wipe!
+                                operation/wrap-update!
                                 operation/write-char!
                                 operation/write-cursor!
                                 operation/write-substring!
                                 y-size)))
   (state false read-only true)
   (operation/beep false read-only true)
+  (operation/clear-line! false read-only true)
+  (operation/clear-rectangle! false read-only true)
+  (operation/clear-screen! false read-only true)
   (operation/discard! false read-only true)
   (operation/enter! false read-only true)
   (operation/exit! false read-only true)
-  (operation/finish-update! false read-only true)
   (operation/flush! false read-only true)
-  (operation/inverse-video! false read-only true)
   (operation/modeline-event! false read-only true)
-  (operation/normal-video! false read-only true)
+  (operation/preempt-update? false read-only true)
   (operation/scroll-lines-down! false read-only true)
   (operation/scroll-lines-up! false read-only true)
-  (operation/start-update! false read-only true)
-  (operation/subscreen-clear! false read-only true)
-  (operation/wipe! false read-only true)
+  (operation/wrap-update! false read-only true)
   (operation/write-char! false read-only true)
   (operation/write-cursor! false read-only true)
   (operation/write-substring! false read-only true)
   (operation/x-size false read-only true)
   (operation/y-size false read-only true)
   (root-window false)
+  (needs-update? false)
   (in-update? false)
   (x-size false)
   (y-size false)
-  (highlight? false))
+
+  ;; Description of actual screen contents.
+  current-matrix
+
+  ;; Description of desired screen contents.
+  new-matrix
+
+  ;; Set this variable in the debugger to force a display preemption.
+  (debug-preemption-y false)
+
+  ;; Set this variable in the debugger to trace interesting events.
+  (debug-trace false))
 
 (define (initialize-screen-root-window! screen bufferset buffer)
   (set-screen-root-window!
    (make-editor-frame
     screen
     buffer
-    (bufferset-find-or-create-buffer bufferset (make-typein-buffer-name -1)))))
-\f
-(define (with-screen-in-update! screen thunk)
-  (call-with-current-continuation
-   (lambda (continuation)
-     (let ((old-flag)
-          (new-flag true)
-          (transition
-           (lambda (old new)
-             (if old
-                 (if (not new)
-                     (begin
-                       ((screen-operation/finish-update! screen) screen)
-                       (set-screen-in-update?! screen false)))
-                 (if new
-                     (begin
-                       ((screen-operation/start-update! screen) screen)
-                       (set-screen-in-update?! screen continuation)))))))
-       (dynamic-wind (lambda ()
-                      (set! old-flag (screen-in-update? screen))
-                      (transition old-flag new-flag))
-                    thunk
-                    (lambda ()
-                      (set! new-flag (screen-in-update? screen))
-                      (transition new-flag old-flag)))))))
-
-(define (with-screen-inverse-video! screen thunk)
-  (let ((old-highlight?)
-       (new-highlight? true)
-       (transition
-        (lambda (old new)
-          (if old
-              (if (not new)
-                  (begin
-                    ((screen-operation/normal-video! screen) screen)
-                    (set-screen-highlight?! screen false)))
-              (if new
-                  (begin
-                    ((screen-operation/inverse-video! screen) screen)
-                    (set-screen-highlight?! screen true)))))))
-    (dynamic-wind (lambda ()
-                   (set! old-highlight? (screen-highlight? screen))
-                   (transition old-highlight? new-highlight?))
-                 thunk
-                 (lambda ()
-                   (set! new-highlight? (screen-highlight? screen))
-                   (transition new-highlight? old-highlight?)))))
+    (bufferset-find-or-create-buffer bufferset (make-typein-buffer-name -1))))
+  (set-screen-current-matrix! screen (make-matrix screen))
+  (set-screen-new-matrix! screen (make-matrix screen)))
 \f
 (define (screen-beep screen)
   ((screen-operation/beep screen) screen))
 
-(define (screen-flush! screen)
-  ((screen-operation/flush! screen) screen))
-
-(define (subscreen-clear! screen xl xu yl yu)
-  ((screen-operation/subscreen-clear! screen) screen xl xu yl yu))
-
-(define (screen-write-cursor! screen x y)
-  ((screen-operation/write-cursor! screen) screen x y))
-
-(define (screen-write-char! screen x y char)
-  ((screen-operation/write-char! screen) screen x y char))
-
-(define (screen-write-substring! screen x y string start end)
-  ((screen-operation/write-substring! screen) screen x y string start end))
-
-(define (screen-write-substrings! screen x y strings bil biu bjl bju)
-  (let ((write-substring! (screen-operation/write-substring! screen)))
-    (clip (screen-x-size screen) x bil biu
-      (lambda (bxl ail aiu)
-       (clip (screen-y-size screen) y bjl bju
-         (lambda (byl ajl aju)
-           (let loop ((y byl) (j ajl))
-             (if (fix:< j aju)
-                 (begin
-                   (write-substring! screen bxl y
-                                     (vector-ref strings j) ail aiu)
-                   (loop (fix:1+ y) (fix:1+ j)))))))))))
-
-(define (clip axu x bil biu receiver)
-  (let ((ail (fix:- bil x)))
-    (if (fix:< ail biu)
-       (let ((aiu (fix:+ ail axu)))
-         (cond ((not (fix:positive? x))
-                (receiver 0 ail (if (fix:< aiu biu) aiu biu)))
-               ((fix:< x axu)
-                (receiver x bil (if (fix:< aiu biu) aiu biu))))))))
-
-(define (screen-scroll-lines-down! screen xl xu yl yu amount)
-  ((screen-operation/scroll-lines-down! screen) screen xl xu yl yu amount))
-
-(define (screen-scroll-lines-up! screen xl xu yl yu amount)
-  ((screen-operation/scroll-lines-up! screen) screen xl xu yl yu amount))
-
 (define (screen-enter! screen)
   ((screen-operation/enter! screen) screen)
   (screen-modeline-event! screen
 
 (define (screen-modeline-event! screen window type)
   ((screen-operation/modeline-event! screen) screen window type))
-\f
+
 (define-integrable (screen-selected-window screen)
   (editor-frame-selected-window (screen-root-window screen)))
 
   (editor-frame-screen (window-root-window window)))
 
 (define (update-screen! screen display-style)
-  (if display-style ((screen-operation/wipe! screen) screen))
-  (editor-frame-update-display! (screen-root-window screen) display-style))
\ No newline at end of file
+  (if display-style (screen-force-update screen))
+  (with-screen-in-update screen display-style
+    (lambda ()
+      (editor-frame-update-display! (screen-root-window screen)
+                                   display-style))))
+\f
+;;; Interface from update optimizer to terminal:
+
+(define-integrable (terminal-scroll-lines-down screen xl xu yl yu amount)
+  (if (screen-debug-trace screen)
+      ((screen-debug-trace screen) 'terminal screen 'scroll-lines-down
+                                  xl xu yl yu amount))
+  ((screen-operation/scroll-lines-down! screen) screen xl xu yl yu amount))
+
+(define-integrable (terminal-scroll-lines-up screen xl xu yl yu amount)
+  (if (screen-debug-trace screen)
+      ((screen-debug-trace screen) 'terminal screen 'scroll-lines-up
+                                  xl xu yl yu amount))
+  ((screen-operation/scroll-lines-up! screen) screen xl xu yl yu amount))
+
+(define-integrable (terminal-flush screen)
+  (if (screen-debug-trace screen)
+      ((screen-debug-trace screen) 'terminal screen 'flush))
+  ((screen-operation/flush! screen) screen))
+
+(define-integrable (terminal-move-cursor screen x y)
+  (if (screen-debug-trace screen)
+      ((screen-debug-trace screen) 'terminal screen 'move-cursor x y))
+  ((screen-operation/write-cursor! screen) screen x y))
+
+(define-integrable (terminal-preempt-update? screen y)
+  ((screen-operation/preempt-update? screen) screen y))
+
+(define-integrable (terminal-clear-screen screen)
+  (if (screen-debug-trace screen)
+      ((screen-debug-trace screen) 'terminal screen 'clear-screen))
+  ((screen-operation/clear-screen! screen) screen))
+
+(define-integrable (terminal-clear-line screen x y first-unused-x)
+  (if (screen-debug-trace screen)
+      ((screen-debug-trace screen) 'terminal screen 'clear-line
+                                  x y first-unused-x))
+  ((screen-operation/clear-line! screen) screen x y first-unused-x))
+
+(define-integrable (terminal-output-char screen x y char highlight)
+  (if (screen-debug-trace screen)
+      ((screen-debug-trace screen) 'terminal screen 'output-char
+                                  x y char highlight))
+  ((screen-operation/write-char! screen) screen x y char highlight))
+
+(define-integrable (terminal-output-substring screen x y string start end
+                                             highlight)
+  (if (screen-debug-trace screen)
+      ((screen-debug-trace screen) 'terminal screen 'output-substring
+                                  x y (string-copy string) start end
+                                  highlight))
+  ((screen-operation/write-substring! screen) screen x y string start end
+                                             highlight))
+\f
+;;;; Update Optimization
+
+(define-structure (matrix (constructor %make-matrix ()))
+  ;; Vector of line contents.
+  ;; (string-ref (vector-ref (matrix-contents m) y) x) is the
+  ;; character at position X, Y.
+  contents
+
+  ;; Vector of line highlights.
+  ;; (boolean-vector-ref (vector-ref (matrix-highlight m) y) x) is the
+  ;; highlight at position X, Y.
+  highlight
+
+  ;; Boolean-vector indicating, for each line, whether its contents
+  ;; mean anything.
+  enable
+
+  ;; Cursor position.
+  cursor-x
+  cursor-y)
+
+(define (make-matrix screen)
+  (let ((matrix (%make-matrix))
+       (x-size (screen-x-size screen))
+       (y-size (screen-y-size screen)))
+    (let ((contents (make-vector y-size))
+         (highlight (make-vector y-size))
+         (enable (make-boolean-vector y-size)))
+      (do ((i 0 (fix:1+ i)))
+         ((fix:= i y-size))
+       (vector-set! contents i (make-string x-size))
+       (vector-set! highlight i (make-boolean-vector x-size)))
+      (boolean-vector-fill! enable false)
+      (set-matrix-contents! matrix contents)
+      (set-matrix-highlight! matrix highlight)
+      (set-matrix-enable! matrix enable))
+    (set-matrix-cursor-x! matrix false)
+    (set-matrix-cursor-y! matrix false)
+    matrix))
+
+(define (set-screen-size! screen x-size y-size)
+  (if (screen-debug-trace screen)
+      ((screen-debug-trace screen) 'screen screen 'set-size! x-size y-size))
+  (without-interrupts
+   (lambda ()
+     (set-screen-x-size! screen x-size)
+     (set-screen-y-size! screen y-size)
+     (set-screen-current-matrix! screen (make-matrix screen))
+     (set-screen-new-matrix! screen (make-matrix screen))
+     (send (screen-root-window screen) ':set-size! x-size y-size))))
+
+(define (screen-move-cursor screen x y)
+  (if (screen-debug-trace screen)
+      ((screen-debug-trace screen) 'screen screen 'move-cursor x y))
+  (let ((new-matrix (screen-new-matrix screen)))
+    (set-matrix-cursor-x! new-matrix x)
+    (set-matrix-cursor-y! new-matrix y)))
+
+(define (screen-direct-output-move-cursor screen x y)
+  (if (screen-debug-trace screen)
+      ((screen-debug-trace screen) 'screen screen 'direct-output-move-cursor
+                                  x y))
+  (terminal-move-cursor screen x y)
+  (terminal-flush screen)
+  (let ((current-matrix (screen-current-matrix screen))
+       (new-matrix (screen-new-matrix screen)))
+    (set-matrix-cursor-x! current-matrix x)
+    (set-matrix-cursor-y! current-matrix y)
+    (set-matrix-cursor-x! new-matrix x)
+    (set-matrix-cursor-y! new-matrix y)))
+\f
+(define (screen-output-char screen x y char highlight)
+  (if (screen-debug-trace screen)
+      ((screen-debug-trace screen) 'screen screen 'output-char
+                                  x y char highlight))
+  (let ((new-matrix (screen-new-matrix screen)))
+    (if (not (boolean-vector-ref (matrix-enable new-matrix) y))
+       (begin
+         (boolean-vector-set! (matrix-enable new-matrix) y true)
+         (set-screen-needs-update?! screen true)
+         (guarantee-display-line screen y)))
+    (string-set! (vector-ref (matrix-contents new-matrix) y) x char)
+    (boolean-vector-set! (vector-ref (matrix-highlight new-matrix) y)
+                        x
+                        highlight)))
+
+(define (screen-direct-output-char screen x y char highlight)
+  (if (screen-debug-trace screen)
+      ((screen-debug-trace screen) 'screen screen 'direct-output-char
+                                  x y char highlight))
+  (let ((cursor-x (fix:1+ x))
+       (current-matrix (screen-current-matrix screen)))
+    (terminal-output-char screen x y char highlight)
+    (terminal-move-cursor screen cursor-x y)
+    (terminal-flush screen)
+    (string-set! (vector-ref (matrix-contents current-matrix) y) x char)
+    (boolean-vector-set! (vector-ref (matrix-highlight current-matrix) y)
+                        x
+                        highlight)
+    (set-matrix-cursor-x! current-matrix cursor-x)
+    (set-matrix-cursor-x! (screen-new-matrix screen) cursor-x)))
+
+(define (screen-output-substring screen x y string start end highlight)
+  (if (screen-debug-trace screen)
+      ((screen-debug-trace screen) 'screen screen 'output-substring
+                                  x y (string-copy string) start end
+                                  highlight))
+  (let ((new-matrix (screen-new-matrix screen)))
+    (if (not (boolean-vector-ref (matrix-enable new-matrix) y))
+       (begin
+         (boolean-vector-set! (matrix-enable new-matrix) y true)
+         (set-screen-needs-update?! screen true)
+         (guarantee-display-line screen y)))
+    (substring-move-left! string start end
+                         (vector-ref (matrix-contents new-matrix) y) x)
+    (boolean-subvector-fill! (vector-ref (matrix-highlight new-matrix) y)
+                            x (fix:+ x (fix:- end start)) highlight)))
+
+(define (screen-direct-output-substring screen x y string start end highlight)
+  (if (screen-debug-trace screen)
+      ((screen-debug-trace screen) 'screen screen 'direct-output-substring
+                                  x y (string-copy string) start end
+                                  highlight))
+  (let ((cursor-x (fix:+ x (fix:- end start)))
+       (current-matrix (screen-current-matrix screen)))
+    (terminal-output-substring screen x y string start end highlight)
+    (terminal-move-cursor screen cursor-x y)
+    (terminal-flush screen)
+    (substring-move-left! string start end
+                         (vector-ref (matrix-contents current-matrix) y) x)
+    (boolean-subvector-fill! (vector-ref (matrix-highlight current-matrix) y)
+                            x cursor-x highlight)
+    (set-matrix-cursor-x! current-matrix cursor-x)
+    (set-matrix-cursor-x! (screen-new-matrix screen) cursor-x)))
+
+(define (guarantee-display-line screen y)
+  (let ((current-matrix (screen-current-matrix screen))
+       (new-matrix (screen-new-matrix screen)))
+    (if (boolean-vector-ref (matrix-enable current-matrix) y)
+       (begin
+         (string-move! (vector-ref (matrix-contents current-matrix) y)
+                       (vector-ref (matrix-contents new-matrix) y))
+         (boolean-vector-move!
+          (vector-ref (matrix-highlight current-matrix) y)
+          (vector-ref (matrix-highlight new-matrix) y)))
+       (begin
+         (string-fill! (vector-ref (matrix-contents new-matrix) y) #\space)
+         (boolean-vector-fill! (vector-ref (matrix-highlight new-matrix) y)
+                               false)))))
+\f
+(define (screen-clear-rectangle screen xl xu yl yu highlight)
+  (if (screen-debug-trace screen)
+      ((screen-debug-trace screen) 'screen screen 'clear-rectangle
+                                  xl xu yl yu highlight))
+  (let ((current-matrix (screen-current-matrix screen))
+       (new-matrix (screen-new-matrix screen)))
+    (let ((current-contents (matrix-contents current-matrix))
+         (current-highlight (matrix-highlight current-matrix))
+         (current-enable (matrix-enable current-matrix))
+         (new-contents (matrix-contents new-matrix))
+         (new-highlight (matrix-highlight new-matrix))
+         (new-enable (matrix-enable new-matrix)))
+      (if (and (fix:= xl 0) (fix:= xu (screen-x-size screen)))
+         (do ((y yl (fix:1+ y)))
+             ((fix:= y yu))
+           (string-fill! (vector-ref new-contents y) #\space)
+           (boolean-vector-fill! (vector-ref new-highlight y) highlight)
+           (boolean-vector-set! new-enable y true))
+         (do ((y yl (fix:1+ y)))
+             ((fix:= y yu))
+           (let ((nl (vector-ref new-contents y))
+                 (nh (vector-ref new-highlight y)))
+             (if (boolean-vector-ref new-enable y)
+                 (begin
+                   (substring-fill! nl xl xu #\space)
+                   (boolean-subvector-fill! nh xl xu highlight))
+                 (begin
+                   (boolean-vector-set! new-enable y true)
+                   (set-screen-needs-update?! screen true)
+                   (if (boolean-vector-ref current-enable y)
+                       (begin
+                         (string-move! (vector-ref current-contents y) nl)
+                         (boolean-vector-move!
+                          (vector-ref current-highlight y)
+                          nh)
+                         (substring-fill! nl xl xu #\space)
+                         (boolean-subvector-fill! nh xl xu highlight))
+                       (begin
+                         (string-fill! nl #\space)
+                         (boolean-vector-fill! nh false)
+                         (if highlight
+                             (boolean-subvector-fill! nh xl xu
+                                                      highlight))))))))))))
+
+(define (screen-force-update screen)
+  (if (screen-debug-trace screen)
+      ((screen-debug-trace screen) 'screen screen 'force-update))
+  (let ((y-size (screen-y-size screen))
+       (current-matrix (screen-current-matrix screen))
+       (new-matrix (screen-new-matrix screen)))
+    (terminal-clear-screen screen)
+    (let ((current-contents (matrix-contents current-matrix))
+         (current-highlight (matrix-highlight current-matrix))
+         (current-enable (matrix-enable current-matrix))
+         (new-contents (matrix-contents new-matrix))
+         (new-highlight (matrix-highlight new-matrix))
+         (new-enable (matrix-enable new-matrix)))
+      (do ((y 0 (fix:1+ y)))
+         ((fix:= y y-size))
+       (if (boolean-vector-ref current-enable y)
+           (begin
+             (boolean-vector-set! current-enable y false)
+             (if (not (boolean-vector-ref new-enable y))
+                 (begin
+                   (string-move! (vector-ref current-contents y)
+                                 (vector-ref new-contents y))
+                   (boolean-vector-move! (vector-ref current-highlight y)
+                                         (vector-ref new-highlight y))))))
+       (string-fill! (vector-ref current-contents y) #\space)
+       (boolean-vector-fill! (vector-ref current-highlight y) false))
+      (boolean-vector-fill! current-enable true)))
+  (set-screen-needs-update?! screen true))
+\f
+(define (screen-scroll-lines-down screen xl xu yl yu amount)
+  (if (screen-debug-trace screen)
+      ((screen-debug-trace screen) 'screen screen 'scroll-lines-down
+                                  xl xu yl yu amount))
+  (let ((current-matrix (screen-current-matrix screen)))
+    (and (boolean-subvector-all-elements? (matrix-enable current-matrix)
+                                         yl yu true)
+        (not (screen-needs-update? screen))
+        (let ((scrolled?
+               (terminal-scroll-lines-down screen xl xu yl yu amount)))
+          (and scrolled?
+               (begin
+                 (let ((contents (matrix-contents current-matrix))
+                       (highlight (matrix-highlight current-matrix)))
+                   (do ((y (fix:-1+ (fix:- yu amount)) (fix:-1+ y))
+                        (y* (fix:-1+ yu) (fix:-1+ y*)))
+                       ((fix:< y yl))
+                     (substring-move-left! (vector-ref contents y) xl xu
+                                           (vector-ref contents y*) xl)
+                     (boolean-subvector-move-left!
+                      (vector-ref highlight y) xl xu
+                      (vector-ref highlight y*) xl)))
+                 (if (eq? scrolled? 'CLEARED)
+                     (matrix-clear-rectangle current-matrix
+                                             xl xu yl (fix:+ yl amount)
+                                             false))
+                 scrolled?))))))
+
+(define (screen-scroll-lines-up screen xl xu yl yu amount)
+  (if (screen-debug-trace screen)
+      ((screen-debug-trace screen) 'screen screen 'scroll-lines-up
+                                  xl xu yl yu amount))
+  (let ((current-matrix (screen-current-matrix screen)))
+    (and (boolean-subvector-all-elements? (matrix-enable current-matrix)
+                                         yl yu true)
+        (not (screen-needs-update? screen))
+        (let ((scrolled?
+               (terminal-scroll-lines-up screen xl xu yl yu amount)))
+          (and scrolled?
+               (begin
+                 (let ((contents (matrix-contents current-matrix))
+                       (highlight (matrix-highlight current-matrix)))
+                   (do ((y yl (fix:1+ y))
+                        (y* (fix:+ yl amount) (fix:1+ y*)))
+                       ((fix:= y* yu))
+                     (substring-move-left! (vector-ref contents y*) xl xu
+                                           (vector-ref contents y) xl)
+                     (boolean-subvector-move-left!
+                      (vector-ref highlight y*) xl xu
+                      (vector-ref highlight y) xl)))
+                 (if (eq? scrolled? 'CLEARED)
+                     (matrix-clear-rectangle current-matrix
+                                             xl xu (fix:- yu amount) yu
+                                             false))
+                 scrolled?))))))
+
+(define (matrix-clear-rectangle matrix xl xu yl yu hl)
+  (let ((contents (matrix-contents matrix))
+       (highlight (matrix-highlight matrix)))
+    (do ((y yl (fix:1+ y)))
+       ((fix:= y yu))
+      (substring-fill! (vector-ref contents y) xl xu #\space)
+      (boolean-subvector-fill! (vector-ref highlight y) xl xu hl))))
+\f
+(define (with-screen-in-update screen display-style thunk)
+  (without-interrupts
+   (lambda ()
+     (call-with-current-continuation
+      (lambda (continuation)
+       (let ((old-flag))
+         (dynamic-wind (lambda ()
+                         (set! old-flag (screen-in-update? screen))
+                         (set-screen-in-update?! screen
+                                                 (or old-flag continuation)))
+                       (lambda ()
+                         ((screen-operation/wrap-update! screen)
+                          screen
+                          (lambda ()
+                            (and (thunk)
+                                 (screen-update screen display-style)))))
+                       (lambda ()
+                         (set-screen-in-update?! screen old-flag)
+                         (set! old-flag)
+                         unspecific))))))))
+
+(define (screen-update screen force?)
+  ;; Update the actual terminal screen based on the data in `new-matrix'.
+  ;; Value is #F if redisplay stopped due to pending input.
+  ;; FORCE? true means do not stop for pending input.
+  (if (screen-debug-trace screen)
+      ((screen-debug-trace screen) 'screen screen 'update force?))
+  (let ((current-matrix (screen-current-matrix screen))
+       (new-matrix (screen-new-matrix screen))
+       (y-size (screen-y-size screen)))
+    (let ((enable (matrix-enable new-matrix)))
+      (let loop ((y 0))
+       (cond ((fix:= y y-size)
+              (let ((x (matrix-cursor-x new-matrix))
+                    (y (matrix-cursor-y new-matrix)))
+                (terminal-move-cursor screen x y)
+                (set-matrix-cursor-x! current-matrix x)
+                (set-matrix-cursor-y! current-matrix y))
+              (set-screen-needs-update?! screen false)
+              true)
+             ((and (terminal-preempt-update? screen y)
+                   ;; `terminal-preempt-update?' has side-effects,
+                   ;; and it must be run regardless of `force?'.
+                   (not force?)
+                   (or (keyboard-active? 0)
+                       (eq? (screen-debug-preemption-y screen) y)))
+              (terminal-move-cursor screen
+                                    (matrix-cursor-x current-matrix)
+                                    (matrix-cursor-y current-matrix))
+              (if (screen-debug-trace screen)
+                  ((screen-debug-trace screen) 'screen screen
+                                               'update-preemption y))
+              false)
+             (else
+              (if (boolean-vector-ref enable y)
+                  (update-line screen y))
+              (loop (fix:1+ y))))))))
+\f
+(define (update-line screen y)
+  (let ((current-matrix (screen-current-matrix screen))
+       (new-matrix (screen-new-matrix screen))
+       (x-size (screen-x-size screen)))
+    (let ((current-contents (vector-ref (matrix-contents current-matrix) y))
+         (current-highlight (vector-ref (matrix-highlight current-matrix) y))
+         (new-contents (vector-ref (matrix-contents new-matrix) y))
+         (new-highlight (vector-ref (matrix-highlight new-matrix) y)))
+      (cond ((not (and (boolean-vector-ref (matrix-enable current-matrix) y)
+                      (boolean-vector=? current-highlight new-highlight)))
+            (update-line-ignore-current screen y
+                                        new-contents new-highlight x-size))
+           ((string=? current-contents new-contents)
+            unspecific)
+           ((boolean-vector-all-elements? new-highlight false)
+            (update-line-no-highlight screen y current-contents new-contents))
+           (else
+            (update-line-ignore-current screen y
+                                        new-contents new-highlight x-size)))
+      ;; Update current-matrix to contain the new line.
+      (vector-set! (matrix-contents current-matrix) y new-contents)
+      (vector-set! (matrix-highlight current-matrix) y new-highlight)
+      (boolean-vector-set! (matrix-enable current-matrix) y true)
+      ;; Move the old line to new-matrix so that it can be reused.
+      (vector-set! (matrix-contents new-matrix) y current-contents)
+      (vector-set! (matrix-highlight new-matrix) y current-highlight)
+      (boolean-vector-set! (matrix-enable new-matrix) y false))))
+
+(define (update-line-no-highlight screen y oline nline)
+  (let ((x-size (screen-x-size screen)))
+    (let ((olen (substring-non-space-end oline 0 x-size))
+         (nlen (substring-non-space-end nline 0 x-size)))
+      (let ((len (fix:min olen nlen)))
+       (let loop ((x 0))
+         (let ((x
+                (fix:+ x (substring-match-forward oline x len nline x len))))
+           (if (fix:= x len)
+               (if (fix:< x nlen)
+                   (terminal-output-substring screen x y
+                                              nline x nlen false))
+               (let find-match ((x* (fix:1+ x)))
+                 (cond ((fix:= x* len)
+                        (if (fix:< x nlen)
+                            (terminal-output-substring screen x y
+                                                       nline x nlen false)))
+                       ((fix:= (vector-8b-ref oline x*)
+                               (vector-8b-ref nline x*))
+                        (let ((n
+                               (substring-match-forward oline x* len
+                                                        nline x* len)))
+                          ;; Ignore matches of 4 characters or less.  The
+                          ;; overhead of moving the cursor and drawing
+                          ;; the characters is too much except for very
+                          ;; slow terminals.
+                          (if (fix:< n 5)
+                              (find-match (fix:+ x* n))
+                              (begin
+                                (terminal-output-substring screen x y
+                                                           nline x x* false)
+                                (loop (fix:+ x* n))))))
+                       (else
+                        (find-match (fix:1+ x*)))))))))
+      (if (fix:< nlen olen)
+         (terminal-clear-line screen nlen y olen)))))
+\f
+(define (update-line-ignore-current screen y nline highlight x-size)
+  (cond ((not (boolean-subvector-uniform? highlight 0 x-size))
+        (let loop ((x 0))
+          (let ((hl (boolean-vector-ref highlight x)))
+            (let ((x*
+                   (boolean-subvector-find-next highlight (fix:1+ x) x-size
+                                                (not hl))))
+              (if x*
+                  (begin
+                    (terminal-output-substring screen x y nline x x* hl)
+                    (loop x*))
+                  (terminal-output-substring screen x y nline x x-size
+                                             hl))))))
+       ((boolean-vector-ref highlight 0)
+        (terminal-output-substring screen 0 y nline 0 x-size true))
+       (else
+        (let ((xe (substring-non-space-end nline 0 x-size)))
+          (if (fix:< 0 xe)
+              (terminal-output-substring screen 0 y nline 0 xe false))
+          (if (fix:< xe x-size)
+              (terminal-clear-line screen xe y x-size))))))
+\f
+(define-integrable (fix:min x y) (if (fix:< x y) x y))
+(define-integrable (fix:max x y) (if (fix:> x y) x y))
+
+(define (substring-non-space-end string start end)
+  (let ((index
+        (substring-find-previous-char-in-set string start end
+                                             char-set/not-space)))
+    (if index
+       (fix:1+ index)
+       start)))
+
+(define-integrable (substring-blank? string start end)
+  (not (substring-find-next-char-in-set string start end char-set/not-space)))
+
+(define char-set/not-space
+  (char-set-invert (char-set #\space)))
+
+(define (string-move! x y)
+  (substring-move-left! x 0 (string-length x) y 0))
+
+(define-integrable (boolean-vector-ref vector index)
+  (fix:= (char->integer #\t) (vector-8b-ref vector index)))
+
+(define-integrable (boolean-vector-set! vector index value)
+  (vector-8b-set! vector index (boolean->ascii value)))
+
+(define (boolean-vector-all-elements? vector value)
+  (boolean-subvector-all-elements? vector 0 (boolean-vector-length vector)
+                                  value))
+
+(define (boolean-subvector-all-elements? vector start end value)
+  (if (vector-8b-find-next-char vector start end (boolean->ascii (not value)))
+      false
+      true))
+
+(define (boolean-subvector-uniform? vector start end)
+  (if (and (fix:< start end)
+          (vector-8b-find-next-char
+           vector start end
+           (boolean->ascii (not (boolean-vector-ref vector start)))))
+      false
+      true))
+
+(define-integrable (boolean-subvector-find-next vector start end value)
+  (vector-8b-find-next-char vector start end (boolean->ascii value)))
+
+(define-integrable make-boolean-vector string-allocate)
+(define-integrable boolean-vector-length string-length)
+(define-integrable boolean-vector=? string=?)
+(define-integrable boolean-subvector-move-right! substring-move-right!)
+(define-integrable boolean-subvector-move-left! substring-move-left!)
+(define-integrable boolean-vector-move! string-move!)
+(define-integrable boolean-vector-copy string-copy)
+
+(define-integrable (boolean-subvector-fill! vector start end value)
+  (vector-8b-fill! vector start end (boolean->ascii value)))
+
+(define (boolean-vector-fill! vector value)
+  (boolean-subvector-fill! vector 0 (boolean-vector-length vector) value))
+
+(define-integrable (boolean->ascii boolean)
+  (if boolean (char->integer #\t) (char->integer #\f)))
\ No newline at end of file
index eb09e4b461e332e13b18123c6a1530297e4eee08..9d6ffbcaf0c2fd99573185bd8bdba1787debcfce 100644 (file)
@@ -1,8 +1,8 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/utlwin.scm,v 1.54 1989/08/14 09:23:08 cph Exp $
+;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/utlwin.scm,v 1.55 1990/11/02 03:24:51 cph Rel $
 ;;;
-;;;    Copyright (c) 1986, 1989 Massachusetts Institute of Technology
+;;;    Copyright (c) 1986, 1989, 1990 Massachusetts Institute of Technology
 ;;;
 ;;;    This material was developed by the Scheme project at the
 ;;;    Massachusetts Institute of Technology, Department of
 (define-class string-base vanilla-window
   (image representation truncate-lines?))
 
-(define-method string-base (:update-display! window screen x-start y-start
-                                            xl xu yl yu display-style)
-  window display-style                 ;ignore
-  (cond ((pair? representation)
-        (cond ((not (cdr representation))
-               ;; disable clipping.
-               (subscreen-clear! screen
-                                 x-start (fix:+ x-start xu)
-                                 y-start (fix:+ y-start yu))
-#|
-               (subscreen-clear! screen
-                                 (fix:+ x-start xl) (fix:+ x-start xu)
-                                 (fix:+ y-start yl) (fix:+ y-start yu))
-|#
-               )
-              ((fix:< yl yu)
-               (let ((start (cdr representation))
-                     (end (string-length (car representation)))
-                     (ayu (fix:+ y-start yu)))
-                 ;; disable clipping.
-                 (if (not (fix:zero? start))
-                     (subscreen-clear! screen
-                                       x-start (fix:+ x-start start)
-                                       y-start ayu))
-                 (screen-write-substring! screen
-                                          (fix:+ x-start start) y-start
-                                          (car representation)
-                                          start end)
-                 (if (fix:< end x-size)
-                     (subscreen-clear! screen
-                                       (fix:+ x-start end)
-                                       (fix:+ x-start x-size)
-                                       y-start
-                                       ayu))
-#|
-                 (if (not (fix:zero? start))
-                     (clip-window-region-1 xl xu start
-                       (lambda (xl xu)
-                         (subscreen-clear! screen
-                                           (fix:+ x-start xl)
-                                           (fix:+ x-start xu)
-                                           ayl
-                                           ayu))))
-                 (clip-window-region-1 (fix:- xl start)
-                                       (fix:- xu start)
-                                       (fix:- end start)
-                   (lambda (xl xu)
-                     (let ((xl* (fix:+ xl start)))
-                       (screen-write-substring! screen
-                                                (fix:+ x-start xl*) ayl
-                                                (car representation)
-                                                xl* (fix:+ xu start)))))
-                 (clip-window-region-1 (fix:- xl end)
-                                       (fix:- xu end)
-                                       (fix:- x-size end)
-                   (lambda (xl xu)
-                     (let ((x-start (fix:+ x-start end)))
-                       (subscreen-clear! screen
-                                         (fix:+ x-start xl) (fix:+ x-start xu)
-                                         ayl ayu))))
-|#
-                 ))))
-       (else
-        (screen-write-substrings! screen (fix:+ x-start xl) (fix:+ y-start yl)
-                                  representation xl xu yl yu)))
+(define-integrable (string-base:representation window)
+  (with-instance-variables string-base window () representation))
+
+(define (string-base:update-display! window screen x-start y-start
+                                    xl xu yl yu display-style)
+  display-style                                ;ignore
+  (let ((representation (string-base:representation window)))
+    (cond ((false? representation)
+          (screen-clear-rectangle screen
+                                  x-start (fix:+ x-start xu)
+                                  y-start (fix:+ y-start yu)
+                                  false))
+         ((string? representation)
+          (screen-output-substring screen x-start y-start
+                                   representation
+                                   0 (string-length representation) false))
+         (else
+          (clip (screen-x-size screen) (fix:+ x-start xl) xl xu
+            (lambda (x il iu)
+              (clip (screen-y-size screen) (fix:+ y-start yl) yl yu
+                (lambda (y jl ju)
+                  (let loop ((y y) (j jl))
+                    (if (fix:< j ju)
+                        (begin
+                          (screen-output-substring screen x y
+                                                   (vector-ref representation
+                                                               j)
+                                                   il iu false)
+                          (loop (fix:1+ y) (fix:1+ j))))))))))))
   true)
+
+(define (clip axu x bil biu receiver)
+  (let ((ail (fix:- bil x)))
+    (if (fix:< ail biu)
+       (let ((aiu (fix:+ ail axu)))
+         (cond ((fix:<= x 0)
+                (receiver 0 ail (if (fix:< aiu biu) aiu biu)))
+               ((fix:< x axu)
+                (receiver x bil (if (fix:< aiu biu) aiu biu))))))))
+
+(define-method string-base :update-display!
+  string-base:update-display!)
 \f
 (define (string-base:set-size-given-x! window x *truncate-lines?)
   (with-instance-variables string-base window (x *truncate-lines?)
 (define (string-base:coordinates->index window x y)
   (with-instance-variables string-base window (x y)
     (image-column->index image
-                        (let ((column-size (image-column-size image)))
-                          (if (and truncate-lines? (fix:= x (fix:-1+ x-size)))
-                              column-size
-                              (min (coordinates->column x y x-size)
-                                   column-size))))))
+                        (let ((column (coordinates->column x y x-size))
+                              (size (image-column-size image)))
+                          (if (fix:< column size)
+                              column
+                              size)))))
 \f
 (define (column->x-size column-size y-size truncate-lines?)
   ;; Assume Y-SIZE > 0.
   (if truncate-lines?
       column-size
       (let ((qr (integer-divide column-size y-size)))
-       (if (fix:zero? (integer-divide-remainder qr))
+       (if (fix:= (integer-divide-remainder qr) 0)
            (integer-divide-quotient qr)
            (fix:1+ (integer-divide-quotient qr))))))
 
 (define (column->y-size column-size x-size truncate-lines?)
   ;; Assume X-SIZE > 1.
-  (if (or truncate-lines? (fix:zero? column-size))
+  (if (or truncate-lines? (fix:< column-size x-size))
       1
       (let ((qr (integer-divide column-size (fix:-1+ x-size))))
-       (if (fix:zero? (integer-divide-remainder qr))
+       (if (fix:= (integer-divide-remainder qr) 0)
            (integer-divide-quotient qr)
            (fix:1+ (integer-divide-quotient qr))))))
 
           (cons -1+x-size 0))
          (else
           (let ((qr (integer-divide column -1+x-size)))
-            (if (and (fix:zero? (integer-divide-remainder qr))
+            (if (and (fix:= (integer-divide-remainder qr) 0)
                      (fix:= column column-size))
                 (cons -1+x-size
                       (fix:-1+ (integer-divide-quotient qr)))
           -1+x-size)
          (else
           (let ((r (remainder column -1+x-size)))
-            (if (and (fix:zero? r) (fix:= column column-size))
+            (if (and (fix:= r 0) (fix:= column column-size))
                 -1+x-size
                 r))))))
 
 (define (column->y column-size x-size truncate-lines? column)
-  (if truncate-lines?
+  (if (or truncate-lines? (fix:< column (fix:-1+ x-size)))
       0
-      (let ((-1+x-size (fix:-1+ x-size)))
-       (if (fix:< column -1+x-size)
-           0
-           (let ((qr (integer-divide column -1+x-size)))
-             (if (and (fix:zero? (integer-divide-remainder qr))
-                      (fix:= column column-size))
-                 (fix:-1+ (integer-divide-quotient qr))
-                 (integer-divide-quotient qr)))))))
+      (let ((qr (integer-divide column (fix:-1+ x-size))))
+       (if (and (fix:= (integer-divide-remainder qr) 0)
+                (fix:= column column-size))
+           (fix:-1+ (integer-divide-quotient qr))
+           (integer-divide-quotient qr)))))
 
 (define-integrable (coordinates->column x y x-size)
   (fix:+ x (fix:* y (fix:-1+ x-size))))
 \f
 (define (string-base:direct-output-insert-char! window x char)
   (with-instance-variables string-base window (x char)
-    (if (pair? representation)
-       (begin
-         (set-car! representation
-                   (string-append-char (car representation) char))
-         (if (and (not (cdr representation))
-                  (not (char=? char #\Space)))
-             (set-cdr! representation x)))
-       (string-set! (vector-ref representation (fix:-1+ y-size)) x char))))
+    (image-direct-output-insert-char! image char)
+    (cond ((false? representation)
+          (let ((s (string-allocate x-size)))
+            (string-fill! s #\space)
+            (string-set! s x char)
+            (set! representation s)))
+         ((string? representation)
+          (string-set! representation x char))
+         (else
+          (string-set! (vector-ref representation (fix:-1+ y-size))
+                       x
+                       char)))))
 
 (define (string-base:direct-output-insert-newline! window)
   (with-instance-variables string-base window ()
+    (set! image (make-null-image))
     (set! y-size 1)
-    (set! representation (cons "" false))))
+    (set! representation false)))
 
 (define (string-base:direct-output-insert-substring! window x string start end)
   (with-instance-variables string-base window (x string start end)
-    (if (pair? representation)
-       (begin
-         (set-car! representation
-                   (string-append-substring (car representation)
-                                            string start end))
-         (if (not (cdr representation))
-             (let ((index
-                    (substring-find-next-char-in-set string start end
-                                                     char-set:not-space)))
-               (if index
-                   (set-cdr! representation (fix:+ x index))))))
-       (substring-move-right! string start end
-                              (vector-ref representation (fix:-1+ y-size))
-                              x))))
+    (image-direct-output-insert-substring! image string start end)
+    (cond ((false? representation)
+          (let ((s (string-allocate x-size)))
+            (substring-fill! s 0 x #\space)
+            (substring-move-left! string start end s x)
+            (substring-fill! s (fix:+ x (fix:- end start)) x-size #\space)
+            (set! representation s)))
+         ((string? representation)
+          (substring-move-left! string start end representation x))
+         (else
+          (substring-move-left! string start end
+                                (vector-ref representation (fix:-1+ y-size))
+                                x)))))
 
 (define (string-base:refresh! window)
   (with-instance-variables string-base window ()
-    (define (one-liner string)
-      (let ((start 
-            (string-find-next-char-in-set string char-set:not-space)))
-       (if (not (and (pair? representation)
-                     (string=? (car representation) string)
-                     (eqv? (cdr representation) start)))
-           (begin
-             (set! representation (cons string start))
-             (setup-redisplay-flags! redisplay-flags)))))
-    (let* ((string (image-representation image))
-          (column-size (string-length string)))
-      (cond ((fix:< column-size x-size)
-            (one-liner string))
-           (truncate-lines?
-            (one-liner
-             (let ((s (string-allocate x-size))
-                   (x-max (fix:-1+ x-size)))
-               (substring-move-right! string 0 x-max s 0)
-               (string-set! s x-max #\$)
-               s)))
-           (else
-            (let ((rep (make-vector y-size '()))
-                  (x-max (fix:-1+ x-size)))
-              (let loop ((start 0) (y 0))
-                (let ((s (string-allocate x-size))
-                      (end (fix:+ start x-max)))
-                  (vector-set! rep y s)
-                  (if (fix:> column-size end)
-                      (begin
-                        (substring-move-right! string start end s 0)
-                        (string-set! s x-max #\\)
-                        (loop end (fix:1+ y)))
-                      (begin
-                        (substring-move-right! string start column-size s 0)
-                        (substring-fill! s
-                                         (fix:- column-size start)
-                                         x-size
-                                         #\space)))))
-              (set! representation rep)
-              (setup-redisplay-flags! redisplay-flags)))))))
+    (let ((string (image-representation image)))
+      (let ((column-size (string-length string)))
+       (cond ((fix:= column-size 0)
+              (set! representation false))
+             ((fix:< column-size x-size)
+              (let ((s (string-allocate x-size)))
+                (substring-move-left! string 0 column-size s 0)
+                (substring-fill! s column-size x-size #\space)
+                (set! representation s)))
+             (truncate-lines?
+              (let ((s (string-allocate x-size))
+                    (x-max (fix:-1+ x-size)))
+                (substring-move-left! string 0 x-max s 0)
+                (string-set! s x-max #\$)
+                (set! representation s)))
+             (else
+              (let ((rep (make-vector y-size '()))
+                    (x-max (fix:-1+ x-size)))
+                (let loop ((start 0) (y 0))
+                  (let ((s (string-allocate x-size))
+                        (end (fix:+ start x-max)))
+                    (vector-set! rep y s)
+                    (if (fix:> column-size end)
+                        (begin
+                          (substring-move-left! string start end s 0)
+                          (string-set! s x-max #\\)
+                          (loop end (fix:1+ y)))
+                        (begin
+                          (substring-move-left! string start column-size s 0)
+                          (substring-fill! s
+                                           (fix:- column-size start)
+                                           x-size
+                                           #\space)))))
+                (set! representation rep))))))
+    (setup-redisplay-flags! redisplay-flags)))
 \f
 ;;;; Blank Window
 
 (define-class blank-window vanilla-window
   ())
 
-(define-method blank-window (:update-display! window screen x-start y-start
-                                             xl xu yl yu display-style)
+(define (blank-window:update-display! window screen x-start y-start
+                                     xl xu yl yu display-style)
   window display-style                 ;ignore
-  (subscreen-clear! screen
-                   (fix:+ x-start xl) (fix:+ x-start xu)
-                   (fix:+ y-start yl) (fix:+ y-start yu))
+  (screen-clear-rectangle screen
+                         (fix:+ x-start xl) (fix:+ x-start xu)
+                         (fix:+ y-start yl) (fix:+ y-start yu)
+                         false)
   true)
 
+(define-method blank-window :update-display!
+  blank-window:update-display!)
+
 ;;;; Vertical Border Window
 
 (define-class vertical-border-window vanilla-window
 
 (define-method vertical-border-window (:initialize! window window*)
   (usual=> window :initialize! window*)
-  (set! x-size 1)
-  unspecific)
+  (set! x-size 1))
 
 (define-method vertical-border-window (:set-x-size! window x)
   window                               ;ignore
 
 (define-method vertical-border-window (:set-size! window x y)
   (if (not (fix:= x 1))
-      (error "x-size of a vertical border window must be 1" x))
+      (error "Can't change the x-size of a vertical border window" x))
   (set! x-size x)
   (set! y-size y)
   (setup-redisplay-flags! redisplay-flags))
 
-(define-method vertical-border-window
-              (:update-display! window screen x-start y-start
-                                xl xu yl yu display-style)
+(define (vertical-border-window:update-display! window screen x-start y-start
+                                               xl xu yl yu display-style)
   display-style                                ;ignore
   (if (fix:< xl xu)
-      (clip-window-region-1 yl yu y-size
+      (clip-window-region-1 yl yu (window-y-size window)
        (lambda (yl yu)
          (let ((xl (fix:+ x-start xl))
                (yu (fix:+ y-start yu)))
            (let loop ((y (fix:+ y-start yl)))
              (if (fix:< y yu)
                  (begin
-                   (screen-write-char! screen xl y #\|)
-                   (loop (fix:1+ y)))))))))
+                   (screen-output-char screen xl y #\| false)
+                   (loop (fix:+ y 1)))))))))
   true)
+
+(define-method vertical-border-window :update-display!
+  vertical-border-window:update-display!)
 \f
 ;;;; Cursor Window
 
   (usual=> window :initialize! window*)
   (set! x-size 1)
   (set! y-size 1)
-  (set! enabled? false)
-  unspecific)
+  (set! enabled? false))
 
 (define-method cursor-window (:set-x-size! window x)
   window                               ;ignore
   window                               ;ignore
   (error "Can't change the size of a cursor window" x y))
 
-(define-method cursor-window (:update-display! window screen x-start y-start
-                                              xl xu yl yu display-style)
+(define (cursor-window:update-display! window screen x-start y-start
+                                      xl xu yl yu display-style)
   display-style                                ;ignore
-  (if (and enabled? (fix:< xl xu) (fix:< yl yu))
-      (screen-write-cursor! screen x-start y-start))
+  (if (and (with-instance-variables cursor-window window () enabled?)
+          (fix:< xl xu)
+          (fix:< yl yu))
+      (screen-move-cursor screen x-start y-start))
   true)
 
+(define-method cursor-window :update-display!
+  cursor-window:update-display!)
+
 (define-method cursor-window (:enable! window)
   (set! enabled? true)
   (setup-redisplay-flags! redisplay-flags))
 
 (define-method cursor-window (:disable! window)
   (set! enabled? false)
-  (set-car! redisplay-flags false)
-  unspecific)
\ No newline at end of file
+  (set-car! redisplay-flags false))
\ No newline at end of file
index 27063cb83054d9a30b857fe100217bdd6ad2aeb4..256246c55a77f2a7adb0e70cccd49f0b3796665d 100644 (file)
@@ -1,6 +1,6 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/wincom.scm,v 1.98 1990/10/09 16:24:47 cph Exp $
+;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/wincom.scm,v 1.99 1990/11/02 03:24:57 cph Rel $
 ;;;
 ;;;    Copyright (c) 1987, 1989, 1990 Massachusetts Institute of Technology
 ;;;
@@ -96,7 +96,8 @@ negative args count from the bottom."
     (let ((window (current-window)))
       (if (not argument)
          (begin
-           (window-redraw! window false)
+           (window-scroll-y-absolute! window (window-y-center window))
+           (window-redraw! window)
            (update-selected-screen! true))
          (window-scroll-y-absolute!
           window
@@ -184,11 +185,9 @@ means scroll one screenful down."
                     (multi-scroll-window-argument window argument 1)))))
 \f
 (define (scroll-window window n #!optional limit)
-  (if (if (negative? n)
-         (= (window-start-index window)
-            (mark-index (buffer-start (window-buffer window))))
-         (= (window-end-index window)
-            (mark-index (buffer-end (window-buffer window)))))
+  (if (window-mark-visible?
+       window
+       ((if (negative? n) buffer-start buffer-end) (window-buffer window)))
       ((if (default-object? limit) editor-error limit))
       (window-scroll-y-relative! window n)))
 
index 67ff4e43daedd2ace40a70ebcb17851950db812b..9bb48f471e1b98bae8f5487f951d23f730c31693 100644 (file)
@@ -1,8 +1,8 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/window.scm,v 1.151 1990/10/06 21:10:32 cph Exp $
+;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/window.scm,v 1.152 1990/11/02 03:25:03 cph Rel $
 ;;;
-;;;    Copyright (c) 1986, 1989 Massachusetts Institute of Technology
+;;;    Copyright (c) 1986, 1989, 1990 Massachusetts Institute of Technology
 ;;;
 ;;;    This material was developed by the Scheme project at the
 ;;;    Massachusetts Institute of Technology, Department of
@@ -45,7 +45,7 @@
 ;;;; Window System
 
 (declare (usual-integrations))
-\f
+
 ;;;  Based on WINDOW-WIN, designed by RMS.
 ;;;  See WINOPS.TXT for more information.
 
 ;;; method invocation.  However, these instance variables are always
 ;;; set by a method defined on the window itself.
 
+;;; It is assumed in several places that the methods to set a window's
+;;; size are called with interrupts disabled.
+\f
 ;;;; Vanilla Window
 
 (define-class vanilla-window ()
   (superior x-size y-size redisplay-flags inferiors))
 
 (define (window-initialize! window window*)
-  (with-instance-variables vanilla-window window (window*)
-    (set! superior window*)
-    (set! redisplay-flags (=> superior :inferior-redisplay-flags window))
-    (set! inferiors '())
-    unspecific))
+  (%set-window-superior! window window*)
+  (set-window-inferiors! window '())
+  (%set-window-redisplay-flags! window
+                               (=> window* :inferior-redisplay-flags window)))
 
 (define (window-kill! window)
   (for-each-inferior-window window (lambda (window) (=> window :kill!))))
 (define-integrable (window-superior window)
   (with-instance-variables vanilla-window window () superior))
 
-(define (set-window-superior! window window*)
+(define-integrable (%set-window-superior! window window*)
   (with-instance-variables vanilla-window window (window*)
-    (set! superior window*)
-    (set! redisplay-flags (=> window* :inferior-redisplay-flags window))
-    (setup-redisplay-flags! redisplay-flags)
-    (for-each (lambda (inferior)
-               (set-inferior-redisplay-flags! inferior
-                                              (cons false redisplay-flags))
-               (=> (inferior-window inferior) :set-superior! window))
-             inferiors)))
-
-(define (window-root-window window)
-  (with-instance-variables vanilla-window window ()
-    (if superior (window-root-window superior) window)))
+    (set! superior window*)))
 
 (define-integrable (window-x-size window)
   (with-instance-variables vanilla-window window () x-size))
 
-(define (set-window-x-size! window x)
-  (with-instance-variables vanilla-window window (x)
-    (%set-window-x-size! window x)
-    (setup-redisplay-flags! redisplay-flags)))
-
 (define-integrable (%set-window-x-size! window x)
-  (with-instance-variables vanilla-window window (x)
-    (set! x-size x)
-    unspecific))
+  (with-instance-variables vanilla-window window (x) (set! x-size x)))
 
 (define-integrable (window-y-size window)
   (with-instance-variables vanilla-window window () y-size))
 
-(define (set-window-y-size! window y)
-  (with-instance-variables vanilla-window window (y)
-    (%set-window-y-size! window y)
-    (setup-redisplay-flags! redisplay-flags)))
-
 (define-integrable (%set-window-y-size! window y)
-  (with-instance-variables vanilla-window window (y)
-    (set! y-size y)
-    unspecific))
-\f
-(define (window-size window receiver)
-  (with-instance-variables vanilla-window window (receiver)
-    (receiver x-size y-size)))
-
-(define (set-window-size! window x y)
-  (with-instance-variables vanilla-window window (x y)
-    (set! x-size x)
-    (set! y-size y)
-    (setup-redisplay-flags! redisplay-flags)))
+  (with-instance-variables vanilla-window window (y) (set! y-size y)))
 
 (define-integrable (window-redisplay-flags window)
   (with-instance-variables vanilla-window window () redisplay-flags))
 
-(define-integrable (%window-needs-redisplay? window)
-  (with-instance-variables vanilla-window window () (car redisplay-flags)))
+(define-integrable (%set-window-redisplay-flags! window flags)
+  (with-instance-variables vanilla-window window (flags)
+    (set! redisplay-flags flags)))
 
 (define-integrable (window-inferiors window)
   (with-instance-variables vanilla-window window () inferiors))
 
+(define-integrable (set-window-inferiors! window inferiors*)
+  (with-instance-variables vanilla-window window (inferiors*)
+    (set! inferiors inferiors*)))
+
+(define (window-root-window window)
+  (if (window-superior window)
+      (window-root-window (window-superior window))
+      window))
+
+(define (set-window-superior! window window*)
+  (%set-window-superior! window window*)
+  (let ((flags (=> window* :inferior-redisplay-flags window)))
+    (%set-window-redisplay-flags! window flags)
+    (setup-redisplay-flags! flags)
+    (for-each-inferior window
+      (lambda (inferior)
+       (set-inferior-redisplay-flags! inferior (cons false flags))
+       (=> (inferior-window inferior) :set-superior! window)))))
+\f
+(define (window-size window receiver)
+  (receiver (window-x-size window) (window-y-size window)))
+
+(define (set-window-x-size! window x)
+  (%set-window-x-size! window x)
+  (window-needs-redisplay! window))
+
+(define (set-window-y-size! window y)
+  (%set-window-y-size! window y)
+  (window-needs-redisplay! window))
+
+(define (set-window-size! window x y)
+  (%set-window-x-size! window x)
+  (%set-window-y-size! window y)
+  (window-needs-redisplay! window))
+
+(define-integrable (window-needs-redisplay? window)
+  (car (window-redisplay-flags window)))
+
+(define-integrable (window-needs-redisplay! window)
+  (setup-redisplay-flags! (window-redisplay-flags window)))
+
 (define-integrable (window-inferior? window window*)
-  (with-instance-variables vanilla-window window (window*)
-    (find-inferior? inferiors window*)))
+  (find-inferior? (window-inferiors window) window*))
 
 (define-integrable (window-inferior window window*)
-  (with-instance-variables vanilla-window window (window*)
-    (find-inferior inferiors window*)))
+  (find-inferior (window-inferiors window) window*))
 
-(define (for-each-inferior window procedure)
-  (with-instance-variables vanilla-window window (procedure)
-    (let loop ((inferiors inferiors))
-      (if (not (null? inferiors))
-         (begin
-           (procedure (car inferiors))
-           (loop (cdr inferiors)))))))
+(define-integrable (for-each-inferior window procedure)
+  (let loop ((inferiors (window-inferiors window)))
+    (if (not (null? inferiors))
+       (begin
+         (procedure (car inferiors))
+         (loop (cdr inferiors))))))
 
-(define (for-each-inferior-window window procedure)
+(define-integrable (for-each-inferior-window window procedure)
   (for-each-inferior window
-    (lambda (inferior) (procedure (inferior-window inferior)))))
+    (lambda (inferior)
+      (procedure (inferior-window inferior)))))
 
 (define (make-inferior window class)
-  (with-instance-variables vanilla-window window (class)
-    (let ((window* (make-object class)))
-      (let ((inferior
-            (cons window*
-                  (vector false
+  (let ((window* (make-object class)))
+    (let ((inferior
+          (%make-inferior window*
+                          false
                           false
-                          (cons false redisplay-flags)))))
-       (set! inferiors (cons inferior inferiors))
-       (=> window* :initialize! window)
-       inferior))))
+                          (cons false (window-redisplay-flags window)))))
+      (set-window-inferiors! window (cons inferior (window-inferiors window)))
+      (=> window* :initialize! window)
+      inferior)))
 
 (define (add-inferior! window window*)
-  (with-instance-variables vanilla-window window (window*)
-    (set! inferiors
-         (cons (cons window*
-                     (vector false
-                             false
-                             (cons false redisplay-flags)))
-               inferiors))
-    (=> window* :set-superior! window)))
+  (let ((inferior
+        (%make-inferior window*
+                        false
+                        false
+                        (cons false (window-redisplay-flags window)))))
+    (set-window-inferiors! window (cons inferior (window-inferiors window)))
+    (=> window* :set-superior! window)
+    inferior))
 
 (define (delete-inferior! window window*)
-  (with-instance-variables vanilla-window window (window*)
-    (set! inferiors
-         (delq! (find-inferior inferiors window*)
-                inferiors))))
+  (set-window-inferiors! window
+                        (let ((inferiors (window-inferiors window)))
+                          (delq! (find-inferior inferiors window*)
+                                 inferiors))))
 
 (define (replace-inferior! window old new)
-  (with-instance-variables vanilla-window window (old new)
-    (set-inferior-window! (find-inferior inferiors old) new)
-    (=> new :set-superior! window)))
+  (set-inferior-window! (find-inferior (window-inferiors window) old) new)
+  (=> new :set-superior! window))
 \f
 ;;; Returns #T if the redisplay finished, #F if aborted.
 ;;; Notice that the :UPDATE-DISPLAY! operation is assumed to return
 ;;; the same value.  This is used to control the setting of the
 ;;; redisplay flags.
 
-(define (update-inferiors! window screen x-start y-start xl xu yl yu
-                          display-style)
-  (with-instance-variables vanilla-window window
-                          (screen x-start y-start xl xu yl yu display-style)
-    (let loop ((inferiors inferiors))
-      (if (null? inferiors)
-         true
-         (let ((window (inferior-window (car inferiors)))
-               (xi (inferior-x-start (car inferiors)))
-               (yi (inferior-y-start (car inferiors)))
-               (flags (inferior-redisplay-flags (car inferiors))))
-           (let ((continue
-                  (lambda ()
-                    (set-car! flags false)
-                    (loop (cdr inferiors)))))
-             (if (and (or display-style (car flags))
-                      xi yi)
-                 (and (or display-style (not (keyboard-active? 0)))
-                      (clip-window-region xl xu yl yu
-                                          xi (window-x-size window)
-                                          yi (window-y-size window)
-                        (lambda (xl xu yl yu)
-                          (=> window :update-display!
-                              screen (fix:+ x-start xi) (fix:+ y-start yi)
-                              xl xu yl yu display-style)))
-                      (continue))
-                 (continue))))))))
-
-(define (clip-window-region xl xu yl yu xi xs yi ys receiver)
-  (clip-window-region-1 (fix:- xl xi) (fix:- xu xi) xs
-    (lambda (xl xu)
-      (clip-window-region-1 (fix:- yl yi) (fix:- yu yi) ys
-       (lambda (yl yu)
-         (receiver xl xu yl yu))))))
+(define (window-update-display! window screen x-start y-start xl xu yl yu
+                               display-style)
+  (update-inferiors! (window-inferiors window) screen x-start y-start
+                    xl xu yl yu display-style
+    (lambda (window screen x-start y-start xl xu yl yu display-style)
+      (and (or display-style (not (keyboard-active? 0)))
+          (=> window :update-display! screen x-start y-start xl xu yl yu
+              display-style)))))
+
+(define (update-inferiors! inferiors screen x-start y-start xl xu yl yu
+                          display-style updater)
+  (let loop ((inferiors inferiors))
+    (if (null? inferiors)
+       true
+       (and (update-inferior! (car inferiors) screen x-start y-start
+                              xl xu yl yu display-style updater)
+            (loop (cdr inferiors))))))
+
+(define (update-inferior! inferior screen x-start y-start xl xu yl yu
+                         display-style updater)
+  (let ((window (inferior-window inferior))
+       (xi (inferior-x-start inferior))
+       (yi (inferior-y-start inferior))
+       (flags (inferior-redisplay-flags inferior)))
+    (and (or (not xi)
+            (not (or display-style (car flags)))
+            (clip-window-region-1 (fix:- xl xi)
+                                  (fix:- xu xi)
+                                  (window-x-size window)
+              (lambda (xl xu)
+                (clip-window-region-1 (fix:- yl yi)
+                                      (fix:- yu yi)
+                                      (window-y-size window)
+                  (lambda (yl yu)
+                    (updater window
+                             screen (fix:+ x-start xi) (fix:+ y-start yi)
+                             xl xu yl yu display-style))))))
+        (begin
+          (set-car! flags false)
+          true))))
 
 (define (clip-window-region-1 al au bs receiver)
-  (if (fix:positive? al)
-      (if (fix:> al bs)
-         true
-         (receiver al (if (fix:< bs au) bs au)))
-      (if (fix:positive? au)
-         (receiver 0 (if (fix:< bs au) bs au))
-         true)))
+  (if (fix:< 0 al)
+      (if (fix:< au bs)
+         (if (fix:< al au) (receiver al au) true)
+         (if (fix:< al bs) (receiver al bs) true))
+      (if (fix:< au bs)
+         (if (fix:< 0 au) (receiver 0 au) true)
+         (if (fix:< 0 bs) (receiver 0 bs) true))))
 
 (define (salvage-inferiors! window)
   (for-each-inferior-window window (lambda (window) (=> window :salvage!))))
 (define-method vanilla-window :add-inferior! add-inferior!)
 (define-method vanilla-window :delete-inferior! delete-inferior!)
 (define-method vanilla-window :replace-inferior! replace-inferior!)
-(define-method vanilla-window :update-display! update-inferiors!)
+(define-method vanilla-window :update-display! window-update-display!)
 (define-method vanilla-window :salvage! salvage-inferiors!)
 
 ;;;; Operations on Inferiors
 \f
 ;;;; Inferiors
 
+(define %inferior-tag
+  "inferior")
+
+(define-integrable (%make-inferior window x-start y-start redisplay-flags)
+  (vector %inferior-tag window x-start y-start redisplay-flags))
+
+(define-integrable (inferior-window inferior)
+  (vector-ref inferior 1))
+
+(define-integrable (set-inferior-window! inferior window)
+  (vector-set! inferior 1 window))
+
+(define-integrable (inferior-x-start inferior)
+  (vector-ref inferior 2))
+
+(define-integrable (%set-inferior-x-start! inferior x-start)
+  (vector-set! inferior 2 x-start))
+
+(define-integrable (inferior-y-start inferior)
+  (vector-ref inferior 3))
+
+(define-integrable (%set-inferior-y-start! inferior y-start)
+  (vector-set! inferior 3 y-start))
+
+(define-integrable (inferior-redisplay-flags inferior)
+  (vector-ref inferior 4))
+
+(define-integrable (set-inferior-redisplay-flags! inferior redisplay-flags)
+  (vector-set! inferior 4 redisplay-flags))
+
+(unparser/set-tagged-vector-method! %inferior-tag
+  (unparser/standard-method 'INFERIOR
+    (lambda (state inferior)
+      (unparse-object state (inferior-window inferior))
+      (unparse-string state " x,y=(")
+      (unparse-object state (inferior-x-start inferior))
+      (unparse-string state ",")
+      (unparse-object state (inferior-y-start inferior))
+      (unparse-string state ")")
+      (if (inferior-needs-redisplay? inferior)
+         (unparse-string state " needs-redisplay")))))
+
+(define (inferior-copy inferior)
+  (%make-inferior (inferior-window inferior)
+                 (inferior-x-start inferior)
+                 (inferior-y-start inferior)
+                 (inferior-redisplay-flags inferior)))
+\f
+(define (inferior-start inferior receiver)
+  (receiver (inferior-x-start inferior)
+           (inferior-y-start inferior)))
+
+(define (%set-inferior-start! inferior x-start y-start)
+  (%set-inferior-x-start! inferior x-start)
+  (%set-inferior-y-start! inferior y-start))
+
+(define (set-inferior-x-start! inferior x-start)
+  (%set-inferior-x-start! inferior x-start)
+  (inferior-needs-redisplay! inferior))
+
+(define (set-inferior-y-start! inferior y-start)
+  (%set-inferior-y-start! inferior y-start)
+  (inferior-needs-redisplay! inferior))
+
+(define (set-inferior-start! inferior x-start y-start)
+  (%set-inferior-start! inferior x-start y-start)
+  (inferior-needs-redisplay! inferior))
+
+(define-integrable (%inferior-x-end inferior)
+  (fix:+ (inferior-x-start inferior) (inferior-x-size inferior)))
+
+(define-integrable (%inferior-y-end inferior)
+  (fix:+ (inferior-y-start inferior) (inferior-y-size inferior)))
+
+(define (inferior-x-end inferior)
+  (and (inferior-x-start inferior)
+       (%inferior-x-end inferior)))
+
+(define (inferior-y-end inferior)
+  (and (inferior-y-start inferior)
+       (%inferior-y-end inferior)))
+
+(define (set-inferior-x-end! inferior x-end)
+  (set-inferior-x-start! inferior (fix:- x-end (inferior-x-size inferior))))
+
+(define (set-inferior-y-end! inferior y-end)
+  (set-inferior-y-start! inferior (fix:- y-end (inferior-y-size inferior))))
+
 (define (inferior-position inferior)
   (and (inferior-x-start inferior)
-       (inferior-y-start inferior)
        (cons (inferior-x-start inferior)
             (inferior-y-start inferior))))
 
       (set-inferior-start! inferior false false)
       (set-inferior-start! inferior (car position) (cdr position))))
 
+(define-integrable (inferior-needs-redisplay? inferior)
+  (car (inferior-redisplay-flags inferior)))
+
 (define (inferior-needs-redisplay! inferior)
-  (if (and (inferior-x-start inferior)
-          (inferior-y-start inferior))
+  (if (and (inferior-x-start inferior) (inferior-y-start inferior))
       (setup-redisplay-flags! (inferior-redisplay-flags inferior))
-      (set-car! (inferior-redisplay-flags inferior) false))
-  unspecific)
+      (set-car! (inferior-redisplay-flags inferior) false)))
 
 (define (setup-redisplay-flags! flags)
-  (if (not (or (null? flags) (car flags)))
-      (begin
-       (set-car! flags true)
-       (setup-redisplay-flags! (cdr flags)))))
-
+  (let loop ((flags flags))
+    (if (not (or (null? flags) (car flags)))
+       (begin
+         (set-car! flags true)
+         (loop (cdr flags))))))
+\f
 (define-integrable (inferior-x-size inferior)
   (window-x-size (inferior-window inferior)))
 
 (define-integrable (set-inferior-size! inferior x y)
   (=> (inferior-window inferior) :set-size! x y))
 
+(define (find-inferior? inferiors window)
+  (let loop ((inferiors inferiors))
+    (and (not (null? inferiors))
+        (if (eq? window (inferior-window (car inferiors)))
+            (car inferiors)
+            (loop (cdr inferiors))))))
+
+(define (find-inferior inferiors window)
+  (let ((inferior (find-inferior? inferiors window)))
+    (if (not inferior)
+       (error "window not in inferiors" window))
+    inferior))
+
 (define (inferior-containing-coordinates window x y stop-search?)
   (let search ((window window) (x x) (y y))
     (if (stop-search? window)
                  (if (and x-start y-start)
                      (let ((x (fix:- x x-start))
                            (y (fix:- y y-start)))
-                       (if (and (not (fix:negative? x))
+                       (if (and (fix:<= 0 x)
                                 (fix:< x (inferior-x-size inferior))
-                                (not (fix:negative? y))
+                                (fix:<= 0 y)
                                 (fix:< y (inferior-y-size inferior)))
                            (search (inferior-window inferior) x y)
                            (loop (cdr inferiors))))
-                     (loop (cdr inferiors))))))))))
-\f
-(define-integrable (find-inferior? inferiors window)
-  (assq window inferiors))
-
-(define-integrable (find-inferior inferiors window)
-  (or (find-inferior? inferiors window)
-      (error "Window is not an inferior" window)))
-
-(define-integrable inferior-window car)
-(define-integrable set-inferior-window! set-car!)
-
-(define-integrable (inferior-x-start inferior)
-  (vector-ref (cdr inferior) 0))
-
-(define-integrable (%set-inferior-x-start! inferior x-start)
-  (vector-set! (cdr inferior) 0 x-start))
-
-(define (set-inferior-x-start! inferior x-start)
-  (%set-inferior-x-start! inferior x-start)
-  (inferior-needs-redisplay! inferior))
-
-(define (inferior-x-end inferior)
-  (let ((x-start (inferior-x-start inferior)))
-    (and x-start
-        (fix:+ x-start (inferior-x-size inferior)))))
-
-(define (set-inferior-x-end! inferior x-end)
-  (set-inferior-x-start! inferior (fix:- x-end (inferior-x-size inferior))))
-
-(define-integrable (inferior-y-start inferior)
-  (vector-ref (cdr inferior) 1))
-
-(define-integrable (%set-inferior-y-start! inferior y-start)
-  (vector-set! (cdr inferior) 1 y-start))
-
-(define (set-inferior-y-start! inferior y-start)
-  (%set-inferior-y-start! inferior y-start)
-  (inferior-needs-redisplay! inferior))
-
-(define (inferior-y-end inferior)
-  (let ((y-start (inferior-y-start inferior)))
-    (and y-start
-        (fix:+ y-start (inferior-y-size inferior)))))
-
-(define (set-inferior-y-end! inferior y-end)
-  (set-inferior-y-start! inferior (fix:- y-end (inferior-y-size inferior))))
-
-(define (inferior-start inferior receiver)
-  (receiver (inferior-x-start inferior)
-           (inferior-y-start inferior)))
-
-(define (%set-inferior-start! inferior x-start y-start)
-  (%set-inferior-x-start! inferior x-start)
-  (%set-inferior-y-start! inferior y-start))
-
-(define (set-inferior-start! inferior x-start y-start)
-  (%set-inferior-start! inferior x-start y-start)
-  (inferior-needs-redisplay! inferior))
-
-(define-integrable (inferior-redisplay-flags inferior)
-  (vector-ref (cdr inferior) 2))
-
-(define-integrable (set-inferior-redisplay-flags! inferior flags)
-  (vector-set! (cdr inferior) 2 flags))
\ No newline at end of file
+                     (loop (cdr inferiors))))))))))
\ No newline at end of file
index 3040ebdea6da44e1d2c15f0ba5c746637fa265f1..e46443cc170a4feb8794e15837ff0bd1c928ab55 100644 (file)
@@ -1,6 +1,8 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    Copyright (c) 1989 Massachusetts Institute of Technology
+;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/winren.scm,v 1.3 1990/11/02 03:25:09 cph Rel $
+;;;
+;;;    Copyright (c) 1989, 1990 Massachusetts Institute of Technology
 ;;;
 ;;;    This material was developed by the Scheme project at the
 ;;;    Massachusetts Institute of Technology, Department of
 ;;;; Window System Rename Exports
 
 (declare (usual-integrations))
-\f
+
 ;; buffrm.scm
 (define window?)
 (define window-x-size)
 (define window-y-size)
+(define window-needs-redisplay?)
 (define %set-window-buffer!)
\ No newline at end of file
index e31ee043d37f36d337ffa77eaa98435668c2ab37..fb5bec4cf3af458e4f9dc1d9f6685db096dc30db 100644 (file)
@@ -1,6 +1,6 @@
 ;;; -*-Scheme-*-
 ;;;
-;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/xterm.scm,v 1.12 1990/10/09 16:24:53 cph Exp $
+;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/edwin/xterm.scm,v 1.13 1990/11/02 03:25:13 cph Rel $
 ;;;
 ;;;    Copyright (c) 1989, 1990 Massachusetts Institute of Technology
 ;;;
@@ -55,7 +55,6 @@
   (x-display-process-events 2)
   (x-display-sync 2)
   (x-window-beep 1)
-  (x-window-clear 1)
   (x-window-display 1)
   (x-window-set-event-mask 2)
   (x-window-set-icon-name 2)
@@ -67,8 +66,8 @@
   (xterm-open-window 3)
   (xterm-restore-contents 6)
   (xterm-save-contents 5)
-  (xterm-scroll-lines-down 7)
-  (xterm-scroll-lines-up 7)
+  (xterm-scroll-lines-down 6)
+  (xterm-scroll-lines-up 6)
   (xterm-set-size 3)
   (xterm-write-char! 5)
   (xterm-write-cursor! 3)
           (make-screen (make-xterm-screen-state xterm
                                                 (x-window-display xterm))
                        xterm-screen/beep
+                       xterm-screen/clear-line!
+                       xterm-screen/clear-rectangle!
+                       xterm-screen/clear-screen!
                        xterm-screen/discard!
                        xterm-screen/enter!
                        xterm-screen/exit!
-                       xterm-screen/finish-update!
                        xterm-screen/flush!
-                       xterm-screen/inverse-video!
                        xterm-screen/modeline-event!
-                       xterm-screen/normal-video!
+                       xterm-screen/preempt-update?
                        xterm-screen/scroll-lines-down!
                        xterm-screen/scroll-lines-up!
-                       xterm-screen/start-update!
-                       xterm-screen/subscreen-clear!
-                       xterm-screen/wipe!
+                       xterm-screen/wrap-update!
                        xterm-screen/write-char!
                        xterm-screen/write-cursor!
                        xterm-screen/write-substring!
 (define-integrable (screen-display screen)
   (xterm-screen-state/display (screen-state screen)))
 
-(define-integrable (screen-highlight screen)
-  (if (screen-highlight? screen) 1 0))
-
 (define-integrable (screen-redisplay-flag screen)
   (xterm-screen-state/redisplay-flag (screen-state screen)))
 
             (car screens)
             (loop (cdr screens))))))
 \f
-(define (xterm-screen/start-update! screen)
-  (xterm-enable-cursor (screen-xterm screen) false))
-
-(define (xterm-screen/finish-update! screen)
-  (if (screen-selected? screen)
-      (let ((xterm (screen-xterm screen)))
-       (xterm-enable-cursor xterm true)
-       (xterm-draw-cursor xterm)))
-  (if (screen-redisplay-flag screen)
-      (begin
-       (update-xterm-screen-names! screen)
-       (set-screen-redisplay-flag! screen false)))
-  (xterm-screen/flush! screen))
+(define (xterm-screen/wrap-update! screen thunk)
+  (dynamic-wind
+   (lambda ()
+     (xterm-enable-cursor (screen-xterm screen) false))
+   thunk
+   (lambda ()
+     (if (screen-selected? screen)
+        (let ((xterm (screen-xterm screen)))
+          (xterm-enable-cursor xterm true)
+          (xterm-draw-cursor xterm)))
+     (if (screen-redisplay-flag screen)
+        (begin
+          (update-xterm-screen-names! screen)
+          (set-screen-redisplay-flag! screen false)))
+     (xterm-screen/flush! screen))))
 
 (define (xterm-screen/discard! screen)
   (set! screen-list (delq! screen screen-list))
     (xterm-erase-cursor xterm))
   (xterm-screen/flush! screen))
 
-(define (xterm-screen/inverse-video! screen)
+(define (xterm-screen/preempt-update? screen y)
   screen                               ; ignored
-  unspecific)
-
-(define (xterm-screen/normal-video! screen)
-  screen                               ; ignored
-  unspecific)
+  (fix:= (fix:remainder y 8) 0))
+  
 
 (define (xterm-screen/scroll-lines-down! screen xl xu yl yu amount)
-  (xterm-scroll-lines-down (screen-xterm screen) xl xu yl yu amount 0)
-  true)
+  (xterm-scroll-lines-down (screen-xterm screen) xl xu yl yu amount)
+  'UNCHANGED)
 
 (define (xterm-screen/scroll-lines-up! screen xl xu yl yu amount)
-  (xterm-scroll-lines-up (screen-xterm screen) xl xu yl yu amount 0)
-  true)
+  (xterm-scroll-lines-up (screen-xterm screen) xl xu yl yu amount)
+  'UNCHANGED)
 
 (define (xterm-screen/beep screen)
   (x-window-beep (screen-xterm screen))
 (define-integrable (xterm-screen/flush! screen)
   (x-display-flush (screen-display screen)))
 
-(define (xterm-screen/write-char! screen x y char)
-  (xterm-write-char! (screen-xterm screen) x y char (screen-highlight screen)))
+(define (xterm-screen/write-char! screen x y char highlight)
+  (xterm-write-char! (screen-xterm screen) x y char (if highlight 1 0)))
 
 (define (xterm-screen/write-cursor! screen x y)
   (xterm-write-cursor! (screen-xterm screen) x y))
 
-(define (xterm-screen/write-substring! screen x y string start end)
+(define (xterm-screen/write-substring! screen x y string start end highlight)
   (xterm-write-substring! (screen-xterm screen) x y string start end
-                         (screen-highlight screen)))
+                         (if highlight 1 0)))
+
+(define (xterm-screen/clear-line! screen x y first-unused-x)
+  (xterm-clear-rectangle! (screen-xterm screen)
+                         x first-unused-x y (fix:1+ y) 0))
 
-(define (xterm-screen/subscreen-clear! screen xl xu yl yu)
-  (xterm-clear-rectangle! (screen-xterm screen) xl xu yl yu
-                         (screen-highlight screen)))
+(define (xterm-screen/clear-rectangle! screen xl xu yl yu highlight)
+  (xterm-clear-rectangle! (screen-xterm screen)
+                         xl xu yl yu (if highlight 1 0)))
 
-(define (xterm-screen/wipe! screen)
-  (x-window-clear (screen-xterm screen)))
+(define (xterm-screen/clear-screen! screen)
+  (xterm-clear-rectangle! (screen-xterm screen)
+                         0 (screen-x-size screen) 0 (screen-y-size screen) 0))
 \f
 ;;;; Input Port
 
   (set! pending-interrupt? false)
   (^G-signal))
 
-(define (with-editor-interrupts-from-x thunk)
+(define (with-editor-interrupts-from-x receiver)
   (fluid-let ((signal-interrupts? true)
              (pending-interrupt? false))
-    (thunk)))
+    (receiver (lambda (thunk) (thunk)))))
 
 (define (with-x-interrupts-enabled thunk)
   (bind-signal-interrupts? true thunk))
       (if (not (and (= x-size (screen-x-size screen))
                    (= y-size (screen-y-size screen))))
          (begin
-           (set-screen-x-size! screen x-size)
-           (set-screen-y-size! screen y-size)
-           (send (screen-root-window screen) ':set-size! x-size y-size)
+           (set-screen-size! screen x-size y-size)
            (update-screen! screen true))))))
 
 (define-event-handler event-type:button-down
 (define x-display-data)
 
 (define (get-x-display)
+  ;; X-OPEN-DISPLAY hangs, uninterruptibly, when the X server is
+  ;; running the login loop of xdm.  Can this be fixed?
   (or x-display-data
       (let ((display (x-open-display false)))
        (set! x-display-data display)