Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libcurses Make the touch family of calls actually force ...



details:   https://anonhg.NetBSD.org/src/rev/8cd0cd761378
branches:  trunk
changeset: 791845:8cd0cd761378
user:      blymn <blymn%NetBSD.org@localhost>
date:      Fri Dec 06 11:23:47 2013 +0000

description:
Make the touch family of calls actually force an update of the
terminal bypassing optimisations.  Previously if curses thought curscr
was in sync with virtscr (curses concept of what is on the screen) then
nothing would be output.  This change forces an update out to the terminal
regardless.

diffstat:

 lib/libcurses/refresh.c  |  95 ++++++++++++++++++++++++++++++++++-------------
 lib/libcurses/touchwin.c |  35 +++++++++++++----
 2 files changed, 95 insertions(+), 35 deletions(-)

diffs (truncated from 351 to 300 lines):

diff -r 7c75eb0e13f8 -r 8cd0cd761378 lib/libcurses/refresh.c
--- a/lib/libcurses/refresh.c   Fri Dec 06 02:39:58 2013 +0000
+++ b/lib/libcurses/refresh.c   Fri Dec 06 11:23:47 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: refresh.c,v 1.77 2013/05/05 14:22:07 jdc Exp $ */
+/*     $NetBSD: refresh.c,v 1.78 2013/12/06 11:23:47 blymn Exp $       */
 
 /*
  * Copyright (c) 1981, 1993, 1994
@@ -34,7 +34,7 @@
 #if 0
 static char sccsid[] = "@(#)refresh.c  8.7 (Berkeley) 8/13/94";
 #else
-__RCSID("$NetBSD: refresh.c,v 1.77 2013/05/05 14:22:07 jdc Exp $");
+__RCSID("$NetBSD: refresh.c,v 1.78 2013/12/06 11:23:47 blymn Exp $");
 #endif
 #endif                         /* not lint */
 
@@ -180,6 +180,12 @@
                                        sub_win->alines[sy]->flags
                                            &= ~__ISDIRTY;
                                }
+                               if (sub_win->alines[sy]->flags & __ISFORCED) {
+                                       orig->alines[sy + sub_win->begy - orig->begy]->flags
+                                           |= __ISFORCED;
+                                       sub_win->alines[sy]->flags
+                                           &= ~__ISFORCED;
+                               }
                        }
                }
        }
@@ -209,7 +215,7 @@
                    "_wnoutrefresh: wy %d\tf %d\tl %d\tflags %x\n",
                    wy, *wlp->firstchp, *wlp->lastchp, wlp->flags);
 #endif
-               if ((wlp->flags & __ISDIRTY) == 0)
+               if ((wlp->flags & (__ISDIRTY | __ISFORCED)) == 0)
                        continue;
                vlp = screen->__virtscr->alines[y_off];
 
@@ -274,6 +280,8 @@
                                vlp->flags &= ~__ISPASTEOL;
                        if (wlp->flags & __ISDIRTY)
                                vlp->flags |= __ISDIRTY;
+                       if (wlp->flags & __ISFORCED)
+                               vlp->flags |= __ISFORCED;
 
 #ifdef DEBUG
                        __CTRACE(__CTRACE_REFRESH,
@@ -282,24 +290,25 @@
 #endif
                        /* Set change pointers on "__virtscr". */
                        if (*vlp->firstchp >
-                           *wlp->firstchp + wbegx - win->ch_off)
-                               *vlp->firstchp =
-                                   *wlp->firstchp + wbegx - win->ch_off;
+                               *wlp->firstchp + wbegx - win->ch_off)
+                                       *vlp->firstchp =
+                                           *wlp->firstchp + wbegx - win->ch_off;
                        if (*vlp->lastchp <
-                           *wlp->lastchp + wbegx - win->ch_off)
-                               *vlp->lastchp =
-                                   *wlp->lastchp + wbegx - win->ch_off;
+                               *wlp->lastchp + wbegx - win->ch_off)
+                                       *vlp->lastchp =
+                                           *wlp->lastchp + wbegx - win->ch_off;
 #ifdef DEBUG
                        __CTRACE(__CTRACE_REFRESH,
                            "__virtscr: firstch = %d, lastch = %d\n",
                            *vlp->firstchp, *vlp->lastchp);
 #endif
                        /*
-                        * Unset change pointers only if a window, as a pad
-                        * can be displayed again without any of the contents
-                        * changing.
+                        * Unset change pointers only if a window and we
+                        * are not forcing a redraw. A pad can be displayed
+                        * again without any of the contents changing.
                         */
-                       if (!(win->flags & __ISPAD)) {
+                       if ((!(win->flags & __ISPAD)) ||
+                           ((wlp->flags & __ISFORCED) == __ISFORCED)) {
                                /* Set change pointers on "win". */
                                if (*wlp->firstchp >= win->ch_off)
                                        *wlp->firstchp = maxx + win->ch_off;
@@ -395,9 +404,9 @@
 doupdate(void)
 {
        WINDOW  *win;
-       __LINE  *wlp;
+       __LINE  *wlp, *vlp;
        short    wy;
-       int      dnum;
+       int      dnum, was_cleared;
 #ifdef HAVE_WCHAR
        __LDATA *lp;
        nschar_t *np;
@@ -450,6 +459,7 @@
                }
        }
 
+       was_cleared = 0;
        if ((win->flags & __CLEAROK) || (curscr->flags & __CLEAROK) ||
            _cursesi_screen->curwin) {
                if (curscr->wattr & __COLOR)
@@ -465,6 +475,8 @@
                }
                __touchwin(win);
                win->flags &= ~__CLEAROK;
+               /* note we cleared for later */
+               was_cleared = 1;
        }
        if (!cursor_address) {
                if (win->curx != 0)
@@ -544,6 +556,7 @@
 
        for (wy = 0; wy < win->maxy; wy++) {
                wlp = win->alines[wy];
+               vlp = _cursesi_screen->__virtscr->alines[win->begy + wy];
 /* XXX: remove this debug */
 #ifdef DEBUG
                __CTRACE(__CTRACE_REFRESH,
@@ -552,29 +565,47 @@
 #endif /* DEBUG */
                if (!_cursesi_screen->curwin)
                        curscr->alines[wy]->hash = wlp->hash;
-               if (wlp->flags & __ISDIRTY) {
+               if ((wlp->flags & __ISDIRTY) ||
+                   (wlp->flags & __ISFORCED)) {
 #ifdef DEBUG
                        __CTRACE(__CTRACE_REFRESH,
                            "doupdate: [ISDIRTY]wy:%d\tf:%d\tl:%d\n", wy,
                            *wlp->firstchp, *wlp->lastchp);
 #endif /* DEBUG */
+                       /*
+                       * We have just cleared so don't force an update
+                       * otherwise we spray neeedless blanks to a cleared
+                       * screen.
+                       */
+                       if (was_cleared == 1)
+                               win->alines[wy]->flags &= ~__ISFORCED;
+
                        if (makech(wy) == ERR)
                                return (ERR);
                        else {
                                if (*wlp->firstchp >= 0)
                                        *wlp->firstchp = win->maxx;
                                if (*wlp->lastchp < win->maxx)
-                                       *wlp->lastchp = 0;
+                                       *wlp->lastchp = win->ch_off;
                                if (*wlp->lastchp < *wlp->firstchp) {
 #ifdef DEBUG
                                        __CTRACE(__CTRACE_REFRESH,
                                            "doupdate: line %d notdirty\n", wy);
 #endif /* DEBUG */
-                                       wlp->flags &= ~__ISDIRTY;
+                                       wlp->flags &= ~(__ISDIRTY | __ISFORCED);
                                }
                        }
+               }
 
-               }
+               /*
+                * virtscr is now synced for the line, unset the change
+                * pointers.
+                */
+               if (*vlp->firstchp >= 0)
+                       *vlp->firstchp = _cursesi_screen->__virtscr->maxx;
+               if (*vlp->lastchp <= _cursesi_screen->__virtscr->maxx)
+                       *vlp->lastchp = 0;
+
 #ifdef DEBUG
                __CTRACE(__CTRACE_REFRESH, "\t%d\t%d\n",
                    *wlp->firstchp, *wlp->lastchp);
@@ -641,6 +672,7 @@
        WINDOW  *win;
        static __LDATA blank;
        __LDATA *nsp, *csp, *cp, *cep;
+       __LINE *wlp;
        size_t  clsp, nlsp;     /* Last space in lines. */
        int     lch, wx;
        const char      *ce;
@@ -691,6 +723,7 @@
                _cursesi_screen->ly++;
                _cursesi_screen->lx = 0;
        }
+       wlp = win->alines[wy];
        wx = *win->alines[wy]->firstchp;
        if (wx < 0)
                wx = 0;
@@ -754,7 +787,8 @@
                __CTRACE(__CTRACE_REFRESH, "makech: wx=%d,lch=%d\n", wx, lch);
 #endif /* DEBUG */
 #ifndef HAVE_WCHAR
-               if (memcmp(nsp, csp, sizeof(__LDATA)) == 0) {
+               if (!(wlp->flags & __ISFORCED) && 
+                   (memcmp(nsp, csp, sizeof(__LDATA)) == 0)) {
                        if (wx <= lch) {
                                while (wx <= lch &&
                                    memcmp(nsp, csp, sizeof(__LDATA)) == 0) {
@@ -774,8 +808,9 @@
                __CTRACE(__CTRACE_REFRESH, "makech: csp=(%x,%x,%x,%x,%p)\n",
                        csp->ch, csp->attr, win->bch, win->battr, csp->nsp);
 #endif /* DEBUG */
-               if (((nsp->attr & __WCWIDTH) != __WCWIDTH) &&
-                   cellcmp(nsp, csp)) {
+               if (!(wlp->flags & __ISFORCED) &&
+                    (((nsp->attr & __WCWIDTH) != __WCWIDTH) &&
+                      cellcmp(nsp, csp))) {
                        if (wx <= lch) {
                                while (wx <= lch && cellcmp( csp, nsp )) {
                                        nsp++;
@@ -798,11 +833,13 @@
                _cursesi_screen->ly = wy;
                _cursesi_screen->lx = wx;
 #ifndef HAVE_WCHAR
-               while (wx <= lch && memcmp(nsp, csp, sizeof(__LDATA)) != 0) {
+               while (wx <= lch && (memcmp(nsp, csp, sizeof(__LDATA)) != 0) ||
+                       (wlp->flags & __ISFORCED)) {
                        if (ce != NULL &&
                            wx >= nlsp && nsp->ch == ' ' && nsp->attr == lspc) {
 #else
-               while (!cellcmp(nsp, csp) && wx <= lch) {
+               while ((!cellcmp(nsp, csp) || (wlp->flags & __ISFORCED)) &&
+                       wx <= lch) {
                        if (ce != NULL && wx >= nlsp
                           && nsp->ch == (wchar_t)btowc((int)' ') /* XXX */
                           && (nsp->attr & WA_ATTRIBUTES) == lspc) {
@@ -818,12 +855,18 @@
 #endif /* HAVE_WCHAR */
                                        if (cep-- <= csp)
                                                break;
-                               clsp = cep - curscr->alines[wy]->line -
-                                   win->begx * __LDATASIZE;
+                               if (cep > (curscr->alines[wy]->line + win->begx * __LDATASIZE))
+                                       clsp = cep - curscr->alines[wy]->line -
+                                       win->begx * __LDATASIZE;
+                               else
+                                       clsp = 0;
 #ifdef DEBUG
                                __CTRACE(__CTRACE_REFRESH,
                                    "makech: clsp = %zu, nlsp = %zu\n",
                                    clsp, nlsp);
+                               __CTRACE(__CTRACE_REFRESH,
+                                   "makech: line = %p, cep = %p, begx = %u\n",
+                                   curscr->alines[wy]->line, cep, win->begx);
 #endif
                                if (((clsp - nlsp >= strlen(clr_eol) &&
                                    clsp < win->maxx * __LDATASIZE) ||
diff -r 7c75eb0e13f8 -r 8cd0cd761378 lib/libcurses/touchwin.c
--- a/lib/libcurses/touchwin.c  Fri Dec 06 02:39:58 2013 +0000
+++ b/lib/libcurses/touchwin.c  Fri Dec 06 11:23:47 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: touchwin.c,v 1.26 2010/02/23 19:48:26 drochner Exp $   */
+/*     $NetBSD: touchwin.c,v 1.27 2013/12/06 11:23:47 blymn Exp $      */
 
 /*
  * Copyright (c) 1981, 1993, 1994
@@ -34,13 +34,15 @@
 #if 0
 static char sccsid[] = "@(#)touchwin.c 8.2 (Berkeley) 5/4/94";
 #else
-__RCSID("$NetBSD: touchwin.c,v 1.26 2010/02/23 19:48:26 drochner Exp $");
+__RCSID("$NetBSD: touchwin.c,v 1.27 2013/12/06 11:23:47 blymn Exp $");
 #endif
 #endif                         /* not lint */
 
 #include "curses.h"
 #include "curses_private.h"
 
+static int _cursesi_touchline_force(WINDOW *, int, int, int, int);
+
 /*
  * is_linetouched --
  *     Indicate if line has been touched or not.
@@ -157,7 +159,8 @@
                line = win->maxy - n;
        for (y = line; y < line + n; y++) {
                if (changed == 1)
-                       __touchline(win, y, 0, (int) win->maxx - 1);
+                       _cursesi_touchline_force(win, y, 0,
+                           (int) win->maxx - 1, 1);
                else {
                        wlp = win->alines[y];
                        if (*wlp->firstchp >= win->ch_off &&
@@ -166,13 +169,13 @@
                        if (*wlp->lastchp >= win->ch_off &&
                            *wlp->lastchp < win->maxx + win->ch_off)
                                *wlp->lastchp = win->ch_off;
-                       wlp->flags &= ~__ISDIRTY;
+                       wlp->flags &= ~(__ISDIRTY | __ISFORCED);
                }
        }
 
        return OK;
 }
-               
+
 int
 __touchwin(WINDOW *win)



Home | Main Index | Thread Index | Old Index