lint
[unix-history] / usr / src / usr.bin / window / wwscroll.c
index e2f4f82..7b7b3a9 100644 (file)
@@ -1,34 +1,54 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
 #ifndef lint
 #ifndef lint
-static char *sccsid = "@(#)wwscroll.c  3.9 83/09/14";
-#endif
+static char sccsid[] = "@(#)wwscroll.c 3.22 (Berkeley) %G%";
+#endif /* not lint */
 
 #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);
+       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) {
        if (n < w->ww_i.nr) {
                while (--n >= 0) {
-                       (void) wwscroll1(w, w->ww_i.t - w->ww_w.t,
-                               w->ww_i.b - w->ww_w.t, 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);
        }
 }
@@ -47,7 +67,7 @@ int leaveit;
        int row1x, row2x;
        int nvis;
        int nvismax;
        int row1x, row2x;
        int nvis;
        int nvismax;
-       int deleted = 0;
+       int scrolled = 0;
 
        /*
         * See how many lines on the screen are affected.
 
        /*
         * See how many lines on the screen are affected.
@@ -73,57 +93,44 @@ int leaveit;
                nvis += w->ww_nvis[i];
 
        /*
                nvis += w->ww_nvis[i];
 
        /*
-        * If it's a good idea to use delete and insert line
-        * and the terminal can, then do it.
+        * If it's a good idea to scroll and the terminal can, then do it.
         */
         */
-       if (nvis > nvismax / 2 && tt.tt_delline && tt.tt_insline) {
+       if (nvis < nvismax / 2)
+               goto no_scroll;         /* not worth it */
+       if ((dir > 0 ? tt.tt_scroll_down == 0 : tt.tt_scroll_up == 0) ||
+           (tt.tt_scroll_top != row1x || tt.tt_scroll_bot != row2x - 1) &&
+           tt.tt_setscroll == 0)
+               if (tt.tt_delline == 0 || tt.tt_insline == 0)
+                       goto no_scroll;
+       xxscroll(dir, row1x, row2x);
+       scrolled = 1;
+       /*
+        * Fix up the old screen.
+        */
+       {
                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)(row1x + w->ww_w.t, 0);
-                       (*tt.tt_delline)();
-                       if (row2x + w->ww_w.t < wwnrow) {
-                               (*tt.tt_move)(row2x + w->ww_w.t - 1, 0);
-                               (*tt.tt_insline)();
-                       }
-                       /*
-                        * Fix up the old screen.
-                        */
-                       cpp = &wwos[row1x + w->ww_w.t];
+                       cpp = &wwos[row1x];
                        cqq = cpp + 1;
                        tmp = *cpp;
                        for (i = row2x - row1x; --i > 0;)
                                *cpp++ = *cqq++;
                        *cpp = tmp;
                        cqq = cpp + 1;
                        tmp = *cpp;
                        for (i = row2x - row1x; --i > 0;)
                                *cpp++ = *cqq++;
                        *cpp = tmp;
-                       for (i = wwncol; --i >= 0;)
-                               tmp++->c_w = ' ';
                } else {
                } else {
-                       if (tt.tt_retain || row2x + w->ww_w.t != wwnrow) {
-                               (*tt.tt_move)(row2x + w->ww_w.t - 1, 0);
-                               (*tt.tt_delline)();
-                       }
-                       (*tt.tt_move)(row1x + w->ww_w.t, 0);
-                       (*tt.tt_insline)();
-                       /*
-                        * Fix up the old screen.
-                        */
-                       cpp = &wwos[row2x + w->ww_w.t];
+                       cpp = &wwos[row2x];
                        cqq = cpp - 1;
                        tmp = *cqq;
                        for (i = row2x - row1x; --i > 0;)
                                *--cpp = *--cqq;
                        *cqq = tmp;
                        cqq = cpp - 1;
                        tmp = *cqq;
                        for (i = row2x - row1x; --i > 0;)
                                *--cpp = *--cqq;
                        *cqq = tmp;
-                       for (i = wwncol; --i >= 0;)
-                               tmp++->c_w = ' ';
                }
                }
-               deleted++;
+               for (i = wwncol; --i >= 0;)
+                       tmp++->c_w = ' ';
        }
 
        }
 
+no_scroll:
        /*
         * Fix the new screen.
         */
        /*
         * Fix the new screen.
         */
@@ -136,70 +143,73 @@ 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[row1x + w->ww_w.t];
+                               cpp = &wwns[row1x];
                                cqq = cpp + 1;
                                tmp = *cpp;
                                for (i = row2x - row1x; --i > 0;)
                                        *cpp++ = *cqq++;
                                *cpp = tmp;
                        }
                                cqq = cpp + 1;
                                tmp = *cpp;
                                for (i = row2x - row1x; --i > 0;)
                                        *cpp++ = *cqq++;
                                *cpp = tmp;
                        }
-                       if (deleted) {
+                       if (scrolled) {
                                register char *p, *q;
 
                                register char *p, *q;
 
-                               p = &wwtouched[row1x + w->ww_w.t];
+                               p = &wwtouched[row1x];
                                q = p + 1;
                                for (i = row2x - row1x; --i > 0;)
                                        *p++ = *q++;
                                q = p + 1;
                                for (i = row2x - row1x; --i > 0;)
                                        *p++ = *q++;
-                               *p = 1;
+                               *p |= WWU_TOUCHED;
                        } else {
                                register char *p;
 
                        } else {
                                register char *p;
 
-                               p = &wwtouched[row1x + w->ww_w.t];
+                               p = &wwtouched[row1x];
                                for (i = row2x - row1x; --i >= 0;)
                                for (i = row2x - row1x; --i >= 0;)
-                                       *p++ = 1;
+                                       *p++ |= WWU_TOUCHED;
                        }
                        }
-                       wwredrawwin1(w, row1, row1x, w->ww_scroll + dir);
-                       wwredrawwin1(w, row2x - 1, row2 - 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;
 
-                               cpp = &wwns[row2x + w->ww_w.t];
+                               cpp = &wwns[row2x];
                                cqq = cpp - 1;
                                tmp = *cqq;
                                for (i = row2x - row1x; --i > 0;)
                                        *--cpp = *--cqq;
                                *cqq = tmp;
                        }
                                cqq = cpp - 1;
                                tmp = *cqq;
                                for (i = row2x - row1x; --i > 0;)
                                        *--cpp = *--cqq;
                                *cqq = tmp;
                        }
-                       if (deleted) {
+                       if (scrolled) {
                                register char *p, *q;
 
                                register char *p, *q;
 
-                               p = &wwtouched[row2x + w->ww_w.t];
+                               p = &wwtouched[row2x];
                                q = p - 1;
                                for (i = row2x - row1x; --i > 0;)
                                        *--p = *--q;
                                q = p - 1;
                                for (i = row2x - row1x; --i > 0;)
                                        *--p = *--q;
-                               *q = 1;
+                               *q |= WWU_TOUCHED;
                        } else {
                                register char *p;
 
                        } else {
                                register char *p;
 
-                               p = &wwtouched[row1x + w->ww_w.t];
+                               p = &wwtouched[row1x];
                                for (i = row2x - row1x; --i >= 0;)
                                for (i = row2x - row1x; --i >= 0;)
-                                       *p++ = 1;
+                                       *p++ |= WWU_TOUCHED;
                        }
                        }
-                       wwredrawwin1(w, row1 + leaveit, row1x - 1,
-                               w->ww_scroll + dir);
-                       wwredrawwin1(w, row2x, row2, w->ww_scroll + dir);
+                       wwredrawwin1(w, row1 + leaveit, row1x + 1, dir);
+                       wwredrawwin1(w, row2x, row2, dir);
                }
        } else {
                }
        } else {
+               if (scrolled) {
+                       register char *p;
+
+                       p = &wwtouched[row1x];
+                       for (i = row2x - row1x; --i >= 0;)
+                               *p++ |= WWU_TOUCHED;
+               }
 out:
                if (dir > 0)
 out:
                if (dir > 0)
-                       wwredrawwin1(w, row1, row2 - leaveit,
-                               w->ww_scroll + dir);
+                       wwredrawwin1(w, row1, row2 - leaveit, dir);
                else
                else
-                       wwredrawwin1(w, row1 + leaveit, row2,
-                               w->ww_scroll + dir);
+                       wwredrawwin1(w, row1 + leaveit, row2, dir);
        }
        }
-       return deleted;
+       return scrolled;
 }
 }