Source-Changes-HG archive

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

[src/trunk]: src/lib/libcurses curses: test terminal capabilities for drawing...



details:   https://anonhg.NetBSD.org/src/rev/192f7274c16c
branches:  trunk
changeset: 836306:192f7274c16c
user:      roy <roy%NetBSD.org@localhost>
date:      Wed Oct 10 09:40:11 2018 +0000

description:
curses: test terminal capabilities for drawing in the bottom right corner

If auto margins are present, we need to turn them off or enter
an insert mode to "push" the character we want into the corner.
If pushing a wide character of greater than one cell, we need something
more than ich1, othewise the bottom right corner will remain blank.

Follow on fix for PR# 30978.

OK jdc@

diffstat:

 lib/libcurses/newwin.c  |   26 +++--
 lib/libcurses/refresh.c |  186 +++++++++++++++++++++++++++++++----------------
 2 files changed, 138 insertions(+), 74 deletions(-)

diffs (truncated from 302 to 300 lines):

diff -r 9c3a7a9bac62 -r 192f7274c16c lib/libcurses/newwin.c
--- a/lib/libcurses/newwin.c    Wed Oct 10 06:16:55 2018 +0000
+++ b/lib/libcurses/newwin.c    Wed Oct 10 09:40:11 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: newwin.c,v 1.53 2018/10/05 11:59:05 roy Exp $  */
+/*     $NetBSD: newwin.c,v 1.54 2018/10/10 09:40:11 roy Exp $  */
 
 /*
  * Copyright (c) 1981, 1993, 1994
@@ -34,7 +34,7 @@
 #if 0
 static char sccsid[] = "@(#)newwin.c   8.3 (Berkeley) 7/27/94";
 #else
-__RCSID("$NetBSD: newwin.c,v 1.53 2018/10/05 11:59:05 roy Exp $");
+__RCSID("$NetBSD: newwin.c,v 1.54 2018/10/10 09:40:11 roy Exp $");
 #endif
 #endif                         /* not lint */
 
@@ -416,20 +416,24 @@
 void
 __swflags(WINDOW *win)
 {
+       TERMINAL *term = win->screen->term;
 
        win->flags &= ~(__ENDLINE | __FULLWIN | __SCROLLWIN | __LEAVEOK);
-       if (win->begx + win->maxx == COLS && !(win->flags & __ISPAD)) {
+       if (win->begx + win->maxx == win->screen->COLS &&
+           !(win->flags & __ISPAD))
+       {
                win->flags |= __ENDLINE;
-               if (win->begx == 0 && win->maxy == LINES && win->begy == 0)
+               if (win->begx == 0 &&
+                   win->maxy == win->screen->LINES &&
+                   win->begy == 0)
                        win->flags |= __FULLWIN;
-               /*
-                * Enable this if we have a terminfo setting which claims
-                * terminal will scroll. Currently there is none.
-                */
-#if 0
-               if (win->begy + win->maxy == LINES)
+               if (win->begy + win->maxy == win->screen->LINES &&
+                   t_auto_right_margin(term) &&
+                   !(t_insert_character(term) != NULL ||
+                   t_parm_ich(term) != NULL ||
+                   (t_enter_insert_mode(term) != NULL &&
+                    t_exit_insert_mode(term) != NULL)))
                        win->flags |= __SCROLLWIN;
-#endif
        }
 }
 
diff -r 9c3a7a9bac62 -r 192f7274c16c lib/libcurses/refresh.c
--- a/lib/libcurses/refresh.c   Wed Oct 10 06:16:55 2018 +0000
+++ b/lib/libcurses/refresh.c   Wed Oct 10 09:40:11 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: refresh.c,v 1.89 2018/10/05 11:59:05 roy Exp $ */
+/*     $NetBSD: refresh.c,v 1.90 2018/10/10 09:40:11 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.89 2018/10/05 11:59:05 roy Exp $");
+__RCSID("$NetBSD: refresh.c,v 1.90 2018/10/10 09:40:11 roy Exp $");
 #endif
 #endif                         /* not lint */
 
@@ -772,6 +772,102 @@
        return fflush(_cursesi_screen->outfd) == EOF ? ERR : OK;
 }
 
+static int
+putch(__LDATA *nsp, __LDATA *csp, int wy, int wx)
+{
+
+       if (!_cursesi_screen->curwin && csp) {
+               csp->attr = nsp->attr;
+               csp->ch = nsp->ch;
+#ifdef HAVE_WCHAR
+               if (_cursesi_copy_nsp(nsp->nsp, csp) == ERR)
+                       return ERR;
+#endif /* HAVE_WCHAR */
+       }
+
+#ifndef HAVE_WCHAR
+       __cputchar((int)nsp->ch);
+#else
+       if (WCOL(*nsp) <= 0)
+               return OK;
+       __cputwchar((int)nsp->ch);
+#ifdef DEBUG
+       __CTRACE(__CTRACE_REFRESH,
+           "makech: (%d,%d)putwchar(0x%x)\n", wy, wx - 1, nsp->ch);
+#endif /* DEBUG */
+
+       /* Output non-spacing characters for the cell. */
+       __cursesi_putnsp(nsp->nsp, wy, wx);
+#endif /* HAVE_WCHAR */
+
+       return OK;
+}
+
+static int
+putchbr(__LDATA *nsp, __LDATA *csp, __LDATA *psp, int wy, int wx)
+{
+       int error, cw, pcw;
+
+       /* Can safely print to bottom right corner. */
+       if (!auto_right_margin)
+               return putch(nsp, csp, wy, wx);
+
+       /* Disable auto margins temporarily. */
+       if (enter_am_mode && exit_am_mode) {
+               tputs(enter_am_mode, 0, __cputchar);
+               error = putch(nsp, csp, wy, wx);
+               tputs(exit_am_mode, 0, __cputchar);
+               return error;
+       }
+
+       /* We need to insert characters.
+        * To do this, work out their widths. */
+#ifdef HAVE_WCHAR
+       cw = wcwidth(nsp->ch);
+       pcw = psp == NULL ? 0 : wcwidth(psp->ch);
+       if (pcw < 1)
+               return ERR; /* Nothing to insert */
+
+       /* When wide characters we need something other than
+        * insert_character. */
+       if (pcw > 1 &&
+           !(parm_ich != NULL ||
+           (enter_insert_mode != NULL && exit_insert_mode != NULL)))
+               return ERR;
+#else
+       cw = pcw = 1;
+#endif /* HAVE_WCHAR */
+
+       /* Write the corner character at wx - pcw. */
+       __mvcur(wy, wx, wy, wx - pcw, 1);
+       if (putch(nsp, csp, wy, wx) == ERR)
+               return ERR;
+
+       /* Move cursor back. */
+       __mvcur(wy, wx - pcw + cw, wy, wx - cw, 1);
+
+       /* Enter insert mode. */
+       if (pcw == 1 && insert_character != NULL)
+               tputs(insert_character, 0, __cputchar);
+       else if (parm_ich != NULL)
+               tputs(tiparm(parm_ich, (long)pcw), 0, __cputchar);
+       else if (enter_insert_mode != NULL && exit_insert_mode != NULL)
+               tputs(enter_insert_mode, 0, __cputchar);
+       else
+               return ERR;
+
+       /* Insert the old character back. */
+       error = putch(psp, NULL, wy, wx - pcw);
+
+       /* Exit insert mode. */
+       if (insert_character != NULL || parm_ich != NULL)
+               ;
+       else if (enter_insert_mode != NULL && exit_insert_mode != NULL)
+               tputs(exit_insert_mode, 0, __cputchar);
+
+       return error;
+}
+
 /*
  * makech --
  *     Make a change on the screen.
@@ -781,10 +877,10 @@
 {
        WINDOW  *win;
        static __LDATA blank;
-       __LDATA *nsp, *csp, *cp, *cep;
+       __LDATA *nsp, *csp, *cp, *cep, *fsp;
        __LINE *wlp;
        size_t  clsp, nlsp;     /* Last space in lines. */
-       int     lch, wx;
+       int     lch, wx, chw;
        const char      *ce;
        attr_t  lspc;           /* Last space colour */
        attr_t  off, on;
@@ -860,7 +956,7 @@
 #endif /* DEBUG */
        }
 
-       nsp = &win->alines[wy]->line[wx];
+       nsp = fsp = &win->alines[wy]->line[wx];
 #ifdef DEBUG
        if (_cursesi_screen->curwin)
                __CTRACE(__CTRACE_REFRESH,
@@ -1205,41 +1301,28 @@
                                curscr->wattr |= __ALTCHARSET;
                        }
 
-                       wx++;
-                       if (wx >= win->maxx &&
+#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) {
                                if (win->flags & __ENDLINE)
                                        __unsetattr(1);
                                if (!(win->flags & __SCROLLWIN)) {
-                                       if (!_cursesi_screen->curwin) {
-                                               csp->attr = nsp->attr;
-                                               csp->ch = nsp->ch;
-#ifdef HAVE_WCHAR
-                                               if (_cursesi_copy_nsp(nsp->nsp, csp) == ERR)
-                                                       return ERR;
-#endif /* HAVE_WCHAR */
-                                       }
-#ifndef HAVE_WCHAR
-                                       __cputchar((int) nsp->ch);
-#else
-                                       if ( WCOL( *nsp ) > 0 ) {
-                                               __cputwchar((int)nsp->ch);
-#ifdef DEBUG
-                                               __CTRACE(__CTRACE_REFRESH,
-                                                   "makech: (%d,%d)putwchar(0x%x)\n",
-                                                       wy, wx - 1,
-                                                       nsp->ch );
-#endif /* DEBUG */
-                                               /*
-                                                * Output non-spacing
-                                                * characters for the
-                                                * cell.
-                                                */
-                                               __cursesi_putnsp(nsp->nsp, wy, wx);
-                                       }
-#endif /* HAVE_WCHAR */
+                                       int e;
+
+                                       if (win->flags & __SCROLLOK)
+                                               e = putch(nsp, csp, wy, wx);
+                                       else
+                                               e = putchbr(nsp, csp,
+                                                   nsp == fsp ? NULL : nsp - 1,
+                                                   wy, wx);
+                                       if (e == ERR)
+                                               return ERR;
                                }
-                               if (wx < curscr->maxx) {
+                               if (wx + chw < curscr->maxx) {
                                        domvcur(win,
                                            _cursesi_screen->ly, wx,
                                            (int)(win->maxy - 1),
@@ -1249,42 +1332,19 @@
                                _cursesi_screen->lx = win->maxx - 1;
                                return OK;
                        }
-                       if (wx < win->maxx || wy < win->maxy - 1 ||
+                       if (wx + chw < win->maxx || wy < win->maxy - 1 ||
                            !(win->flags & __SCROLLWIN))
                        {
-                               if (!_cursesi_screen->curwin) {
-                                       csp->attr = nsp->attr;
-                                       csp->ch = nsp->ch;
-#ifdef HAVE_WCHAR
-                                       if (_cursesi_copy_nsp(nsp->nsp,
-                                                             csp) == ERR)
-                                               return ERR;
-#endif /* HAVE_WCHAR */
-                                       csp++;
-                               }
-#ifndef HAVE_WCHAR
-                               __cputchar((int)nsp->ch);
-#ifdef DEBUG
-                               __CTRACE(__CTRACE_REFRESH,
-                                   "makech: putchar(%c)\n", nsp->ch & 0177);
-#endif
-#else
-                               if (WCOL(*nsp) > 0) {
-                                       __cputwchar((int)nsp->ch);
-#ifdef DEBUG
-                                       __CTRACE(__CTRACE_REFRESH,
-                                           "makech:(%d,%d) putwchar(%x)\n",
-                                           wy, wx - 1, nsp->ch);
-                                       __cursesi_putnsp(nsp->nsp, wy, wx);
-#endif /* DEBUG */
-                               }
-#endif /* HAVE_WCHAR */
+                               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);
                        }
+                       wx += chw;
                        nsp++;



Home | Main Index | Thread Index | Old Index