scrolling region, suggestion from Ray Moody (ray@j.cc.purdue.edu)
authorEdward Wang <edward@ucbvax.Berkeley.EDU>
Thu, 12 May 1988 09:04:21 +0000 (01:04 -0800)
committerEdward Wang <edward@ucbvax.Berkeley.EDU>
Thu, 12 May 1988 09:04:21 +0000 (01:04 -0800)
SCCS-vsn: usr.bin/window/wwend.c 3.10
SCCS-vsn: usr.bin/window/tt.h 3.19
SCCS-vsn: usr.bin/window/ttinit.c 3.19
SCCS-vsn: usr.bin/window/tth19.c 3.18
SCCS-vsn: usr.bin/window/ttgeneric.c 3.34
SCCS-vsn: usr.bin/window/wwscroll.c 3.19

usr/src/usr.bin/window/tt.h
usr/src/usr.bin/window/ttgeneric.c
usr/src/usr.bin/window/tth19.c
usr/src/usr.bin/window/ttinit.c
usr/src/usr.bin/window/wwend.c
usr/src/usr.bin/window/wwscroll.c

index 367bb8d..6a77267 100644 (file)
@@ -9,7 +9,7 @@
  * software without specific prior written permission. This software
  * is provided ``as is'' without express or implied warranty.
  *
  * software without specific prior written permission. This software
  * is provided ``as is'' without express or implied warranty.
  *
- *     @(#)tt.h        3.18 (Berkeley) %G%
+ *     @(#)tt.h        3.19 (Berkeley) %G%
  */
 
 /*
  */
 
 /*
@@ -30,6 +30,9 @@ struct tt {
        int (*tt_clreol)();
        int (*tt_clreos)();
        int (*tt_clear)();
        int (*tt_clreol)();
        int (*tt_clreos)();
        int (*tt_clear)();
+       int (*tt_scroll_down)();
+       int (*tt_scroll_up)();
+       int (*tt_setscroll)();          /* set scrolling region */
        int (*tt_setinsert)();          /* set insert mode */
        int (*tt_setmodes)();           /* set display modes */
 
        int (*tt_setinsert)();          /* set insert mode */
        int (*tt_setmodes)();           /* set display modes */
 
@@ -40,6 +43,8 @@ struct tt {
        char tt_ninsert;                /* insert mode on next write */
        int tt_row;                     /* cursor row */
        int tt_col;                     /* cursor column */
        char tt_ninsert;                /* insert mode on next write */
        int tt_row;                     /* cursor row */
        int tt_col;                     /* cursor column */
+       int tt_scroll_top;              /* top of scrolling region */
+       int tt_scroll_bot;              /* bottom of scrolling region */
 
                /* terminal info */
        int tt_nrow;                    /* number of display rows */
 
                /* terminal info */
        int tt_nrow;                    /* number of display rows */
@@ -48,7 +53,6 @@ struct tt {
        char tt_availmodes;             /* the display modes supported */
        char tt_wrap;                   /* has auto wrap around */
        char tt_retain;                 /* can retain below (db flag) */
        char tt_availmodes;             /* the display modes supported */
        char tt_wrap;                   /* has auto wrap around */
        char tt_retain;                 /* can retain below (db flag) */
-       char tt_noscroll;               /* terminal doesn't scroll (ns flag) */
 
                /* the frame characters */
        short *tt_frame;
 
                /* the frame characters */
        short *tt_frame;
index cb07c0e..9b9bca8 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)ttgeneric.c        3.33 (Berkeley) %G%";
+static char sccsid[] = "@(#)ttgeneric.c        3.34 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "ww.h"
 #endif /* not lint */
 
 #include "ww.h"
@@ -65,15 +65,20 @@ struct tt_str *gen_BC;
 struct tt_str *gen_ND;
 struct tt_str *gen_HO;
 struct tt_str *gen_NL;
 struct tt_str *gen_ND;
 struct tt_str *gen_HO;
 struct tt_str *gen_NL;
+struct tt_str *gen_CR;
 struct tt_str *gen_AS;
 struct tt_str *gen_AE;
 struct tt_str *gen_XS;
 struct tt_str *gen_XE;
 struct tt_str *gen_AS;
 struct tt_str *gen_AE;
 struct tt_str *gen_XS;
 struct tt_str *gen_XE;
+struct tt_str *gen_SF;
+struct tt_str *gen_SR;
+struct tt_str *gen_CS;
 char gen_MI;
 char gen_MS;
 char gen_AM;
 char gen_OS;
 char gen_BS;
 char gen_MI;
 char gen_MS;
 char gen_AM;
 char gen_OS;
 char gen_BS;
+char gen_DA;
 char gen_DB;
 char gen_NS;
 char gen_XN;
 char gen_DB;
 char gen_NS;
 char gen_XN;
@@ -214,9 +219,13 @@ register int row, col;
                gen_setinsert(0);
        if (!gen_MS && tt.tt_modes)
                gen_setmodes(0);
                gen_setinsert(0);
        if (!gen_MS && tt.tt_modes)
                gen_setmodes(0);
+       if (row < tt.tt_scroll_top || row > tt.tt_scroll_bot)
+               gen_setscroll(tt.tt_nrow - 1, 0);
        if (tt.tt_row == row) {
        if (tt.tt_row == row) {
-               if (tt.tt_col == col)
-                       return;
+               if (col == 0) {
+                       ttxputs(gen_CR);
+                       goto out;
+               }
                if (tt.tt_col == col - 1) {
                        if (gen_ND) {
                                ttxputs(gen_ND);
                if (tt.tt_col == col - 1) {
                        if (gen_ND) {
                                ttxputs(gen_ND);
@@ -296,6 +305,26 @@ gen_delchar()
        tttputs(gen_DC, gen_CO - tt.tt_col);
 }
 
        tttputs(gen_DC, gen_CO - tt.tt_col);
 }
 
+gen_scroll_down()
+{
+       gen_move(tt.tt_scroll_bot, 0);
+       ttxputs(gen_SF);
+}
+
+gen_scroll_up()
+{
+       gen_move(tt.tt_scroll_top, 0);
+       ttxputs(gen_SR);
+}
+
+gen_setscroll(top, bot)
+{
+       tttgoto(gen_CS, bot, top);
+       tt.tt_scroll_top = top;
+       tt.tt_scroll_bot = bot;
+       tt.tt_row = tt.tt_col = -10;
+}
+
 tt_generic()
 {
        gen_PC = tttgetstr("pc");
 tt_generic()
 {
        gen_PC = tttgetstr("pc");
@@ -326,15 +355,20 @@ tt_generic()
        gen_ND = ttxgetstr("nd");
        gen_HO = ttxgetstr("ho");
        gen_NL = ttxgetstr("nl");
        gen_ND = ttxgetstr("nd");
        gen_HO = ttxgetstr("ho");
        gen_NL = ttxgetstr("nl");
+       gen_CR = ttxgetstr("cr");
        gen_AS = ttxgetstr("as");
        gen_AE = ttxgetstr("ae");
        gen_XS = ttxgetstr("XS");
        gen_XE = ttxgetstr("XE");
        gen_AS = ttxgetstr("as");
        gen_AE = ttxgetstr("ae");
        gen_XS = ttxgetstr("XS");
        gen_XE = ttxgetstr("XE");
+       gen_SF = ttxgetstr("sf");
+       gen_SR = ttxgetstr("sr");
+       gen_CS = ttxgetstr("cs");
        gen_MI = tgetflag("mi");
        gen_MS = tgetflag("ms");
        gen_AM = tgetflag("am");
        gen_OS = tgetflag("os");
        gen_BS = tgetflag("bs");
        gen_MI = tgetflag("mi");
        gen_MS = tgetflag("ms");
        gen_AM = tgetflag("am");
        gen_OS = tgetflag("os");
        gen_BS = tgetflag("bs");
+       gen_DA = tgetflag("da");
        gen_DB = tgetflag("db");
        gen_NS = tgetflag("ns");
        gen_XN = tgetflag("xn");
        gen_DB = tgetflag("db");
        gen_NS = tgetflag("ns");
        gen_XN = tgetflag("xn");
@@ -342,19 +376,25 @@ tt_generic()
        gen_LI = tgetnum("li");
        gen_UG = tgetnum("ug");
        gen_SG = tgetnum("sg");
        gen_LI = tgetnum("li");
        gen_UG = tgetnum("ug");
        gen_SG = tgetnum("sg");
+       if (gen_CL == 0 || gen_OS || gen_CM == 0)
+               return -1;
 
        if (gen_NL == 0) {
                static struct tt_str nl = { "\n", 1 };
                gen_NL = &nl;
        }
 
        if (gen_NL == 0) {
                static struct tt_str nl = { "\n", 1 };
                gen_NL = &nl;
        }
+       if (gen_CR == 0) {
+               static struct tt_str cr = { "\r", 1 };
+               gen_CR = &cr;
+       }
        if (gen_BC == 0 && gen_BS) {
                static struct tt_str bc = { "\b", 1 };
                gen_BC = &bc;
        }
        if (gen_BC == 0 && gen_BS) {
                static struct tt_str bc = { "\b", 1 };
                gen_BC = &bc;
        }
+       if (gen_SF == 0 && !gen_NS)
+               gen_SF = gen_NL;
        BC = gen_BC ? gen_BC->ts_str : 0;
        UP = gen_UP ? gen_UP->ts_str : 0;
        BC = gen_BC ? gen_BC->ts_str : 0;
        UP = gen_UP ? gen_UP->ts_str : 0;
-       if (gen_CL == 0 || gen_OS || gen_CM == 0)
-               return -1;
 
        if (gen_DC)
                tt.tt_delchar = gen_delchar;
 
        if (gen_DC)
                tt.tt_delchar = gen_delchar;
@@ -366,6 +406,16 @@ tt_generic()
                tt.tt_clreol = gen_clreol;
        if (gen_CD)
                tt.tt_clreos = gen_clreos;
                tt.tt_clreol = gen_clreol;
        if (gen_CD)
                tt.tt_clreos = gen_clreos;
+       if (gen_SF)
+               tt.tt_scroll_down = gen_scroll_down;
+       /*
+        * Don't allow scroll_up if da or db but not cs.
+        * See comment in wwscroll.c.
+        */
+       if (gen_SR && (gen_CS || !gen_DA && !gen_DB))
+               tt.tt_scroll_up = gen_scroll_up;
+       if (gen_CS)
+               tt.tt_setscroll = gen_setscroll;
        if (gen_SG > 0)
                gen_SO = 0;
        if (gen_UG > 0 || gen_US && gen_SO && ttstrcmp(gen_US, gen_SO) == 0)
        if (gen_SG > 0)
                gen_SO = 0;
        if (gen_UG > 0 || gen_US && gen_SO && ttstrcmp(gen_US, gen_SO) == 0)
@@ -381,7 +431,6 @@ tt_generic()
        tt.tt_hasinsert = gen_IM != 0;
        tt.tt_wrap = gen_AM;
        tt.tt_retain = gen_DB;
        tt.tt_hasinsert = gen_IM != 0;
        tt.tt_wrap = gen_AM;
        tt.tt_retain = gen_DB;
-       tt.tt_noscroll = gen_NS;
        tt.tt_ncol = gen_CO;
        tt.tt_nrow = gen_LI;
        tt.tt_init = gen_init;
        tt.tt_ncol = gen_CO;
        tt.tt_nrow = gen_LI;
        tt.tt_init = gen_init;
index d6509d9..6aa8368 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)tth19.c    3.17 (Berkeley) %G%";
+static char sccsid[] = "@(#)tth19.c    3.18 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "ww.h"
 #endif /* not lint */
 
 #include "ww.h"
@@ -141,11 +141,16 @@ register char row, col;
        if (tt.tt_row == row) {
                if (tt.tt_col == col)
                        return;
        if (tt.tt_row == row) {
                if (tt.tt_col == col)
                        return;
+               if (col == 0) {
+                       pc(\r);
+                       goto out;
+               }
                if (tt.tt_col == col - 1) {
                        esc();
                        pc(C);
                        goto out;
                if (tt.tt_col == col - 1) {
                        esc();
                        pc(C);
                        goto out;
-               } else if (tt.tt_col == col + 1) {
+               }
+               if (tt.tt_col == col + 1) {
                        pc(\b);
                        goto out;
                }
                        pc(\b);
                        goto out;
                }
@@ -155,7 +160,8 @@ register char row, col;
                        esc();
                        pc(A);
                        goto out;
                        esc();
                        pc(A);
                        goto out;
-               } else if (tt.tt_row == row - 1) {
+               }
+               if (tt.tt_row == row - 1) {
                        pc(\n);
                        goto out;
                }
                        pc(\n);
                        goto out;
                }
@@ -219,6 +225,19 @@ h19_delchar()
        pc(N);
 }
 
        pc(N);
 }
 
+h19_scroll_down()
+{
+       h19_move(NROW - 1, 0);
+       pc(\n);
+}
+
+h19_scroll_up()
+{
+       h19_move(0, 0);
+       esc();
+       pc(I);
+}
+
 tt_h19()
 {
        float cpms = (float) wwbaud / 10000;    /* char per ms */
 tt_h19()
 {
        float cpms = (float) wwbaud / 10000;    /* char per ms */
@@ -239,6 +258,8 @@ tt_h19()
        tt.tt_move = h19_move;
        tt.tt_write = h19_write;
        tt.tt_putc = h19_putc;
        tt.tt_move = h19_move;
        tt.tt_write = h19_write;
        tt.tt_putc = h19_putc;
+       tt.tt_scroll_down = h19_scroll_down;
+       tt.tt_scroll_up = h19_scroll_up;
        tt.tt_setinsert = h19_setinsert;
        tt.tt_setmodes = h19_setmodes;
 
        tt.tt_setinsert = h19_setinsert;
        tt.tt_setmodes = h19_setmodes;
 
index 3e50bb2..568059d 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)ttinit.c   3.18 (Berkeley) %G%";
+static char sccsid[] = "@(#)ttinit.c   3.19 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "ww.h"
 #endif /* not lint */
 
 #include "ww.h"
@@ -80,6 +80,8 @@ ttinit()
                wwerrno = WWE_CANTDO;
                return -1;
        }
                wwerrno = WWE_CANTDO;
                return -1;
        }
+       tt.tt_scroll_top = 0;
+       tt.tt_scroll_bot = tt.tt_nrow - 1;
        if (ioctl(0, TIOCGWINSZ, (char *)&winsize) >= 0 &&
            winsize.ws_row != 0 && winsize.ws_col != 0) {
                tt.tt_nrow = winsize.ws_row;
        if (ioctl(0, TIOCGWINSZ, (char *)&winsize) >= 0 &&
            winsize.ws_row != 0 && winsize.ws_col != 0) {
                tt.tt_nrow = winsize.ws_row;
index 6dd0789..165f988 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)wwend.c    3.9 (Berkeley) %G%";
+static char sccsid[] = "@(#)wwend.c    3.10 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "ww.h"
 #endif /* not lint */
 
 #include "ww.h"
@@ -20,10 +20,15 @@ static char sccsid[] = "@(#)wwend.c 3.9 (Berkeley) %G%";
 wwend()
 {
        wwupdate();
 wwend()
 {
        wwupdate();
+       if (tt.tt_scroll_top != 0 || tt.tt_scroll_bot != tt.tt_nrow - 1)
+               /* tt.tt_setscroll is known to be defined */
+               (*tt.tt_setscroll)(0, tt.tt_nrow - 1);
        if (tt.tt_insert)
                (*tt.tt_setinsert)(0);
        if (tt.tt_modes)
                (*tt.tt_setmodes)(0);
        if (tt.tt_insert)
                (*tt.tt_setinsert)(0);
        if (tt.tt_modes)
                (*tt.tt_setmodes)(0);
+       if (tt.tt_scroll_down)
+               (*tt.tt_scroll_down)();
        (*tt.tt_move)(tt.tt_nrow - 1, 0);
        (*tt.tt_end)();
        ttflush();
        (*tt.tt_move)(tt.tt_nrow - 1, 0);
        (*tt.tt_end)();
        ttflush();
index c2426d2..d86ca2a 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)wwscroll.c 3.18 (Berkeley) %G%";
+static char sccsid[] = "@(#)wwscroll.c 3.19 (Berkeley) %G%";
 #endif /* not lint */
 
 #include "ww.h"
 #endif /* not lint */
 
 #include "ww.h"
@@ -62,7 +62,8 @@ int leaveit;
        int row1x, row2x;
        int nvis;
        int nvismax;
        int row1x, row2x;
        int nvis;
        int nvismax;
-       int deleted = 0;
+       int scrolled = 0;
+       int (*scroll_func)();
 
        /*
         * See how many lines on the screen are affected.
 
        /*
         * See how many lines on the screen are affected.
@@ -89,47 +90,68 @@ int leaveit;
 
        /*
         * If it's a good idea to scroll and the terminal can, then do it.
 
        /*
         * If it's a good idea to scroll and the terminal can, then do it.
+        * We handle retain (da and db) by putting the burden on scrolling up,
+        * which is the less common operation.  It must ensure that
+        * text is not pushed below the screen, so scrolling down doesn't
+        * have to worry about it.
         */
         */
-       if (nvis < nvismax / 2) {
-               /* not worth it */
-       } else if (!tt.tt_noscroll && row1x == 0 && row2x == wwnrow && dir > 0)
-       {
-               /*
-                * We're going to assume that a line feed at the
-                * bottom of the screen will cause a scroll, unless
-                * "ns" is set.  This should work at least 99%
-                * of the time.  At any rate, vi seems to do it.
-                */
-               if (tt.tt_row != wwnrow - 1)
-                       (*tt.tt_move)(wwnrow - 1, 0);
-               ttputc('\n');
-               deleted++;
-       } else if (tt.tt_delline && tt.tt_insline) {
-               /*
-                * Don't worry about retain when scrolling down,
-                * but do worry when scrolling up, for hp2621.
-                */
-               if (dir > 0) {
-                       (*tt.tt_move)(row1x, 0);
-                       (*tt.tt_delline)();
-                       if (row2x < wwnrow) {
-                               (*tt.tt_move)(row2x - 1, 0);
-                               (*tt.tt_insline)();
-                       }
-               } else {
-                       if (tt.tt_retain || row2x != wwnrow) {
-                               (*tt.tt_move)(row2x - 1, 0);
-                               (*tt.tt_delline)();
-                       }
-                       (*tt.tt_move)(row1x, 0);
+       if (nvis < nvismax / 2)
+               goto no_scroll;         /* not worth it */
+       /*
+        * Try scrolling region (or scrolling the whole screen) first.
+        * Can we assume "sr" doesn't push text below the screen
+        * so we don't have to worry about retain below?
+        * What about scrolling down with a newline?  It probably does
+        * push text above (with da).  Scrolling up would then have
+        * to take care of that.
+        * It's easy to be fool proof, but that slows things down.
+        * The current solution is to disallow tt_scroll_up if da or db is true
+        * but cs (scrolling region) is not.  Again, we sacrifice scrolling
+        * up in favor of scrolling down.  The idea is having scrolling regions
+        * probably means we can scroll (even the whole screen) with impunity.
+        * This lets us work efficiently on simple terminals (use newline
+        * on the bottom to scroll), on any terminal without retain, and
+        * on vt100 style scrolling regions (I think).
+        */
+       if (scroll_func = dir > 0 ? tt.tt_scroll_down : tt.tt_scroll_up) {
+               if (tt.tt_scroll_top != row1x || tt.tt_scroll_bot != row2x - 1)
+                       if (tt.tt_setscroll == 0)
+                               scroll_func = 0;
+                       else
+                               (*tt.tt_setscroll)(row1x, row2x - 1);
+               if (scroll_func) {
+                       (*scroll_func)();
+                       goto did_scroll;
+               }
+       }
+       /*
+        * Try insert/delete line.
+        * Don't worry about retain when scrolling down,
+        * but do worry when scrolling up, for hp2621.
+        */
+       if (tt.tt_delline == 0 || tt.tt_insline == 0)
+               goto no_scroll;
+       if (dir > 0) {
+               (*tt.tt_move)(row1x, 0);
+               (*tt.tt_delline)();
+               if (row2x < wwnrow) {
+                       (*tt.tt_move)(row2x - 1, 0);
                        (*tt.tt_insline)();
                }
                        (*tt.tt_insline)();
                }
-               deleted++;
+       } else {
+               if (tt.tt_retain || row2x != wwnrow) {
+                       (*tt.tt_move)(row2x - 1, 0);
+                       (*tt.tt_delline)();
+               }
+               (*tt.tt_move)(row1x, 0);
+               (*tt.tt_insline)();
        }
        }
+did_scroll:
+       scrolled = 1;
        /*
         * Fix up the old screen.
         */
        /*
         * Fix up the old screen.
         */
-       if (deleted) {
+       {
                register union ww_char *tmp;
                register union ww_char **cpp, **cqq;
 
                register union ww_char *tmp;
                register union ww_char **cpp, **cqq;
 
@@ -152,6 +174,7 @@ int leaveit;
                        tmp++->c_w = ' ';
        }
 
                        tmp++->c_w = ' ';
        }
 
+no_scroll:
        /*
         * Fix the new screen.
         */
        /*
         * Fix the new screen.
         */
@@ -171,7 +194,7 @@ int leaveit;
                                        *cpp++ = *cqq++;
                                *cpp = tmp;
                        }
                                        *cpp++ = *cqq++;
                                *cpp = tmp;
                        }
-                       if (deleted) {
+                       if (scrolled) {
                                register char *p, *q;
 
                                p = &wwtouched[row1x];
                                register char *p, *q;
 
                                p = &wwtouched[row1x];
@@ -200,7 +223,7 @@ int leaveit;
                                        *--cpp = *--cqq;
                                *cqq = tmp;
                        }
                                        *--cpp = *--cqq;
                                *cqq = tmp;
                        }
-                       if (deleted) {
+                       if (scrolled) {
                                register char *p, *q;
 
                                p = &wwtouched[row2x];
                                register char *p, *q;
 
                                p = &wwtouched[row2x];
@@ -219,7 +242,7 @@ int leaveit;
                        wwredrawwin1(w, row2x, row2, dir);
                }
        } else {
                        wwredrawwin1(w, row2x, row2, dir);
                }
        } else {
-               if (deleted) {
+               if (scrolled) {
                        register char *p;
 
                        p = &wwtouched[row1x];
                        register char *p;
 
                        p = &wwtouched[row1x];
@@ -232,5 +255,5 @@ out:
                else
                        wwredrawwin1(w, row1 + leaveit, row2, dir);
        }
                else
                        wwredrawwin1(w, row1 + leaveit, row2, dir);
        }
-       return deleted;
+       return scrolled;
 }
 }