Module Name: src
Committed By: blymn
Date: Tue Apr 19 22:26:57 UTC 2022
Modified Files:
src/lib/libcurses: background.c curses.c curses_private.h refresh.c
Log Message:
fix for PR 55496
* Fix bkgrndset so that it actually sets the background character in
in line with the SUSv2 specification.
* Add an internal function to copy a complex character
* Make the previously static celleq function into a libcurses private
function so that it can be called in other files.
To generate a diff of this commit:
cvs rdiff -u -r1.29 -r1.30 src/lib/libcurses/background.c
cvs rdiff -u -r1.28 -r1.29 src/lib/libcurses/curses.c
cvs rdiff -u -r1.78 -r1.79 src/lib/libcurses/curses_private.h
cvs rdiff -u -r1.121 -r1.122 src/lib/libcurses/refresh.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/lib/libcurses/background.c
diff -u src/lib/libcurses/background.c:1.29 src/lib/libcurses/background.c:1.30
--- src/lib/libcurses/background.c:1.29 Tue Apr 12 07:03:04 2022
+++ src/lib/libcurses/background.c Tue Apr 19 22:26:57 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: background.c,v 1.29 2022/04/12 07:03:04 blymn Exp $ */
+/* $NetBSD: background.c,v 1.30 2022/04/19 22:26:57 blymn Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: background.c,v 1.29 2022/04/12 07:03:04 blymn Exp $");
+__RCSID("$NetBSD: background.c,v 1.30 2022/04/19 22:26:57 blymn Exp $");
#endif /* not lint */
#include <stdlib.h>
@@ -160,7 +160,9 @@ wbkgrndset(WINDOW *win, const cchar_t *w
{
attr_t battr;
nschar_t *np, *tnp;
- int i;
+ int i, wy, wx;
+ __LDATA obkgrnd, nbkgrnd;
+ __LINE *wlp;
__CTRACE(__CTRACE_ATTR, "wbkgrndset: (%p), '%s', %x\n",
win, (const char *)wunctrl(wch), wch->attributes);
@@ -169,6 +171,14 @@ wbkgrndset(WINDOW *win, const cchar_t *w
if (!wch->elements || wcwidth(wch->vals[0]) > 1)
return;
+ /* get a copy of the old background, we will need it. */
+ obkgrnd.ch = win->bch;
+ obkgrnd.attr = win->battr;
+ obkgrnd.wflags = 0;
+ obkgrnd.wcols = win->wcols;
+ obkgrnd.nsp = NULL;
+ _cursesi_copy_nsp(win->bnsp, &obkgrnd);
+
/* Background character. */
tnp = np = win->bnsp;
if (wcwidth( wch->vals[0]))
@@ -204,11 +214,7 @@ wbkgrndset(WINDOW *win, const cchar_t *w
}
}
/* clear the old non-spacing characters */
- while (np) {
- tnp = np->next;
- free(np);
- np = tnp;
- }
+ __cursesi_free_nsp(np);
/* Background attributes (check colour). */
battr = wch->attributes & WA_ATTRIBUTES;
@@ -216,6 +222,29 @@ wbkgrndset(WINDOW *win, const cchar_t *w
battr |= __default_color;
win->battr = battr;
win->wcols = 1;
+
+ /*
+ * Now do the dirty work of updating all the locations
+ * that have the old background character with the new.
+ */
+
+ nbkgrnd.ch = win->bch;
+ nbkgrnd.attr = win->battr;
+ nbkgrnd.wflags = 0;
+ nbkgrnd.wcols = win->wcols;
+ nbkgrnd.nsp = NULL;
+ _cursesi_copy_nsp(win->bnsp, &nbkgrnd);
+
+ for (wy = 0; wy < win->maxy; wy++) {
+ wlp = win->alines[wy];
+ for (wx = 0; wx < win->maxx; wx++) {
+ if (_cursesi_celleq(&obkgrnd, &wlp->line[wx])) {
+ _cursesi_copy_wchar(&nbkgrnd, &wlp->line[wx]);
+ }
+ }
+ }
+ __touchwin(win, 1);
+
}
Index: src/lib/libcurses/curses.c
diff -u src/lib/libcurses/curses.c:1.28 src/lib/libcurses/curses.c:1.29
--- src/lib/libcurses/curses.c:1.28 Tue Jan 31 09:17:53 2017
+++ src/lib/libcurses/curses.c Tue Apr 19 22:26:57 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: curses.c,v 1.28 2017/01/31 09:17:53 roy Exp $ */
+/* $NetBSD: curses.c,v 1.29 2022/04/19 22:26:57 blymn Exp $ */
/*
* Copyright (c) 1981, 1993, 1994
@@ -35,7 +35,7 @@
#if 0
static char sccsid[] = "@(#)curses.c 8.3 (Berkeley) 5/4/94";
#else
-__RCSID("$NetBSD: curses.c,v 1.28 2017/01/31 09:17:53 roy Exp $");
+__RCSID("$NetBSD: curses.c,v 1.29 2022/04/19 22:26:57 blymn Exp $");
#endif
#endif /* not lint */
@@ -77,7 +77,55 @@ char __GT; /* Gtty indicates tabs. *
char __NONL; /* Term can't hack LF doing a CR. */
char __UPPERCASE; /* Terminal is uppercase only. */
+/* compare two cells on screen, must have the same foreground/background,
+ * and for wide characters the same sequence of non-spacing characters
+ */
+int
+_cursesi_celleq(__LDATA *x, __LDATA *y)
+{
#ifdef HAVE_WCHAR
+ nschar_t *xnp = x->nsp, *ynp = y->nsp;
+#endif /* HAVE_WCHAR */
+ int ret = ( x->ch == y->ch ) && ( x->attr == y->attr );
+
+#ifdef HAVE_WCHAR
+ if (!ret)
+ return 0;
+
+ if (!xnp && !ynp)
+ return 1;
+
+ if ((xnp && !ynp) || (!xnp && ynp))
+ return 0;
+
+ while (xnp && ynp) {
+ if (xnp->ch != ynp->ch)
+ return 0;
+ xnp = xnp->next;
+ ynp = ynp->next;
+ }
+
+ return !xnp && !ynp;
+#else
+ return ret;
+#endif /* HAVE_WCHAR */
+}
+
+#ifdef HAVE_WCHAR
+/*
+ * Copy a complex character from source to destination.
+ *
+ */
+void
+_cursesi_copy_wchar(__LDATA *src, __LDATA *dest)
+{
+ dest->ch = src->ch;
+ dest->attr = src->attr;
+ dest->wflags = src->wflags;
+ dest->wcols = src->wcols;
+ _cursesi_copy_nsp(src->nsp, dest);
+}
+
/*
* Copy the non-spacing character list (src_nsp) to the given character,
* allocate or free storage as required.
Index: src/lib/libcurses/curses_private.h
diff -u src/lib/libcurses/curses_private.h:1.78 src/lib/libcurses/curses_private.h:1.79
--- src/lib/libcurses/curses_private.h:1.78 Tue Apr 12 07:03:04 2022
+++ src/lib/libcurses/curses_private.h Tue Apr 19 22:26:57 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: curses_private.h,v 1.78 2022/04/12 07:03:04 blymn Exp $ */
+/* $NetBSD: curses_private.h,v 1.79 2022/04/19 22:26:57 blymn Exp $ */
/*-
* Copyright (c) 1998-2000 Brett Lymn
@@ -361,10 +361,12 @@ unsigned int __hash_line(const __LDATA
void __id_subwins(WINDOW *);
void __init_getch(SCREEN *);
void __init_acs(SCREEN *);
+int _cursesi_celleq(__LDATA *, __LDATA *);
#ifdef HAVE_WCHAR
void __init_get_wch(SCREEN *);
void __init_wacs(SCREEN *);
int __cputwchar_args( wchar_t, void * );
+void _cursesi_copy_wchar(__LDATA *, __LDATA *);
int _cursesi_copy_nsp(nschar_t *, struct __ldata *);
void __cursesi_free_nsp(nschar_t *);
void __cursesi_win_free_nsp(WINDOW *);
Index: src/lib/libcurses/refresh.c
diff -u src/lib/libcurses/refresh.c:1.121 src/lib/libcurses/refresh.c:1.122
--- src/lib/libcurses/refresh.c:1.121 Wed Apr 13 19:17:09 2022
+++ src/lib/libcurses/refresh.c Tue Apr 19 22:26:57 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: refresh.c,v 1.121 2022/04/13 19:17:09 pgoyette Exp $ */
+/* $NetBSD: refresh.c,v 1.122 2022/04/19 22:26:57 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.121 2022/04/13 19:17:09 pgoyette Exp $");
+__RCSID("$NetBSD: refresh.c,v 1.122 2022/04/19 22:26:57 blymn Exp $");
#endif
#endif /* not lint */
@@ -57,7 +57,6 @@ static void scrolln(int, int, int, int,
static int _wnoutrefresh(WINDOW *, int, int, int, int, int, int);
-static int celleq(__LDATA *, __LDATA *);
static int lineeq(__LDATA *, __LDATA *, size_t);
#define CHECK_INTERVAL 5 /* Change N lines before checking typeahead */
@@ -1174,7 +1173,7 @@ makech(int wy)
|| (__using_color && back_color_erase))) {
cp = &win->alines[wy]->line[win->maxx - 1];
#ifdef HAVE_WCHAR
- while ((celleq(cp, &space) == 1) &&
+ while ((_cursesi_celleq(cp, &space) == 1) &&
#else
while (cp->ch == space.ch &&
#endif /* HAVE_WCHAR */
@@ -1200,7 +1199,7 @@ makech(int wy)
__CTRACE(__CTRACE_REFRESH, "makech: wx=%d,lch=%d\n", wx, lch);
#ifdef HAVE_WCHAR
__CTRACE(__CTRACE_REFRESH, "makech: farnarkle: flags 0x%x, wflags 0x%x, color_init %d, celleq %d\n",
- wlp->flags, nsp->wflags, __do_color_init, celleq(nsp, csp));
+ wlp->flags, nsp->wflags, __do_color_init, _cursesi_celleq(nsp, csp));
__CTRACE(__CTRACE_REFRESH, "makech: nsp=(%x,%x,%d,%x,%x,%d,%p)\n",
nsp->ch, nsp->attr, nsp->wcols, win->bch, win->battr,
win->wcols, nsp->nsp);
@@ -1212,10 +1211,10 @@ makech(int wy)
#ifdef HAVE_WCHAR
((nsp->wflags & WCA_CONTINUATION) != WCA_CONTINUATION) &&
#endif
- celleq(nsp, csp))
+ _cursesi_celleq(nsp, csp))
{
if (wx <= lch) {
- while (wx <= lch && celleq(nsp, csp)) {
+ while (wx <= lch && _cursesi_celleq(nsp, csp)) {
#ifdef HAVE_WCHAR
wx += nsp->wcols;
#else
@@ -1239,7 +1238,7 @@ makech(int wy)
_cursesi_screen->lx = wx;
owx = wx;
while (wx <= lch &&
- ((wlp->flags & __ISFORCED) || !celleq(nsp, csp)))
+ ((wlp->flags & __ISFORCED) || !_cursesi_celleq(nsp, csp)))
{
if ((ce != NULL) && (wx >= nlsp) &&
(nsp->ch == space.ch) &&
@@ -1346,7 +1345,7 @@ makech(int wy)
!(win->flags & __SCROLLWIN))
{
tld = nsp;
- if (celleq(&blank, nsp))
+ if (_cursesi_celleq(&blank, nsp))
tld = ␣
if (putch(tld, csp, wy, wx) == ERR)
@@ -1711,7 +1710,7 @@ done:
if (clp->hash != blank_hash ||
!lineeq(clp->line, clp->line + 1,
(__virtscr->maxx - 1)) ||
- !celleq(clp->line, buf))
+ !_cursesi_celleq(clp->line, buf))
{
for (i = __virtscr->maxx;
i > BLANKSIZE;
@@ -1990,40 +1989,6 @@ __unsetattr(int checkms)
__unset_color(curscr);
}
-/* compare two cells on screen, must have the same foreground/background,
- * and for wide characters the same sequence of non-spacing characters
- */
-static int
-celleq(__LDATA *x, __LDATA *y)
-{
-#ifdef HAVE_WCHAR
- nschar_t *xnp = x->nsp, *ynp = y->nsp;
-#endif /* HAVE_WCHAR */
- int ret = ( x->ch == y->ch ) && ( x->attr == y->attr );
-
-#ifdef HAVE_WCHAR
- if (!ret)
- return 0;
-
- if (!xnp && !ynp)
- return 1;
-
- if ((xnp && !ynp) || (!xnp && ynp))
- return 0;
-
- while (xnp && ynp) {
- if (xnp->ch != ynp->ch)
- return 0;
- xnp = xnp->next;
- ynp = ynp->next;
- }
-
- return !xnp && !ynp;
-#else
- return ret;
-#endif /* HAVE_WCHAR */
-}
-
/* compare two line segments */
static int
lineeq(__LDATA *xl, __LDATA *yl, size_t len)
@@ -2032,7 +1997,7 @@ lineeq(__LDATA *xl, __LDATA *yl, size_t
__LDATA *xp = xl, *yp = yl;
for (i = 0; i < len; i++, xp++, yp++) {
- if (!celleq(xp, yp))
+ if (!_cursesi_celleq(xp, yp))
return 0;
}
return 1;