removed extra tt_col += n in gen_write
[unix-history] / usr / src / usr.bin / window / wwscroll.c
index d4b12c8..c2ce506 100644 (file)
@@ -1,47 +1,84 @@
 #ifndef lint
 #ifndef lint
-static char *sccsid = "@(#)wwscroll.c  3.2 83/08/15";
+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"
 
 #include "ww.h"
 #include "tt.h"
 
+wwscroll(w, n)
+register struct ww *w;
+int n;
+{
+       register dir;
+       register top;
+
+       if (n == 0)
+               return;
+       dir = n < 0 ? -1 : 1;
+       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) {
+                       (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 {
+               w->ww_buf -= top - w->ww_b.t;
+               w->ww_b.t = top;
+               w->ww_b.b = top + w->ww_b.nr;
+               wwredrawwin(w);
+       }
+}
+
 /*
 /*
- * Scroll down one line, starting at 'line'.
+ * Scroll one line, between 'row1' and 'row2', in direction 'dir'.
  * Don't adjust ww_scroll.
  * 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;
-char leaveit;
+int row1, row2, dir;
+int leaveit;
 {
        register i;
 {
        register i;
-       int startrow, endrow;
+       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 ((startrow = i) > erow) {
-               /* can't do any fancy stuff */
-               endrow = startrow - 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 ((endrow = i) == startrow)
+       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 * (endrow - startrow + 1);
+       nvismax = wwncol * (row2x - row1x);
        nvis = 0;
        nvis = 0;
-       for (i = startrow; i <= endrow; i++)
+       for (i = row1x; i < row2x; i++)
                nvis += w->ww_nvis[i];
 
        /*
                nvis += w->ww_nvis[i];
 
        /*
@@ -52,43 +89,45 @@ char 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)(startrow + w->ww_w.t, 0);
+                       (*tt.tt_move)(row1x, 0);
                        (*tt.tt_delline)();
                        (*tt.tt_delline)();
-                       if (endrow + w->ww_w.t != wwnrow - 1) {
-                               (*tt.tt_move)(endrow + 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[startrow + w->ww_w.t];
+                       cpp = &wwos[row1x];
                        cqq = cpp + 1;
                        tmp = *cpp;
                        cqq = cpp + 1;
                        tmp = *cpp;
-                       for (i = endrow - startrow; --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 (endrow + w->ww_w.t != wwnrow - 1) {
-                               (*tt.tt_move)(endrow + 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)(startrow + 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[endrow + w->ww_w.t];
-                       cpp = cqq + 1;
+                       cpp = &wwos[row2x];
+                       cqq = cpp - 1;
                        tmp = *cqq;
                        tmp = *cqq;
-                       for (i = endrow - startrow; --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++;
        }
 
@@ -99,38 +138,71 @@ char leaveit;
                /*
                 * Can shift whole lines.
                 */
                /*
                 * Can shift whole lines.
                 */
-               register union ww_char *tmp;
-               register union ww_char **cpp, **cqq;
-
                if (dir > 0) {
                if (dir > 0) {
-                       cpp = &wwns[startrow + w->ww_w.t];
-                       cqq = cpp + 1;
-                       tmp = *cpp;
-                       for (i = endrow - startrow; --i >= 0;)
-                               *cpp++ = *cqq++;
-                       *cpp = tmp;
-                       wwredrawwin1(w, srow, startrow - 1, w->ww_scroll + dir);
-                       wwredrawwin1(w, endrow + 1, erow - leaveit,
-                               w->ww_scroll + dir);
+                       {
+                               register union ww_char *tmp;
+                               register union ww_char **cpp, **cqq;
+
+                               cpp = &wwns[row1x];
+                               cqq = cpp + 1;
+                               tmp = *cpp;
+                               for (i = row2x - row1x; --i > 0;)
+                                       *cpp++ = *cqq++;
+                               *cpp = tmp;
+                       }
+                       if (deleted) {
+                               register char *p, *q;
+
+                               p = &wwtouched[row1x];
+                               q = p + 1;
+                               for (i = row2x - row1x; --i > 0;)
+                                       *p++ = *q++;
+                               *p |= WWU_TOUCHED;
+                       } else {
+                               register char *p;
+
+                               p = &wwtouched[row1x];
+                               for (i = row2x - row1x; --i >= 0;)
+                                       *p++ |= WWU_MAJOR|WWU_TOUCHED;
+                       }
+                       wwredrawwin1(w, row1, row1x, dir);
+                       wwredrawwin1(w, row2x - 1, row2 - leaveit, dir);
                } else {
                } else {
-                       cqq = &wwns[endrow + w->ww_w.t];
-                       cpp = cqq + 1;
-                       tmp = *cqq;
-                       for (i = endrow - startrow; --i >= 0;)
-                               *--cpp = *--cqq;
-                       *cqq = tmp;
-                       wwredrawwin1(w, srow + leaveit, startrow - 1,
-                               w->ww_scroll + dir);
-                       wwredrawwin1(w, endrow + 1, erow, w->ww_scroll + dir);
+                       {
+                               register union ww_char *tmp;
+                               register union ww_char **cpp, **cqq;
+
+                               cpp = &wwns[row2x];
+                               cqq = cpp - 1;
+                               tmp = *cqq;
+                               for (i = row2x - row1x; --i > 0;)
+                                       *--cpp = *--cqq;
+                               *cqq = tmp;
+                       }
+                       if (deleted) {
+                               register char *p, *q;
+
+                               p = &wwtouched[row2x];
+                               q = p - 1;
+                               for (i = row2x - row1x; --i > 0;)
+                                       *--p = *--q;
+                               *q |= WWU_MAJOR|WWU_TOUCHED;
+                       } else {
+                               register char *p;
+
+                               p = &wwtouched[row1x];
+                               for (i = row2x - row1x; --i >= 0;)
+                                       *p++ |= WWU_TOUCHED;
+                       }
+                       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;
 }