BSD 4_3_Net_2 release
[unix-history] / usr / src / lib / libcurses / refresh.c
index f532472..a4937c5 100644 (file)
@@ -1,15 +1,67 @@
+/*
+ * Copyright (c) 1981 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)refresh.c  5.5 (Berkeley) 3/3/91";
+#endif /* not lint */
+
+/*
+ * make the current screen look like "win" over the area coverd by
+ * win.
+ */
+
 # include      "curses.ext"
 
 # include      "curses.ext"
 
-# ifndef DEBUG
-static short   ly, lx;
+# ifdef DEBUG
+# define       STATIC
 # else
 # else
-short          ly, lx;
+# define       STATIC  static
 # endif
 
 # endif
 
+STATIC short   ly, lx;
+
+STATIC bool    curwin;
+
+WINDOW *_win = NULL;
+
+STATIC int     domvcur(), makech();
+
 wrefresh(win)
 reg WINDOW     *win;
 {
        reg short       wy;
 wrefresh(win)
 reg WINDOW     *win;
 {
        reg short       wy;
+       reg int         retval;
+       reg WINDOW      *orig;
 
        /*
         * make sure were in visual state
 
        /*
         * make sure were in visual state
@@ -19,101 +71,156 @@ reg WINDOW        *win;
                _puts(TI);
                _endwin = FALSE;
        }
                _puts(TI);
                _endwin = FALSE;
        }
-       if (win->_clear || curscr->_clear) {
+
+       /*
+        * initialize loop parameters
+        */
+
+       ly = curscr->_cury;
+       lx = curscr->_curx;
+       wy = 0;
+       _win = win;
+       curwin = (win == curscr);
+
+       if (win->_clear || curscr->_clear || curwin) {
                if ((win->_flags & _FULLWIN) || curscr->_clear) {
                        _puts(CL);
                if ((win->_flags & _FULLWIN) || curscr->_clear) {
                        _puts(CL);
-                       curscr->_curx = curscr->_cury = 0;
-                       curscr->_clear = FALSE;
-                       werase(curscr);
+                       ly = 0;
+                       lx = 0;
+                       if (!curwin) {
+                               curscr->_clear = FALSE;
+                               curscr->_cury = 0;
+                               curscr->_curx = 0;
+                               werase(curscr);
+                       }
+                       touchwin(win);
                }
                win->_clear = FALSE;
        }
        if (!CA) {
                if (win->_curx != 0)
                }
                win->_clear = FALSE;
        }
        if (!CA) {
                if (win->_curx != 0)
-                       putchar('\n');
-               werase(curscr);
+                       _putchar('\n');
+               if (!curwin)
+                       werase(curscr);
        }
 # ifdef DEBUG
        }
 # ifdef DEBUG
+       fprintf(outf, "REFRESH(%0.2o): curwin = %d\n", win, curwin);
        fprintf(outf, "REFRESH:\n\tfirstch\tlastch\n");
 # endif
        fprintf(outf, "REFRESH:\n\tfirstch\tlastch\n");
 # endif
-       ly = curscr->_cury;
-       lx = curscr->_curx;
-       wy = 0;
        for (wy = 0; wy < win->_maxy; wy++) {
 # ifdef DEBUG
        for (wy = 0; wy < win->_maxy; wy++) {
 # ifdef DEBUG
-               fprintf(outf, "%d\t%d\t%d\n", wy, win->_firstch[wy], win->_lastch[wy]);
+               fprintf(outf, "%d\t%d\t%d\n", wy, win->_firstch[wy],
+                       win->_lastch[wy]);
 # endif
                if (win->_firstch[wy] != _NOCHANGE)
                        if (makech(win, wy) == ERR)
 # endif
                if (win->_firstch[wy] != _NOCHANGE)
                        if (makech(win, wy) == ERR)
-                           return ERR;
-                       else
-                           win->_firstch[wy] = win->_firstch[wy] = _NOCHANGE;
-       }
-       if (win->_leave) {
-               curscr->_cury = ly;
-               curscr->_curx = lx;
-               ly -= win->_begy;
-               lx -= win->_begx;
-               if (ly >= 0 && ly < win->_maxy && lx >= 0 && lx < win->_maxx) {
-                       win->_cury = ly;
-                       win->_curx = lx;
-               }
-               else
-                       win->_cury = win->_curx = 0;
+                               return ERR;
+                       else {
+                               if (win->_firstch[wy] >= win->_ch_off)
+                                       win->_firstch[wy] = win->_maxx +
+                                                           win->_ch_off;
+                               if (win->_lastch[wy] < win->_maxx +
+                                                      win->_ch_off)
+                                       win->_lastch[wy] = win->_ch_off;
+                               if (win->_lastch[wy] < win->_firstch[wy])
+                                       win->_firstch[wy] = _NOCHANGE;
+                       }
+# ifdef DEBUG
+               fprintf(outf, "\t%d\t%d\n", win->_firstch[wy],
+                       win->_lastch[wy]);
+# endif
        }
        }
+
+       if (win == curscr)
+               domvcur(ly, lx, win->_cury, win->_curx);
        else {
        else {
-               mvcur(ly, lx, win->_cury + win->_begy, win->_curx + win->_begx);
-               curscr->_cury = win->_cury + win->_begy;
-               curscr->_curx = win->_curx + win->_begx;
+               if (win->_leave) {
+                       curscr->_cury = ly;
+                       curscr->_curx = lx;
+                       ly -= win->_begy;
+                       lx -= win->_begx;
+                       if (ly >= 0 && ly < win->_maxy && lx >= 0 &&
+                           lx < win->_maxx) {
+                               win->_cury = ly;
+                               win->_curx = lx;
+                       }
+                       else
+                               win->_cury = win->_curx = 0;
+               }
+               else {
+                       domvcur(ly, lx, win->_cury + win->_begy,
+                               win->_curx + win->_begx);
+                       curscr->_cury = win->_cury + win->_begy;
+                       curscr->_curx = win->_curx + win->_begx;
+               }
        }
        }
+       retval = OK;
+ret:
+       _win = NULL;
        fflush(stdout);
        fflush(stdout);
-       return OK;
+       return retval;
 }
 
 /*
  * make a change on the screen
  */
 }
 
 /*
  * make a change on the screen
  */
-# ifndef DEBUG
-static
-# endif
+STATIC
 makech(win, wy)
 reg WINDOW     *win;
 short          wy;
 {
 makech(win, wy)
 reg WINDOW     *win;
 short          wy;
 {
-       reg char        *nsp, *csp, *sp;
+       reg char        *nsp, *csp, *ce;
        reg short       wx, lch, y;
        reg int         nlsp, clsp;     /* last space in lines          */
 
        reg short       wx, lch, y;
        reg int         nlsp, clsp;     /* last space in lines          */
 
-       wx = win->_firstch[wy];
+       wx = win->_firstch[wy] - win->_ch_off;
+       if (wx >= win->_maxx)
+               return OK;
+       else if (wx < 0)
+               wx = 0;
+       lch = win->_lastch[wy] - win->_ch_off;
+       if (lch < 0)
+               return OK;
+       else if (lch >= win->_maxx)
+               lch = win->_maxx - 1;;
        y = wy + win->_begy;
        y = wy + win->_begy;
-       lch = win->_lastch[wy];
-       csp = &curscr->_y[wy + win->_begy][wx + win->_begx];
+
+       if (curwin)
+               csp = " ";
+       else
+               csp = &curscr->_y[wy + win->_begy][wx + win->_begx];
+
        nsp = &win->_y[wy][wx];
        nsp = &win->_y[wy][wx];
-       if (CE) {
-               for (sp = &win->_y[wy][win->_maxx - 1]; *sp == ' '; sp--)
-                       if (sp <= win->_y[wy])
+       if (CE && !curwin) {
+               for (ce = &win->_y[wy][win->_maxx - 1]; *ce == ' '; ce--)
+                       if (ce <= win->_y[wy])
                                break;
                                break;
-               nlsp = sp - win->_y[wy];
+               nlsp = ce - win->_y[wy];
        }
        }
-       sp = CE;
+
+       if (!curwin)
+               ce = CE;
+       else
+               ce = NULL;
+
        while (wx <= lch) {
                if (*nsp != *csp) {
        while (wx <= lch) {
                if (*nsp != *csp) {
-                       mvcur(ly, lx, y, wx + win->_begx);
+                       domvcur(ly, lx, y, wx + win->_begx);
 # ifdef DEBUG
                        fprintf(outf, "MAKECH: 1: wx = %d, lx = %d\n", wx, lx);
 # endif        
                        ly = y;
                        lx = wx + win->_begx;
                        while (*nsp != *csp && wx <= lch) {
 # ifdef DEBUG
                        fprintf(outf, "MAKECH: 1: wx = %d, lx = %d\n", wx, lx);
 # endif        
                        ly = y;
                        lx = wx + win->_begx;
                        while (*nsp != *csp && wx <= lch) {
-                               if (sp && wx >= nlsp && *nsp == ' ') {
+                               if (ce != NULL && wx >= nlsp && *nsp == ' ') {
                                        /*
                                         * check for clear to end-of-line
                                         */
                                        /*
                                         * check for clear to end-of-line
                                         */
-                                       sp = &curscr->_y[ly][COLS - 1];
-                                       while (*sp == ' ')
-                                               if (sp-- <= csp)
+                                       ce = &curscr->_y[ly][COLS - 1];
+                                       while (*ce == ' ')
+                                               if (ce-- <= csp)
                                                        break;
                                                        break;
-                                       clsp = sp - curscr->_y[ly] - win->_begx;
+                                       clsp = ce - curscr->_y[ly] - win->_begx;
 # ifdef DEBUG
                                        fprintf(outf, "MAKECH: clsp = %d, nlsp = %d\n", clsp, nlsp);
 # endif
 # ifdef DEBUG
                                        fprintf(outf, "MAKECH: clsp = %d, nlsp = %d\n", clsp, nlsp);
 # endif
@@ -126,14 +233,14 @@ short             wy;
                                                lx = wx + win->_begx;
                                                while (wx++ <= clsp)
                                                        *csp++ = ' ';
                                                lx = wx + win->_begx;
                                                while (wx++ <= clsp)
                                                        *csp++ = ' ';
-                                               goto ret;
+                                               return OK;
                                        }
                                        }
-                                       sp = NULL;
+                                       ce = NULL;
                                }
                                /*
                                 * enter/exit standout mode as appropriate
                                 */
                                }
                                /*
                                 * enter/exit standout mode as appropriate
                                 */
-                               if ((*nsp&_STANDOUT) != (curscr->_flags&_STANDOUT)) {
+                               if (SO && (*nsp&_STANDOUT) != (curscr->_flags&_STANDOUT)) {
                                        if (*nsp & _STANDOUT) {
                                                _puts(SO);
                                                curscr->_flags |= _STANDOUT;
                                        if (*nsp & _STANDOUT) {
                                                _puts(SO);
                                                curscr->_flags |= _STANDOUT;
@@ -144,21 +251,41 @@ short             wy;
                                        }
                                }
                                wx++;
                                        }
                                }
                                wx++;
-                               if (wx >= win->_maxx && wy == win->_maxy)
-                                               if (win->_scroll) {
-                                                   putchar((*csp = *nsp) & 0177);
-                                                   scroll(win);
-                                                   if (win->_flags&_FULLWIN)
-                                                           scroll(curscr);
-                                                   ly = win->_begy+win->_cury;
-                                                   lx = win->_begx+win->_curx;
-                                                   return OK;
-                                               }
-                                               else if (win->_flags&_SCROLLWIN) {
-                                                   lx = --wx;
-                                                   return ERR;
-                                               }
-                               putchar((*csp++ = *nsp++) & 0177);
+                               if (wx >= win->_maxx && wy == win->_maxy - 1)
+                                       if (win->_scroll) {
+                                           if ((curscr->_flags&_STANDOUT) &&
+                                               (win->_flags & _ENDLINE))
+                                                   if (!MS) {
+                                                       _puts(SE);
+                                                       curscr->_flags &= ~_STANDOUT;
+                                                   }
+                                           if (!curwin)
+                                               _putchar((*csp = *nsp) & 0177);
+                                           else
+                                               _putchar(*nsp & 0177);
+                                           if (win->_flags&_FULLWIN && !curwin)
+                                               scroll(curscr);
+                                           ly = win->_begy+win->_cury;
+                                           lx = win->_begx+win->_curx;
+                                           return OK;
+                                       }
+                                       else if (win->_flags&_SCROLLWIN) {
+                                           lx = --wx;
+                                           return ERR;
+                                       }
+                               if (!curwin)
+                                       _putchar((*csp++ = *nsp) & 0177);
+                               else
+                                       _putchar(*nsp & 0177);
+# ifdef FULLDEBUG
+                               fprintf(outf,
+                                       "MAKECH:putchar(%c)\n", *nsp & 0177);
+# endif
+                               if (UC && (*nsp & _STANDOUT)) {
+                                       _putchar('\b');
+                                       _puts(UC);
+                               }
+                               nsp++;
                        }
 # ifdef DEBUG
                        fprintf(outf, "MAKECH: 2: wx = %d, lx = %d\n", wx, lx);
                        }
 # ifdef DEBUG
                        fprintf(outf, "MAKECH: 2: wx = %d, lx = %d\n", wx, lx);
@@ -166,10 +293,24 @@ short             wy;
                        if (lx == wx + win->_begx)      /* if no change */
                                break;
                        lx = wx + win->_begx;
                        if (lx == wx + win->_begx)      /* if no change */
                                break;
                        lx = wx + win->_begx;
+                       if (lx >= COLS && AM) {
+                               lx = 0;
+                               ly++;
+                               /*
+                                * xn glitch: chomps a newline after auto-wrap.
+                                * we just feed it now and forget about it.
+                                */
+                               if (XN) {
+                                       _putchar('\n');
+                                       _putchar('\r');
+                               }
+                       }
                }
                }
-               else if (wx < lch)
-                       while (*nsp == *csp) {
-                               nsp++, csp++;
+               else if (wx <= lch)
+                       while (*nsp == *csp && wx <= lch) {
+                               nsp++;
+                               if (!curwin)
+                                       csp++;
                                ++wx;
                        }
                else
                                ++wx;
                        }
                else
@@ -178,6 +319,19 @@ short              wy;
                fprintf(outf, "MAKECH: 3: wx = %d, lx = %d\n", wx, lx);
 # endif        
        }
                fprintf(outf, "MAKECH: 3: wx = %d, lx = %d\n", wx, lx);
 # endif        
        }
-ret:
        return OK;
 }
        return OK;
 }
+
+/*
+ * perform a mvcur, leaving standout mode if necessary
+ */
+STATIC
+domvcur(oy, ox, ny, nx)
+int    oy, ox, ny, nx; {
+
+       if (curscr->_flags & _STANDOUT && !MS) {
+               _puts(SE);
+               curscr->_flags &= ~_STANDOUT;
+       }
+       mvcur(oy, ox, ny, nx);
+}