added "more" command
[unix-history] / usr / src / usr.bin / window / wwscroll.c
index b8b3a6f..c2ce506 100644 (file)
@@ -1,75 +1,84 @@
 #ifndef lint
 #ifndef lint
-static char *sccsid = "@(#)wwscroll.c  3.4 83/08/18";
+static char sccsid[] = "@(#)wwscroll.c 3.13 %G%";
 #endif
 
 #endif
 
+/*
+ * Copyright (c) 1983 Regents of the University of California,
+ * All rights reserved.  Redistribution permitted subject to
+ * the terms of the Berkeley Software License Agreement.
+ */
+
 #include "ww.h"
 #include "tt.h"
 
 wwscroll(w, n)
 register struct ww *w;
 #include "ww.h"
 #include "tt.h"
 
 wwscroll(w, n)
 register struct ww *w;
-register n;
+int n;
 {
 {
-       int dir;
-       register scroll;
+       register dir;
+       register top;
 
        if (n == 0)
                return;
        dir = n < 0 ? -1 : 1;
 
        if (n == 0)
                return;
        dir = n < 0 ? -1 : 1;
-       scroll = w->ww_scroll + n;
-       if (scroll < 0)
-               scroll = 0;
-       else if (scroll > w->ww_nline - w->ww_w.nr)
-               scroll = w->ww_nline - w->ww_w.nr;
-       n = abs(scroll - w->ww_scroll);
-       if (n < w->ww_w.nr) {
+       top = w->ww_b.t - n;
+       if (top > w->ww_w.t)
+               top = w->ww_w.t;
+       else if (top + w->ww_b.nr < w->ww_w.b)
+               top = w->ww_w.b - w->ww_b.nr;
+       n = abs(top - w->ww_b.t);
+       if (n < w->ww_i.nr) {
                while (--n >= 0) {
                while (--n >= 0) {
-                       wwscroll1(w, 0, w->ww_w.nr - 1, dir, 0);
-                       w->ww_scroll += dir;
+                       (void) wwscroll1(w, w->ww_i.t, w->ww_i.b, dir, 0);
+                       w->ww_buf += dir;
+                       w->ww_b.t -= dir;
+                       w->ww_b.b -= dir;
                }
        } else {
                }
        } else {
-               w->ww_scroll = scroll;
+               w->ww_buf -= top - w->ww_b.t;
+               w->ww_b.t = top;
+               w->ww_b.b = top + w->ww_b.nr;
                wwredrawwin(w);
        }
 }
 
 /*
                wwredrawwin(w);
        }
 }
 
 /*
- * Scroll one line, between 'srow' and 'erow', in direction 'dir'.
+ * Scroll one line, between 'row1' and 'row2', in direction 'dir'.
  * Don't adjust ww_scroll.
  * And don't redraw 'leaveit' lines.
  */
  * Don't adjust ww_scroll.
  * And don't redraw 'leaveit' lines.
  */
-wwscroll1(w, srow, erow, dir, leaveit)
+wwscroll1(w, row1, row2, dir, leaveit)
 register struct ww *w;
 register struct ww *w;
-int srow, erow, dir;
+int row1, row2, dir;
 int leaveit;
 {
        register i;
 int leaveit;
 {
        register i;
-       int srow1, erow1;
+       int row1x, row2x;
        int nvis;
        int nvismax;
        int deleted = 0;
 
        /*
         * See how many lines on the screen are affected.
        int nvis;
        int nvismax;
        int deleted = 0;
 
        /*
         * See how many lines on the screen are affected.
-        * And calculate srow, erow, and left at the same time.
+        * And calculate row1x, row2x, and left at the same time.
         */
         */
-       for (i = srow; i <= erow && w->ww_nvis[i] == 0; i++)
+       for (i = row1; i < row2 && w->ww_nvis[i] == 0; i++)
                ;
                ;
-       if ((srow1 = i) > erow) {
-               /* can't do any fancy stuff */
-               erow1 = srow1 - 1;
+       if (i >= row2)                  /* can't do any fancy stuff */
                goto out;
                goto out;
-       }
-       for (i = erow; i >= srow && w->ww_nvis[i] == 0; i--)
+       row1x = i;
+       for (i = row2 - 1; i >= row1 && w->ww_nvis[i] == 0; i--)
                ;
                ;
-       if ((erow1 = i) == srow1)
+       if (i <= row1x)
                goto out;               /* just one line is easy */
                goto out;               /* just one line is easy */
+       row2x = i + 1;
 
        /*
         * See how much of this window is visible.
         */
 
        /*
         * See how much of this window is visible.
         */
-       nvismax = wwncol * (erow1 - srow1 + 1);
+       nvismax = wwncol * (row2x - row1x);
        nvis = 0;
        nvis = 0;
-       for (i = srow1; i <= erow1; i++)
+       for (i = row1x; i < row2x; i++)
                nvis += w->ww_nvis[i];
 
        /*
                nvis += w->ww_nvis[i];
 
        /*
@@ -80,43 +89,45 @@ int leaveit;
                register union ww_char *tmp;
                register union ww_char **cpp, **cqq;
 
                register union ww_char *tmp;
                register union ww_char **cpp, **cqq;
 
+               /*
+                * Don't worry about retain when scrolling down.
+                * But do worry when scrolling up.  For hp2621.
+                */
                if (dir > 0) {
                if (dir > 0) {
-                       (*tt.tt_move)(srow1 + w->ww_w.t, 0);
+                       (*tt.tt_move)(row1x, 0);
                        (*tt.tt_delline)();
                        (*tt.tt_delline)();
-                       if (erow1 + w->ww_w.t != wwnrow - 1) {
-                               (*tt.tt_move)(erow1 + w->ww_w.t, 0);
+                       if (row2x < wwnrow) {
+                               (*tt.tt_move)(row2x - 1, 0);
                                (*tt.tt_insline)();
                        }
                        /*
                         * Fix up the old screen.
                         */
                                (*tt.tt_insline)();
                        }
                        /*
                         * Fix up the old screen.
                         */
-                       cpp = &wwos[srow1 + w->ww_w.t];
+                       cpp = &wwos[row1x];
                        cqq = cpp + 1;
                        tmp = *cpp;
                        cqq = cpp + 1;
                        tmp = *cpp;
-                       for (i = erow1 - srow1; --i >= 0;)
+                       for (i = row2x - row1x; --i > 0;)
                                *cpp++ = *cqq++;
                        *cpp = tmp;
                                *cpp++ = *cqq++;
                        *cpp = tmp;
-                       for (i = wwncol; --i >= 0;)
-                               tmp++->c_w = ' ';
                } else {
                } else {
-                       if (erow1 + w->ww_w.t != wwnrow - 1) {
-                               (*tt.tt_move)(erow1 + w->ww_w.t, 0);
+                       if (tt.tt_retain || row2x != wwnrow) {
+                               (*tt.tt_move)(row2x - 1, 0);
                                (*tt.tt_delline)();
                        }
                                (*tt.tt_delline)();
                        }
-                       (*tt.tt_move)(srow1 + w->ww_w.t, 0);
+                       (*tt.tt_move)(row1x, 0);
                        (*tt.tt_insline)();
                        /*
                         * Fix up the old screen.
                         */
                        (*tt.tt_insline)();
                        /*
                         * Fix up the old screen.
                         */
-                       cqq = &wwos[erow1 + w->ww_w.t];
-                       cpp = cqq + 1;
+                       cpp = &wwos[row2x];
+                       cqq = cpp - 1;
                        tmp = *cqq;
                        tmp = *cqq;
-                       for (i = erow1 - srow1; --i >= 0;)
+                       for (i = row2x - row1x; --i > 0;)
                                *--cpp = *--cqq;
                        *cqq = tmp;
                                *--cpp = *--cqq;
                        *cqq = tmp;
-                       for (i = wwncol; --i >= 0;)
-                               tmp++->c_w = ' ';
                }
                }
+               for (i = wwncol; --i >= 0;)
+                       tmp++->c_w = ' ';
                deleted++;
        }
 
                deleted++;
        }
 
@@ -132,58 +143,66 @@ int leaveit;
                                register union ww_char *tmp;
                                register union ww_char **cpp, **cqq;
 
                                register union ww_char *tmp;
                                register union ww_char **cpp, **cqq;
 
-                               cpp = &wwns[srow1 + w->ww_w.t];
+                               cpp = &wwns[row1x];
                                cqq = cpp + 1;
                                tmp = *cpp;
                                cqq = cpp + 1;
                                tmp = *cpp;
-                               for (i = erow1 - srow1; --i >= 0;)
+                               for (i = row2x - row1x; --i > 0;)
                                        *cpp++ = *cqq++;
                                *cpp = tmp;
                        }
                                        *cpp++ = *cqq++;
                                *cpp = tmp;
                        }
-                       {
+                       if (deleted) {
                                register char *p, *q;
 
                                register char *p, *q;
 
-                               p = &wwtouched[srow1 + w->ww_w.t];
+                               p = &wwtouched[row1x];
                                q = p + 1;
                                q = p + 1;
-                               for (i = erow1 - srow1; --i >= 0;)
+                               for (i = row2x - row1x; --i > 0;)
                                        *p++ = *q++;
                                        *p++ = *q++;
-                               *p = 1;
+                               *p |= WWU_TOUCHED;
+                       } else {
+                               register char *p;
+
+                               p = &wwtouched[row1x];
+                               for (i = row2x - row1x; --i >= 0;)
+                                       *p++ |= WWU_MAJOR|WWU_TOUCHED;
                        }
                        }
-                       wwredrawwin1(w, srow, srow1 - 1, w->ww_scroll + dir);
-                       wwredrawwin1(w, erow1, erow - leaveit,
-                               w->ww_scroll + dir);
+                       wwredrawwin1(w, row1, row1x, dir);
+                       wwredrawwin1(w, row2x - 1, row2 - leaveit, dir);
                } else {
                        {
                                register union ww_char *tmp;
                                register union ww_char **cpp, **cqq;
 
                } else {
                        {
                                register union ww_char *tmp;
                                register union ww_char **cpp, **cqq;
 
-                               cqq = &wwns[erow1 + w->ww_w.t];
-                               cpp = cqq + 1;
+                               cpp = &wwns[row2x];
+                               cqq = cpp - 1;
                                tmp = *cqq;
                                tmp = *cqq;
-                               for (i = erow1 - srow1; --i >= 0;)
+                               for (i = row2x - row1x; --i > 0;)
                                        *--cpp = *--cqq;
                                *cqq = tmp;
                        }
                                        *--cpp = *--cqq;
                                *cqq = tmp;
                        }
-                       {
+                       if (deleted) {
                                register char *p, *q;
 
                                register char *p, *q;
 
-                               q = &wwtouched[erow1 + w->ww_w.t];
-                               p = q + 1;
-                               for (i = erow1 - srow1; --i >= 0;)
+                               p = &wwtouched[row2x];
+                               q = p - 1;
+                               for (i = row2x - row1x; --i > 0;)
                                        *--p = *--q;
                                        *--p = *--q;
-                               *q = 1;
+                               *q |= WWU_MAJOR|WWU_TOUCHED;
+                       } else {
+                               register char *p;
+
+                               p = &wwtouched[row1x];
+                               for (i = row2x - row1x; --i >= 0;)
+                                       *p++ |= WWU_TOUCHED;
                        }
                        }
-                       wwredrawwin1(w, srow + leaveit, srow1,
-                               w->ww_scroll + dir);
-                       wwredrawwin1(w, erow1 + 1, erow, w->ww_scroll + dir);
+                       wwredrawwin1(w, row1 + leaveit, row1x + 1, dir);
+                       wwredrawwin1(w, row2x, row2, dir);
                }
        } else {
 out:
                if (dir > 0)
                }
        } else {
 out:
                if (dir > 0)
-                       wwredrawwin1(w, srow, erow - leaveit,
-                               w->ww_scroll + dir);
+                       wwredrawwin1(w, row1, row2 - leaveit, dir);
                else
                else
-                       wwredrawwin1(w, srow + leaveit, erow,
-                               w->ww_scroll + dir);
+                       wwredrawwin1(w, row1 + leaveit, row2, dir);
        }
        return deleted;
 }
        }
        return deleted;
 }