Source-Changes-HG archive

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

[src/trunk]: src/lib/libcurses curses: ensure attributes are correctly set fo...



details:   https://anonhg.NetBSD.org/src/rev/113e84d1e0d1
branches:  trunk
changeset: 836520:113e84d1e0d1
user:      roy <roy%NetBSD.org@localhost>
date:      Sun Oct 21 12:47:33 2018 +0000

description:
curses: ensure attributes are correctly set for each character

Another fix for PR# 30978.

diffstat:

 lib/libcurses/refresh.c |  423 +++++++++++++++++++++++++----------------------
 1 files changed, 221 insertions(+), 202 deletions(-)

diffs (truncated from 519 to 300 lines):

diff -r e27f363c9e3f -r 113e84d1e0d1 lib/libcurses/refresh.c
--- a/lib/libcurses/refresh.c   Sun Oct 21 12:26:59 2018 +0000
+++ b/lib/libcurses/refresh.c   Sun Oct 21 12:47:33 2018 +0000
@@ -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 @@
 #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 @@
        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 @@
        __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 @@
 
        /* 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 @@
        }
 
        /* 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 @@
        /* 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 @@
        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 @@
        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 @@
                                ce = NULL;
                        }



Home | Main Index | Thread Index | Old Index