Module Name: src
Committed By: roy
Date: Sun Oct 21 12:47:33 UTC 2018
Modified Files:
src/lib/libcurses: refresh.c
Log Message:
curses: ensure attributes are correctly set for each character
Another fix for PR# 30978.
To generate a diff of this commit:
cvs rdiff -u -r1.90 -r1.91 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/refresh.c
diff -u src/lib/libcurses/refresh.c:1.90 src/lib/libcurses/refresh.c:1.91
--- src/lib/libcurses/refresh.c:1.90 Wed Oct 10 09:40:11 2018
+++ src/lib/libcurses/refresh.c Sun Oct 21 12:47:33 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: refresh.c,v 1.90 2018/10/10 09:40:11 roy Exp $ */
+/* $NetBSD: refresh.c,v 1.91 2018/10/21 12:47:33 roy 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.90 2018/10/10 09:40:11 roy Exp $");
+__RCSID("$NetBSD: refresh.c,v 1.91 2018/10/21 12:47:33 roy Exp $");
#endif
#endif /* not lint */
@@ -46,6 +46,10 @@ __RCSID("$NetBSD: refresh.c,v 1.90 2018/
#include "curses_private.h"
static void domvcur(const WINDOW *, int, int, int, int);
+static void putattr(__LDATA *);
+static void putattr_out(__LDATA *);
+static int putch(__LDATA *, __LDATA *, int, int);
+static int putchbr(__LDATA *, __LDATA *, __LDATA *, int, int);
static int makech(int);
static void quickch(void);
static void scrolln(int, int, int, int, int);
@@ -772,10 +776,210 @@ cleanup:
return fflush(_cursesi_screen->outfd) == EOF ? ERR : OK;
}
+static void
+putattr(__LDATA *nsp)
+{
+ attr_t off, on;
+
+#ifdef DEBUG
+ __CTRACE(__CTRACE_REFRESH,
+ "makech: have attr %08x, need attr %08x\n",
+ curscr->wattr
+#ifndef HAVE_WCHAR
+ & __ATTRIBUTES
+#else
+ & WA_ATTRIBUTES
+#endif
+ , nsp->attr
+#ifndef HAVE_WCHAR
+ & __ATTRIBUTES
+#else
+ & WA_ATTRIBUTES
+#endif
+ );
+#endif
+
+ off = (~nsp->attr & curscr->wattr)
+#ifndef HAVE_WCHAR
+ & __ATTRIBUTES
+#else
+ & WA_ATTRIBUTES
+#endif
+ ;
+
+ /*
+ * Unset attributes as appropriate. Unset first
+ * so that the relevant attributes can be reset
+ * (because 'me' unsets 'mb', 'md', 'mh', 'mk',
+ * 'mp' and 'mr'). Check to see if we also turn off
+ * standout, attributes and colour.
+ */
+ if (off & __TERMATTR && exit_attribute_mode != NULL) {
+ tputs(exit_attribute_mode, 0, __cputchar);
+ curscr->wattr &= __mask_me;
+ off &= __mask_me;
+ }
+
+ /*
+ * Exit underscore mode if appropriate.
+ * Check to see if we also turn off standout,
+ * attributes and colour.
+ */
+ if (off & __UNDERSCORE && exit_underline_mode != NULL) {
+ tputs(exit_underline_mode, 0, __cputchar);
+ curscr->wattr &= __mask_ue;
+ off &= __mask_ue;
+ }
+
+ /*
+ * Exit standout mode as appropriate.
+ * Check to see if we also turn off underscore,
+ * attributes and colour.
+ * XXX
+ * Should use uc if so/se not available.
+ */
+ if (off & __STANDOUT && exit_standout_mode != NULL) {
+ tputs(exit_standout_mode, 0, __cputchar);
+ curscr->wattr &= __mask_se;
+ off &= __mask_se;
+ }
+
+ if (off & __ALTCHARSET && exit_alt_charset_mode != NULL) {
+ tputs(exit_alt_charset_mode, 0, __cputchar);
+ curscr->wattr &= ~__ALTCHARSET;
+ }
+
+ /* Set/change colour as appropriate. */
+ if (__using_color)
+ __set_color(curscr, nsp->attr & __COLOR);
+
+ on = (nsp->attr & ~curscr->wattr)
+#ifndef HAVE_WCHAR
+ & __ATTRIBUTES
+#else
+ & WA_ATTRIBUTES
+#endif
+ ;
+
+ /*
+ * Enter standout mode if appropriate.
+ */
+ if (on & __STANDOUT &&
+ enter_standout_mode != NULL &&
+ exit_standout_mode != NULL)
+ {
+ tputs(enter_standout_mode, 0, __cputchar);
+ curscr->wattr |= __STANDOUT;
+ }
+
+ /*
+ * Enter underscore mode if appropriate.
+ * XXX
+ * Should use uc if us/ue not available.
+ */
+ if (on & __UNDERSCORE &&
+ enter_underline_mode != NULL &&
+ exit_underline_mode != NULL)
+ {
+ tputs(enter_underline_mode, 0, __cputchar);
+ curscr->wattr |= __UNDERSCORE;
+ }
+
+ /*
+ * Set other attributes as appropriate.
+ */
+ if (exit_attribute_mode != NULL) {
+ if (on & __BLINK && enter_blink_mode != NULL)
+ {
+ tputs(enter_blink_mode, 0, __cputchar);
+ curscr->wattr |= __BLINK;
+ }
+ if (on & __BOLD && enter_bold_mode != NULL)
+ {
+ tputs(enter_bold_mode, 0, __cputchar);
+ curscr->wattr |= __BOLD;
+ }
+ if (on & __DIM && enter_dim_mode != NULL)
+ {
+ tputs(enter_dim_mode, 0, __cputchar);
+ curscr->wattr |= __DIM;
+ }
+ if (on & __BLANK && enter_secure_mode != NULL)
+ {
+ tputs(enter_secure_mode, 0, __cputchar);
+ curscr->wattr |= __BLANK;
+ }
+ if (on & __PROTECT && enter_protected_mode != NULL)
+ {
+ tputs(enter_protected_mode, 0, __cputchar);
+ curscr->wattr |= __PROTECT;
+ }
+ if (on & __REVERSE && enter_reverse_mode != NULL)
+ {
+ tputs(enter_reverse_mode, 0, __cputchar);
+ curscr->wattr |= __REVERSE;
+ }
+#ifdef HAVE_WCHAR
+ if (on & WA_TOP && enter_top_hl_mode != NULL)
+ {
+ tputs(enter_top_hl_mode, 0, __cputchar);
+ curscr->wattr |= WA_TOP;
+ }
+ if (on & WA_LOW && enter_low_hl_mode != NULL)
+ {
+ tputs(enter_low_hl_mode, 0, __cputchar);
+ curscr->wattr |= WA_LOW;
+ }
+ if (on & WA_LEFT && enter_left_hl_mode != NULL)
+ {
+ tputs(enter_left_hl_mode, 0, __cputchar);
+ curscr->wattr |= WA_LEFT;
+ }
+ if (on & WA_RIGHT && enter_right_hl_mode != NULL)
+ {
+ tputs(enter_right_hl_mode, 0, __cputchar);
+ curscr->wattr |= WA_RIGHT;
+ }
+ if (on & WA_HORIZONTAL && enter_horizontal_hl_mode != NULL)
+ {
+ tputs(enter_horizontal_hl_mode, 0, __cputchar);
+ curscr->wattr |= WA_HORIZONTAL;
+ }
+ if (on & WA_VERTICAL && enter_vertical_hl_mode != NULL)
+ {
+ tputs(enter_vertical_hl_mode, 0, __cputchar);
+ curscr->wattr |= WA_VERTICAL;
+ }
+#endif /* HAVE_WCHAR */
+ }
+
+ /* Enter/exit altcharset mode as appropriate. */
+ if (on & __ALTCHARSET && enter_alt_charset_mode != NULL &&
+ exit_alt_charset_mode != NULL) {
+ tputs(enter_alt_charset_mode, 0, __cputchar);
+ curscr->wattr |= __ALTCHARSET;
+ }
+}
+
+static void
+putattr_out(__LDATA *nsp)
+{
+
+ if (underline_char &&
+ ((nsp->attr & __STANDOUT) || (nsp->attr & __UNDERSCORE)))
+ {
+ __cputchar('\b');
+ tputs(underline_char, 0, __cputchar);
+ }
+}
+
static int
putch(__LDATA *nsp, __LDATA *csp, int wy, int wx)
{
+ if (csp != NULL)
+ putattr(nsp);
+
if (!_cursesi_screen->curwin && csp) {
csp->attr = nsp->attr;
csp->ch = nsp->ch;
@@ -789,7 +993,7 @@ putch(__LDATA *nsp, __LDATA *csp, int wy
__cputchar((int)nsp->ch);
#else
if (WCOL(*nsp) <= 0)
- return OK;
+ goto out;
__cputwchar((int)nsp->ch);
#ifdef DEBUG
__CTRACE(__CTRACE_REFRESH,
@@ -798,8 +1002,11 @@ putch(__LDATA *nsp, __LDATA *csp, int wy
/* Output non-spacing characters for the cell. */
__cursesi_putnsp(nsp->nsp, wy, wx);
+out:
#endif /* HAVE_WCHAR */
+ if (csp != NULL)
+ putattr_out(nsp);
return OK;
}
@@ -821,7 +1028,8 @@ putchbr(__LDATA *nsp, __LDATA *csp, __LD
}
/* We need to insert characters.
- * To do this, work out their widths. */
+ * To do this, work out their widths.
+ * XXX This does not work when the bottom right corner is an ACS. */
#ifdef HAVE_WCHAR
cw = wcwidth(nsp->ch);
pcw = psp == NULL ? 0 : wcwidth(psp->ch);
@@ -846,6 +1054,8 @@ putchbr(__LDATA *nsp, __LDATA *csp, __LD
/* Move cursor back. */
__mvcur(wy, wx - pcw + cw, wy, wx - cw, 1);
+ putattr(psp);
+
/* Enter insert mode. */
if (pcw == 1 && insert_character != NULL)
tputs(insert_character, 0, __cputchar);
@@ -865,6 +1075,8 @@ putchbr(__LDATA *nsp, __LDATA *csp, __LD
else if (enter_insert_mode != NULL && exit_insert_mode != NULL)
tputs(exit_insert_mode, 0, __cputchar);
+ putattr_out(psp);
+
return error;
}
@@ -883,7 +1095,6 @@ makech(int wy)
int lch, wx, chw;
const char *ce;
attr_t lspc; /* Last space colour */
- attr_t off, on;
#ifdef __GNUC__
nlsp = lspc = 0; /* XXX gcc -Wuninitialized */
@@ -1110,204 +1321,14 @@ makech(int wy)
ce = NULL;
}
-#ifdef DEBUG
- __CTRACE(__CTRACE_REFRESH,
- "makech: have attr %08x, need attr %08x\n",
- curscr->wattr
-#ifndef HAVE_WCHAR
- & __ATTRIBUTES
-#else
- & WA_ATTRIBUTES
-#endif
- , nsp->attr
-#ifndef HAVE_WCHAR
- & __ATTRIBUTES
-#else
- & WA_ATTRIBUTES
-#endif
- );
-#endif
-
- off = (~nsp->attr & curscr->wattr)
-#ifndef HAVE_WCHAR
- & __ATTRIBUTES
-#else
- & WA_ATTRIBUTES
-#endif
- ;
-
- /*
- * Unset attributes as appropriate. Unset first
- * so that the relevant attributes can be reset
- * (because 'me' unsets 'mb', 'md', 'mh', 'mk',
- * 'mp' and 'mr'). Check to see if we also turn off
- * standout, attributes and colour.
- */
- if (off & __TERMATTR && exit_attribute_mode != NULL) {
- tputs(exit_attribute_mode, 0, __cputchar);
- curscr->wattr &= __mask_me;
- off &= __mask_me;
- }
-
- /*
- * Exit underscore mode if appropriate.
- * Check to see if we also turn off standout,
- * attributes and colour.
- */
- if (off & __UNDERSCORE && exit_underline_mode != NULL) {
- tputs(exit_underline_mode, 0, __cputchar);
- curscr->wattr &= __mask_ue;
- off &= __mask_ue;
- }
-
- /*
- * Exit standout mode as appropriate.
- * Check to see if we also turn off underscore,
- * attributes and colour.
- * XXX
- * Should use uc if so/se not available.
- */
- if (off & __STANDOUT && exit_standout_mode != NULL) {
- tputs(exit_standout_mode, 0, __cputchar);
- curscr->wattr &= __mask_se;
- off &= __mask_se;
- }
-
- if (off & __ALTCHARSET && exit_alt_charset_mode != NULL) {
- tputs(exit_alt_charset_mode, 0, __cputchar);
- curscr->wattr &= ~__ALTCHARSET;
- }
-
- /* Set/change colour as appropriate. */
- if (__using_color)
- __set_color(curscr, nsp->attr & __COLOR);
-
- on = (nsp->attr & ~curscr->wattr)
-#ifndef HAVE_WCHAR
- & __ATTRIBUTES
-#else
- & WA_ATTRIBUTES
-#endif
- ;
-
- /*
- * Enter standout mode if appropriate.
- */
- if (on & __STANDOUT &&
- enter_standout_mode != NULL &&
- exit_standout_mode != NULL)
- {
- tputs(enter_standout_mode, 0, __cputchar);
- curscr->wattr |= __STANDOUT;
- }
-
- /*
- * Enter underscore mode if appropriate.
- * XXX
- * Should use uc if us/ue not available.
- */
- if (on & __UNDERSCORE &&
- enter_underline_mode != NULL &&
- exit_underline_mode != NULL)
- {
- tputs(enter_underline_mode, 0, __cputchar);
- curscr->wattr |= __UNDERSCORE;
- }
-
- /*
- * Set other attributes as appropriate.
- */
- if (exit_attribute_mode != NULL) {
- if (on & __BLINK &&
- enter_blink_mode != NULL)
- {
- tputs(enter_blink_mode, 0, __cputchar);
- curscr->wattr |= __BLINK;
- }
- if (on & __BOLD &&
- enter_bold_mode != NULL)
- {
- tputs(enter_bold_mode, 0, __cputchar);
- curscr->wattr |= __BOLD;
- }
- if (on & __DIM &&
- enter_dim_mode != NULL)
- {
- tputs(enter_dim_mode, 0, __cputchar);
- curscr->wattr |= __DIM;
- }
- if (on & __BLANK &&
- enter_secure_mode != NULL)
- {
- tputs(enter_secure_mode, 0, __cputchar);
- curscr->wattr |= __BLANK;
- }
- if (on & __PROTECT &&
- enter_protected_mode != NULL)
- {
- tputs(enter_protected_mode, 0, __cputchar);
- curscr->wattr |= __PROTECT;
- }
- if (on & __REVERSE &&
- enter_reverse_mode != NULL)
- {
- tputs(enter_reverse_mode, 0, __cputchar);
- curscr->wattr |= __REVERSE;
- }
-#ifdef HAVE_WCHAR
- if (on & WA_TOP &&
- enter_top_hl_mode != NULL)
- {
- tputs(enter_top_hl_mode, 0, __cputchar);
- curscr->wattr |= WA_TOP;
- }
- if (on & WA_LOW &&
- enter_low_hl_mode != NULL)
- {
- tputs(enter_low_hl_mode, 0, __cputchar);
- curscr->wattr |= WA_LOW;
- }
- if (on & WA_LEFT &&
- enter_left_hl_mode != NULL)
- {
- tputs(enter_left_hl_mode, 0, __cputchar);
- curscr->wattr |= WA_LEFT;
- }
- if (on & WA_RIGHT &&
- enter_right_hl_mode != NULL)
- {
- tputs(enter_right_hl_mode, 0, __cputchar);
- curscr->wattr |= WA_RIGHT;
- }
- if (on & WA_HORIZONTAL &&
- enter_horizontal_hl_mode != NULL)
- {
- tputs(enter_horizontal_hl_mode, 0, __cputchar);
- curscr->wattr |= WA_HORIZONTAL;
- }
- if (on & WA_VERTICAL &&
- enter_vertical_hl_mode != NULL)
- {
- tputs(enter_vertical_hl_mode, 0, __cputchar);
- curscr->wattr |= WA_VERTICAL;
- }
-#endif /* HAVE_WCHAR */
- }
-
- /* Enter/exit altcharset mode as appropriate. */
- if (on & __ALTCHARSET && enter_alt_charset_mode != NULL &&
- exit_alt_charset_mode != NULL) {
- tputs(enter_alt_charset_mode, 0, __cputchar);
- curscr->wattr |= __ALTCHARSET;
- }
-
#ifdef HAVE_WCHAR
chw = wcwidth(nsp->ch);
#else
chw = 1;
#endif /* HAVE_WCHAR */
if (wx + chw >= win->maxx &&
- wy == win->maxy - 1 && !_cursesi_screen->curwin) {
+ wy == win->maxy - 1 && !_cursesi_screen->curwin)
+ {
if (win->flags & __ENDLINE)
__unsetattr(1);
if (!(win->flags & __SCROLLWIN)) {
@@ -1338,11 +1359,9 @@ makech(int wy)
if (putch(nsp, csp, wy, wx) == ERR)
return ERR;
csp++;
- }
- if (underline_char && ((nsp->attr & __STANDOUT) ||
- (nsp->attr & __UNDERSCORE))) {
- __cputchar('\b');
- tputs(underline_char, 0, __cputchar);
+ } else {
+ putattr(nsp);
+ putattr_out(nsp);
}
wx += chw;
nsp++;