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.
This commit is contained in:
parent
f8da61b0f1
commit
d345484675
|
@ -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 @@ _cursesi_wnoutrefresh(SCREEN *screen, WINDOW *win, int begy, int begx,
|
|||
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 @@ _cursesi_wnoutrefresh(SCREEN *screen, WINDOW *win, int begy, int begx,
|
|||
"_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 @@ _cursesi_wnoutrefresh(SCREEN *screen, WINDOW *win, int begy, int begx,
|
|||
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 @@ _cursesi_wnoutrefresh(SCREEN *screen, WINDOW *win, int begy, int begx,
|
|||
#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 @@ int
|
|||
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 @@ doupdate(void)
|
|||
}
|
||||
}
|
||||
|
||||
was_cleared = 0;
|
||||
if ((win->flags & __CLEAROK) || (curscr->flags & __CLEAROK) ||
|
||||
_cursesi_screen->curwin) {
|
||||
if (curscr->wattr & __COLOR)
|
||||
|
@ -465,6 +475,8 @@ doupdate(void)
|
|||
}
|
||||
__touchwin(win);
|
||||
win->flags &= ~__CLEAROK;
|
||||
/* note we cleared for later */
|
||||
was_cleared = 1;
|
||||
}
|
||||
if (!cursor_address) {
|
||||
if (win->curx != 0)
|
||||
|
@ -544,6 +556,7 @@ doupdate(void)
|
|||
|
||||
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 @@ doupdate(void)
|
|||
#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 @@ makech(int wy)
|
|||
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 @@ makech(int wy)
|
|||
_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 @@ makech(int wy)
|
|||
__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 @@ makech(int wy)
|
|||
__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 @@ makech(int wy)
|
|||
_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 @@ makech(int wy)
|
|||
#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) ||
|
||||
|
|
|
@ -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 @@ wtouchln(WINDOW *win, int line, int n, int changed)
|
|||
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 @@ wtouchln(WINDOW *win, int line, int n, int changed)
|
|||
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)
|
||||
{
|
||||
|
@ -189,6 +192,19 @@ __touchwin(WINDOW *win)
|
|||
|
||||
int
|
||||
__touchline(WINDOW *win, int y, int sx, int ex)
|
||||
{
|
||||
return (_cursesi_touchline_force(win, y, sx, ex, 0));
|
||||
}
|
||||
|
||||
/*
|
||||
* Touch line y on window win starting from column sx and ending at
|
||||
* column ex. If force is 1 then we mark this line as a forced update
|
||||
* which will bypass screen optimisation in the refresh code to rewrite
|
||||
* this line unconditionally (even if refresh thinks the screen matches
|
||||
* what is in the virtscr)
|
||||
*/
|
||||
static int
|
||||
_cursesi_touchline_force(WINDOW *win, int y, int sx, int ex, int force)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
__CTRACE(__CTRACE_LINE, "__touchline: (%p, %d, %d, %d)\n",
|
||||
|
@ -198,8 +214,9 @@ __touchline(WINDOW *win, int y, int sx, int ex)
|
|||
#endif
|
||||
sx += win->ch_off;
|
||||
ex += win->ch_off;
|
||||
if (!(win->alines[y]->flags & __ISDIRTY))
|
||||
win->alines[y]->flags |= __ISDIRTY;
|
||||
win->alines[y]->flags |= __ISDIRTY;
|
||||
if (force == 1)
|
||||
win->alines[y]->flags |= __ISFORCED;
|
||||
/* firstchp/lastchp are shared between parent window and sub-window. */
|
||||
if (*win->alines[y]->firstchp > sx)
|
||||
*win->alines[y]->firstchp = sx;
|
||||
|
@ -217,7 +234,7 @@ wsyncup(WINDOW *win)
|
|||
{
|
||||
|
||||
do {
|
||||
touchwin(win);
|
||||
__touchwin(win);
|
||||
win = win->orig;
|
||||
} while (win);
|
||||
}
|
||||
|
@ -229,7 +246,7 @@ wsyncdown(WINDOW *win)
|
|||
|
||||
while (w) {
|
||||
if (is_wintouched(w)) {
|
||||
touchwin(win);
|
||||
__touchwin(win);
|
||||
break;
|
||||
}
|
||||
w = w->orig;
|
||||
|
|
Loading…
Reference in New Issue