Module Name: src Committed By: blymn Date: Tue Jan 25 03:05:06 UTC 2022
Modified Files: src/lib/libcurses: add_wchstr.c addbytes.c background.c border.c clrtobot.c clrtoeol.c cr_put.c curses_private.h delch.c erase.c in_wch.c in_wchstr.c ins_wch.c ins_wstr.c insch.c insdelln.c insstr.c inwstr.c newwin.c refresh.c resize.c slk.c Log Message: Correct (hopefully) the handling of wide characters. * Remove the WCOL family of macros, these were "stealing" the upper bits of a character attribute to store the column width of a character. No warning was given about this in curses.h which meant it was easy to accidentally reuse the bits in use by the WCOL macros (we already did). Add couple of 16bit ints to the character structure iff HAVE_WCHAR is true to hold the display width and wide char related flags (just continuation at the moment) * Convert all instances of WCOL macros to just reference the column width in the char structure so it is not obfuscated. * Fix cursor positioning so placing a cursor in the middle of a wide char actually does just that. * Fix plod so it understands that if the cursor is going to be positioned in the middle of a wide char it cannot just reprint the char to get there. * Fix plodput so it correctly counts the number of output characters for wide characters. * Fix slk routines to properly size the wctomb() buffer. To generate a diff of this commit: cvs rdiff -u -r1.10 -r1.11 src/lib/libcurses/add_wchstr.c cvs rdiff -u -r1.60 -r1.61 src/lib/libcurses/addbytes.c cvs rdiff -u -r1.27 -r1.28 src/lib/libcurses/background.c \ src/lib/libcurses/clrtobot.c cvs rdiff -u -r1.21 -r1.22 src/lib/libcurses/border.c \ src/lib/libcurses/ins_wstr.c cvs rdiff -u -r1.32 -r1.33 src/lib/libcurses/clrtoeol.c cvs rdiff -u -r1.37 -r1.38 src/lib/libcurses/cr_put.c cvs rdiff -u -r1.76 -r1.77 src/lib/libcurses/curses_private.h cvs rdiff -u -r1.26 -r1.27 src/lib/libcurses/delch.c \ src/lib/libcurses/insch.c cvs rdiff -u -r1.33 -r1.34 src/lib/libcurses/erase.c \ src/lib/libcurses/resize.c cvs rdiff -u -r1.7 -r1.8 src/lib/libcurses/in_wch.c cvs rdiff -u -r1.9 -r1.10 src/lib/libcurses/in_wchstr.c \ src/lib/libcurses/insstr.c src/lib/libcurses/inwstr.c cvs rdiff -u -r1.17 -r1.18 src/lib/libcurses/ins_wch.c cvs rdiff -u -r1.19 -r1.20 src/lib/libcurses/insdelln.c cvs rdiff -u -r1.63 -r1.64 src/lib/libcurses/newwin.c cvs rdiff -u -r1.117 -r1.118 src/lib/libcurses/refresh.c cvs rdiff -u -r1.18 -r1.19 src/lib/libcurses/slk.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/add_wchstr.c diff -u src/lib/libcurses/add_wchstr.c:1.10 src/lib/libcurses/add_wchstr.c:1.11 --- src/lib/libcurses/add_wchstr.c:1.10 Mon Sep 6 07:45:48 2021 +++ src/lib/libcurses/add_wchstr.c Tue Jan 25 03:05:06 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: add_wchstr.c,v 1.10 2021/09/06 07:45:48 rin Exp $ */ +/* $NetBSD: add_wchstr.c,v 1.11 2022/01/25 03:05:06 blymn Exp $ */ /* * Copyright (c) 2005 The NetBSD Foundation Inc. @@ -36,7 +36,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: add_wchstr.c,v 1.10 2021/09/06 07:45:48 rin Exp $"); +__RCSID("$NetBSD: add_wchstr.c,v 1.11 2022/01/25 03:05:06 blymn Exp $"); #endif /* not lint */ #include <stdlib.h> @@ -163,7 +163,7 @@ wadd_wchnstr(WINDOW *win, const cchar_t lp = &win->alines[y]->line[x]; lnp = win->alines[y]; - cw = WCOL(*lp); + cw = (*lp).wcols; if (cw >= 0) { sx = x; } else { @@ -174,7 +174,7 @@ wadd_wchnstr(WINDOW *win, const cchar_t if (_cursesi_copy_nsp(win->bnsp, tp) == ERR) return ERR; tp->attr = win->battr; - SET_WCOL(*tp, 1); + (*tp).wcols = 1; np = tp->nsp; } } else { @@ -211,7 +211,7 @@ wadd_wchnstr(WINDOW *win, const cchar_t == ERR) return ERR; lp->attr = win->battr; - SET_WCOL(*lp, 1); + (*lp).wcols = 1; lp++, ex++; } ex = win->maxx - 1; @@ -230,7 +230,7 @@ wadd_wchnstr(WINDOW *win, const cchar_t } lp->ch = chp->vals[0]; lp->attr = chp->attributes & WA_ATTRIBUTES; - SET_WCOL(*lp, cw); + (*lp).wcols = cw; if (chp->elements > 1) { for (i = 1; i < chp->elements; i++) { np = (nschar_t *) @@ -258,7 +258,7 @@ wadd_wchnstr(WINDOW *win, const cchar_t } lp->ch = chp->vals[0]; lp->attr = chp->attributes & WA_ATTRIBUTES; - SET_WCOL(*lp, x - ex); + (*lp).wcols = x - ex; lp++, ex++; } } else { Index: src/lib/libcurses/addbytes.c diff -u src/lib/libcurses/addbytes.c:1.60 src/lib/libcurses/addbytes.c:1.61 --- src/lib/libcurses/addbytes.c:1.60 Sun Jan 16 10:30:45 2022 +++ src/lib/libcurses/addbytes.c Tue Jan 25 03:05:06 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: addbytes.c,v 1.60 2022/01/16 10:30:45 rillig Exp $ */ +/* $NetBSD: addbytes.c,v 1.61 2022/01/25 03:05:06 blymn Exp $ */ /* * Copyright (c) 1987, 1993, 1994 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)addbytes.c 8.4 (Berkeley) 5/4/94"; #else -__RCSID("$NetBSD: addbytes.c,v 1.60 2022/01/16 10:30:45 rillig Exp $"); +__RCSID("$NetBSD: addbytes.c,v 1.61 2022/01/25 03:05:06 blymn Exp $"); #endif #endif /* not lint */ @@ -203,7 +203,7 @@ _cursesi_addbyte(WINDOW *win, __LINE **l { static char blank[] = " "; int tabsize; - int newx, i; + int newx, i, wcols; attr_t attributes; if (char_interp) { @@ -275,6 +275,11 @@ _cursesi_addbyte(WINDOW *win, __LINE **l else if (win->wattr & __COLOR) attributes |= win->wattr & __COLOR; + + wcols = wcwidth(c); + if (wcols < 0) + wcols = 1; + /* * Always update the change pointers. Otherwise, * we could end up not displaying 'blank' characters @@ -294,10 +299,17 @@ _cursesi_addbyte(WINDOW *win, __LINE **l *(*lp)->firstchp, *(*lp)->lastchp, *(*lp)->firstchp - win->ch_off, *(*lp)->lastchp - win->ch_off); - if (win->bch != ' ' && c == ' ') + if (win->bch != ' ' && c == ' ') { (*lp)->line[*x].ch = win->bch; - else +#ifdef HAVE_CHAR + (*lp)->line[*x].wcols = win->wcols; +#endif + } else { (*lp)->line[*x].ch = c; +#ifdef HAVE_CHAR + (*lp)->line[*x].wcols = wcols; +#endif + } if (attributes & __COLOR) (*lp)->line[*x].attr = @@ -391,7 +403,7 @@ _cursesi_addwchar(WINDOW *win, __LINE ** __CTRACE(__CTRACE_INPUT, "_cursesi_addwchar: char '%c' is non-spacing\n", wch->vals[0]); - cw = WCOL(*lp); + cw = (*lp).wcols; if (cw < 0) { lp += cw; *x += cw; @@ -427,7 +439,7 @@ _cursesi_addwchar(WINDOW *win, __LINE ** lp = &win->alines[*y]->line[*x]; } /* clear out the current character */ - cw = WCOL(*lp); + cw = (*lp).wcols; if (cw >= 0) { sx = *x; } else { @@ -441,7 +453,7 @@ _cursesi_addwchar(WINDOW *win, __LINE ** return ERR; tp->attr = win->battr; - SET_WCOL(*tp, 1); + tp->wcols = win->wcols; } sx = *x + cw; (*lnp)->flags |= __ISDIRTY; @@ -473,7 +485,7 @@ _cursesi_addwchar(WINDOW *win, __LINE ** if (_cursesi_copy_nsp(win->bnsp, tp) == ERR) return ERR; tp->attr = win->battr; - SET_WCOL(*tp, 1); + tp->wcols = win->wcols; } newx = win->maxx - 1 + win->ch_off; if (newx > *(*lnp)->lastchp) @@ -513,11 +525,11 @@ _cursesi_addwchar(WINDOW *win, __LINE ** else lp->attr = attributes | win->battr; - SET_WCOL(*lp, cw); + lp->wcols = cw; __CTRACE(__CTRACE_INPUT, - "_cursesi_addwchar: add spacing char 0x%x, attr 0x%x\n", - lp->ch, lp->attr); + "_cursesi_addwchar: add spacing char 0x%x, attr 0x%x, width %d\n", + lp->ch, lp->attr, lp->wcols); if (wch->elements > 1) { for (i = 1; i < wch->elements; i++) { @@ -547,10 +559,11 @@ _cursesi_addwchar(WINDOW *win, __LINE ** tp->ch = wch->vals[0]; tp->attr = lp->attr & WA_ATTRIBUTES; /* Mark as "continuation" cell */ - tp->attr |= __WCWIDTH; + tp->wflags |= WCA_CONTINUATION; } - if (*x == win->maxx) { + + if (*x >= win->maxx) { __CTRACE(__CTRACE_INPUT, "_cursesi_addwchar: do line wrap\n"); if (*y == win->scr_b) { __CTRACE(__CTRACE_INPUT, @@ -577,7 +590,7 @@ _cursesi_addwchar(WINDOW *win, __LINE ** if (*x && *x < win->maxx) { ex = sx + cw; tp = &win->alines[*y]->line[ex]; - while (ex < win->maxx && WCOL(*tp) < 0) { + while (ex < win->maxx && tp->wcols < 0) { __CTRACE(__CTRACE_INPUT, "_cursesi_addwchar: clear " "remaining of current char (%d,%d)nn", @@ -586,7 +599,7 @@ _cursesi_addwchar(WINDOW *win, __LINE ** if (_cursesi_copy_nsp(win->bnsp, tp) == ERR) return ERR; tp->attr = win->battr; - SET_WCOL(*tp, 1); + tp->wcols = win->wcols; tp++, ex++; } newx = ex - 1 + win->ch_off; Index: src/lib/libcurses/background.c diff -u src/lib/libcurses/background.c:1.27 src/lib/libcurses/background.c:1.28 --- src/lib/libcurses/background.c:1.27 Mon Sep 6 07:45:48 2021 +++ src/lib/libcurses/background.c Tue Jan 25 03:05:06 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: background.c,v 1.27 2021/09/06 07:45:48 rin Exp $ */ +/* $NetBSD: background.c,v 1.28 2022/01/25 03:05:06 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.27 2021/09/06 07:45:48 rin Exp $"); +__RCSID("$NetBSD: background.c,v 1.28 2022/01/25 03:05:06 blymn Exp $"); #endif /* not lint */ #include <stdlib.h> @@ -106,7 +106,7 @@ wbkgd(WINDOW *win, chtype ch) /* Update/merge attributes */ cp->attr = win->battr | (cp->attr & __ALTCHARSET); #ifdef HAVE_WCHAR - SET_WCOL(*cp, 1); + cp->wcols = 1; #endif } } @@ -215,7 +215,7 @@ wbkgrndset(WINDOW *win, const cchar_t *w if (__using_color && !( battr & __COLOR)) battr |= __default_color; win->battr = battr; - SET_BGWCOL((*win), 1); + win->wcols = 1; } Index: src/lib/libcurses/clrtobot.c diff -u src/lib/libcurses/clrtobot.c:1.27 src/lib/libcurses/clrtobot.c:1.28 --- src/lib/libcurses/clrtobot.c:1.27 Sun Mar 15 01:18:43 2020 +++ src/lib/libcurses/clrtobot.c Tue Jan 25 03:05:06 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: clrtobot.c,v 1.27 2020/03/15 01:18:43 uwe Exp $ */ +/* $NetBSD: clrtobot.c,v 1.28 2022/01/25 03:05:06 blymn Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)clrtobot.c 8.2 (Berkeley) 5/4/94"; #else -__RCSID("$NetBSD: clrtobot.c,v 1.27 2020/03/15 01:18:43 uwe Exp $"); +__RCSID("$NetBSD: clrtobot.c,v 1.28 2022/01/25 03:05:06 blymn Exp $"); #endif #endif /* not lint */ @@ -105,7 +105,7 @@ wclrtobot(WINDOW *win) #ifdef HAVE_WCHAR if (_cursesi_copy_nsp(win->bnsp, sp) == ERR) return ERR; - SET_WCOL(*sp, 1); + sp->wcols = 1; #endif } Index: src/lib/libcurses/border.c diff -u src/lib/libcurses/border.c:1.21 src/lib/libcurses/border.c:1.22 --- src/lib/libcurses/border.c:1.21 Tue Oct 19 06:41:03 2021 +++ src/lib/libcurses/border.c Tue Jan 25 03:05:06 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: border.c,v 1.21 2021/10/19 06:41:03 blymn Exp $ */ +/* $NetBSD: border.c,v 1.22 2022/01/25 03:05:06 blymn Exp $ */ /* * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: border.c,v 1.21 2021/10/19 06:41:03 blymn Exp $"); +__RCSID("$NetBSD: border.c,v 1.22 2022/01/25 03:05:06 blymn Exp $"); #endif /* not lint */ #include <stdlib.h> @@ -312,9 +312,9 @@ int wborder_set(WINDOW *win, const cchar win->alines[i]->line[j].nsp = NULL; } if (j) - SET_WCOL(win->alines[i]->line[j], -j); + win->alines[i]->line[j].wcols = -j; else { - SET_WCOL(win->alines[i]->line[j], cw); + win->alines[i]->line[j].wcols = cw; if (left.elements > 1) { for (k = 1; k < left.elements; k++) { np = malloc(sizeof(nschar_t)); @@ -328,20 +328,20 @@ int wborder_set(WINDOW *win, const cchar } } } - for (j = cw; WCOL(win->alines[i]->line[j]) < 0; j++) { + for (j = cw; win->alines[i]->line[j].wcols < 0; j++) { __CTRACE(__CTRACE_INPUT, "wborder_set: clean out partial char[%d]", j); win->alines[i]->line[j].ch = ( wchar_t )btowc(win->bch); if (_cursesi_copy_nsp(win->bnsp, &win->alines[i]->line[j]) == ERR) return ERR; - SET_WCOL(win->alines[i]->line[j], 1); + win->alines[i]->line[j].wcols = 1; } /* right border */ cw = wcwidth(right.vals[0]); if (cw < 0) cw = 1; - pcw = WCOL( win->alines[i]->line[endx - cw]); + pcw = win->alines[i]->line[endx - cw].wcols; for ( j = endx - cw + 1; j <= endx; j++ ) { win->alines[i]->line[j].ch = right.vals[0]; win->alines[i]->line[j].attr = right.attributes; @@ -355,7 +355,7 @@ int wborder_set(WINDOW *win, const cchar win->alines[i]->line[j].nsp = NULL; } if (j == endx - cw + 1) { - SET_WCOL(win->alines[i]->line[j], cw); + win->alines[i]->line[j].wcols = cw; if (right.elements > 1) { for (k = 1; k < right.elements; k++) { np = malloc(sizeof(nschar_t)); @@ -368,8 +368,8 @@ int wborder_set(WINDOW *win, const cchar } } } else - SET_WCOL(win->alines[i]->line[j], - endx - cw + 1 - j); + win->alines[i]->line[j].wcols = + endx - cw + 1 - j; } if (pcw != 1) { __CTRACE(__CTRACE_INPUT, @@ -383,7 +383,7 @@ int wborder_set(WINDOW *win, const cchar &win->alines[i]->line[j]) == ERR) return ERR; win->alines[i]->line[j].attr = win->battr; - SET_WCOL(win->alines[i]->line[j], 1); + win->alines[i]->line[j].wcols = 1; } } } @@ -417,9 +417,9 @@ int wborder_set(WINDOW *win, const cchar win->alines[0]->line[i + j].nsp = NULL; } if (j) - SET_WCOL(win->alines[ 0 ]->line[ i + j ], -j); + win->alines[ 0 ]->line[ i + j ].wcols = -j; else { - SET_WCOL(win->alines[ 0 ]->line[ i + j ], cw); + win->alines[ 0 ]->line[ i + j ].wcols = cw; if ( top.elements > 1 ) { for (k = 1; k < top.elements; k++) { np = malloc(sizeof(nschar_t)); @@ -441,7 +441,7 @@ int wborder_set(WINDOW *win, const cchar &win->alines[0]->line[i]) == ERR) return ERR; win->alines[0]->line[i].attr = win->battr; - SET_WCOL(win->alines[0]->line[i], 1); + win->alines[0]->line[i].wcols = 1; i++; } /* lower border */ @@ -459,9 +459,9 @@ int wborder_set(WINDOW *win, const cchar win->alines[endy]->line[i + j].nsp = NULL; } if (j) - SET_WCOL(win->alines[endy]->line[i + j], -j); + win->alines[endy]->line[i + j].wcols = -j; else { - SET_WCOL(win->alines[endy]->line[i + j], cw); + win->alines[endy]->line[i + j].wcols = cw; if (bottom.elements > 1) { for (k = 1; k < bottom.elements; k++) { np = malloc(sizeof(nschar_t)); @@ -481,7 +481,7 @@ int wborder_set(WINDOW *win, const cchar &win->alines[endy]->line[i]) == ERR) return ERR; win->alines[endy]->line[i].attr = win->battr; - SET_WCOL(win->alines[endy]->line[ i ], 1); + win->alines[endy]->line[i].wcols = 1; i++; } @@ -501,9 +501,9 @@ int wborder_set(WINDOW *win, const cchar win->alines[0]->line[i].nsp = NULL; } if (i) - SET_WCOL(win->alines[0]->line[i], -i); + win->alines[0]->line[i].wcols = -i; else { - SET_WCOL(win->alines[0]->line[i], tlcw); + win->alines[0]->line[i].wcols = tlcw; if (topleft.elements > 1) { for (k = 1; k < topleft.elements; k++) { @@ -530,7 +530,7 @@ int wborder_set(WINDOW *win, const cchar win->alines[0]->line[i].nsp = NULL; } if (i == endx - trcw + 1) { - SET_WCOL(win->alines[0]->line[i], trcw); + win->alines[0]->line[i].wcols = trcw; if (topright.elements > 1) { for (k = 1; k < topright.elements;k ++) { @@ -543,8 +543,8 @@ int wborder_set(WINDOW *win, const cchar } } } else - SET_WCOL(win->alines[0]->line[i], - endx - trcw + 1 - i); + win->alines[0]->line[i].wcols = + endx - trcw + 1 - i; } for (i = 0; i < blcw; i++) { win->alines[endy]->line[i].ch = botleft.vals[0]; @@ -559,9 +559,9 @@ int wborder_set(WINDOW *win, const cchar win->alines[endy]->line[i].nsp = NULL; } if (i) - SET_WCOL(win->alines[endy]->line[i], -i); + win->alines[endy]->line[i].wcols = -i; else { - SET_WCOL(win->alines[endy]->line[i], blcw); + win->alines[endy]->line[i].wcols = blcw; if (botleft.elements > 1) { for (k = 1; k < botleft.elements; k++) { np = malloc(sizeof(nschar_t)); @@ -587,7 +587,7 @@ int wborder_set(WINDOW *win, const cchar win->alines[endy]->line[i].nsp = NULL; } if (i == endx - brcw + 1) { - SET_WCOL(win->alines[endy]->line[i], brcw); + win->alines[endy]->line[i].wcols = brcw; if (botright.elements > 1) { for (k = 1; k < botright.elements; k++){ np = malloc(sizeof(nschar_t)); @@ -599,8 +599,8 @@ int wborder_set(WINDOW *win, const cchar } } } else - SET_WCOL(win->alines[endy]->line[i], - endx - brcw + 1 - i); + win->alines[endy]->line[i].wcols = + endx - brcw + 1 - i; } } __touchwin(win); Index: src/lib/libcurses/ins_wstr.c diff -u src/lib/libcurses/ins_wstr.c:1.21 src/lib/libcurses/ins_wstr.c:1.22 --- src/lib/libcurses/ins_wstr.c:1.21 Sun Jan 16 10:30:45 2022 +++ src/lib/libcurses/ins_wstr.c Tue Jan 25 03:05:06 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: ins_wstr.c,v 1.21 2022/01/16 10:30:45 rillig Exp $ */ +/* $NetBSD: ins_wstr.c,v 1.22 2022/01/25 03:05:06 blymn Exp $ */ /* * Copyright (c) 2005 The NetBSD Foundation Inc. @@ -36,7 +36,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: ins_wstr.c,v 1.21 2022/01/16 10:30:45 rillig Exp $"); +__RCSID("$NetBSD: ins_wstr.c,v 1.22 2022/01/25 03:05:06 blymn Exp $"); #endif /* not lint */ #include <string.h> @@ -280,13 +280,13 @@ loopdone: start = &win->alines[y]->line[x]; sx = x; lnp = win->alines[y]; - pcw = WCOL(*start); + pcw = start->wcols; if (pcw < 0) { sx += pcw; start += pcw; } __CTRACE(__CTRACE_INPUT, "wins_nwstr: start@(%d)\n", sx); - pcw = WCOL(*start); + pcw = start->wcols; lnp->flags |= __ISDIRTY; newx = sx + win->ch_off; if (newx < *lnp->firstchp) @@ -310,7 +310,7 @@ loopdone: __CTRACE(__CTRACE_INPUT, "wins_nwstr: shift all characters by %d\n", width); temp1 = &win->alines[y]->line[win->maxx - 1]; temp2 = temp1 - width; - pcw = WCOL(*(temp2 + 1)); + pcw = (temp2 + 1)->wcols; if (pcw < 0) { __CTRACE(__CTRACE_INPUT, "wins_nwstr: clear from %d to EOL(%d)\n", @@ -323,7 +323,7 @@ loopdone: return ERR; } temp1->attr = win->battr; - SET_WCOL(*temp1, 1); + temp1->wcols = 1; __CTRACE(__CTRACE_INPUT, "wins_nwstr: empty cell(%p)\n", temp1); temp1--; Index: src/lib/libcurses/clrtoeol.c diff -u src/lib/libcurses/clrtoeol.c:1.32 src/lib/libcurses/clrtoeol.c:1.33 --- src/lib/libcurses/clrtoeol.c:1.32 Mon Sep 6 07:03:49 2021 +++ src/lib/libcurses/clrtoeol.c Tue Jan 25 03:05:06 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: clrtoeol.c,v 1.32 2021/09/06 07:03:49 rin Exp $ */ +/* $NetBSD: clrtoeol.c,v 1.33 2022/01/25 03:05:06 blymn Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)clrtoeol.c 8.2 (Berkeley) 5/4/94"; #else -__RCSID("$NetBSD: clrtoeol.c,v 1.32 2021/09/06 07:03:49 rin Exp $"); +__RCSID("$NetBSD: clrtoeol.c,v 1.33 2022/01/25 03:05:06 blymn Exp $"); #endif #endif /* not lint */ @@ -107,7 +107,7 @@ wclrtoeol(WINDOW *win) #ifdef HAVE_WCHAR if (_cursesi_copy_nsp(win->bnsp, sp) == ERR) return ERR; - SET_WCOL(*sp, 1); + sp->wcols = 1; #endif } Index: src/lib/libcurses/cr_put.c diff -u src/lib/libcurses/cr_put.c:1.37 src/lib/libcurses/cr_put.c:1.38 --- src/lib/libcurses/cr_put.c:1.37 Mon Sep 6 07:45:48 2021 +++ src/lib/libcurses/cr_put.c Tue Jan 25 03:05:06 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: cr_put.c,v 1.37 2021/09/06 07:45:48 rin Exp $ */ +/* $NetBSD: cr_put.c,v 1.38 2022/01/25 03:05:06 blymn Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -30,11 +30,13 @@ */ #include <sys/cdefs.h> +#include <limits.h> +#include <stdlib.h> #ifndef lint #if 0 static char sccsid[] = "@(#)cr_put.c 8.3 (Berkeley) 5/4/94"; #else -__RCSID("$NetBSD: cr_put.c,v 1.37 2021/09/06 07:45:48 rin Exp $"); +__RCSID("$NetBSD: cr_put.c,v 1.38 2022/01/25 03:05:06 blymn Exp $"); #endif #endif /* not lint */ @@ -188,18 +190,29 @@ fgoto(int in_refresh) * Otherwise just use cursor motions, hacking use of tabs and overtabbing * and backspace. * - * XXX this needs to be revisited for wide characters since we may output - * XXX more than one byte for a character. */ static int plodcnt, plodflg; +#ifdef HAVE_WCHAR +static char s[MB_LEN_MAX]; +#endif static int plodput(int c) { - if (plodflg) - --plodcnt; - else + if (plodflg) { + int cw; + +#ifdef HAVE_WCHAR + cw = wctomb(s, c); + if (cw < 0) + cw = 1; +#else + cw = 1; +#endif /* HAVE_WCHAR */ + + plodcnt -= cw; + } else __cputchar(c); return 0; } @@ -404,6 +417,21 @@ dontcr:while (outline < destline) { } } } + +#ifdef HAVE_WCHAR + /* + * If destcol is halfway through a multicolumn + * wide char, we have no chance of plodding. + */ + k = outcol - destcol; + if (k < 0) + k = -k; + if ((k != 0) && (curscr->alines[outline]->line[outcol].wcols > k)) { + plodcnt = -1; + goto out; + } +#endif /* HAVE_WCHAR */ + while (outcol < destcol) { /* * Move one char to the right. We don't use nd space because @@ -423,17 +451,17 @@ dontcr:while (outline < destline) { if ((curscr->alines[outline]->line[outcol].attr & WA_ATTRIBUTES) == curscr->wattr) { - switch (WCOL(curscr->alines[outline]->line[outcol])) { + switch (curscr->alines[outline]->line[outcol].wcols) { case 1: __cputwchar(curscr->alines[outline]->line[outcol].ch); __cursesi_putnsp(curscr->alines[outline]->line[outcol].nsp, outline, outcol); __CTRACE(__CTRACE_OUTPUT, - "plod: (%d,%d)WCOL(%d), " + "plod: (%d,%d)wcols(%d), " "putwchar(%x)\n", outline, outcol, - WCOL(curscr->alines[outline]->line[outcol]), + curscr->alines[outline]->line[outcol].wcols, curscr->alines[outline]->line[outcol].ch); /*FALLTHROUGH*/ case 0: Index: src/lib/libcurses/curses_private.h diff -u src/lib/libcurses/curses_private.h:1.76 src/lib/libcurses/curses_private.h:1.77 --- src/lib/libcurses/curses_private.h:1.76 Tue Sep 7 01:23:09 2021 +++ src/lib/libcurses/curses_private.h Tue Jan 25 03:05:06 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: curses_private.h,v 1.76 2021/09/07 01:23:09 rin Exp $ */ +/* $NetBSD: curses_private.h,v 1.77 2022/01/25 03:05:06 blymn Exp $ */ /*- * Copyright (c) 1998-2000 Brett Lymn @@ -72,23 +72,12 @@ struct __ldata { attr_t attr; /* Attributes */ #ifdef HAVE_WCHAR nschar_t *nsp; /* Foreground non-spacing character pointer */ +#define WCA_CONTINUATION 0x0001 /* a continuation cell */ + int16_t wflags; /* internal attributes for wide char */ + int16_t wcols; /* display width of a wide char */ #endif /* HAVE_WCHAR */ }; -#ifdef HAVE_WCHAR -/* macros to extract the width of a wide character */ -#define __WCWIDTH 0xfc000000 -#define WCW_SHIFT 26 -#define WCOL(wc) ((((unsigned) (wc).attr) >> WCW_SHIFT ) > MB_LEN_MAX ? ((int)(((unsigned) (wc).attr ) >> WCW_SHIFT )) - 64 : ((int)(((unsigned) (wc).attr ) >> WCW_SHIFT))) -#define SET_WCOL(c, w) do { \ - ((c).attr) = ((((c).attr) & WA_ATTRIBUTES ) | ((w) << WCW_SHIFT )); \ -} while(/*CONSTCOND*/0) -#define BGWCOL(wc) ((((wc).battr) >> WCW_SHIFT ) > MB_LEN_MAX ? (((wc).battr ) >> WCW_SHIFT ) - 64 : (((wc).battr ) >> WCW_SHIFT )) -#define SET_BGWCOL(c, w) do { \ - ((c).battr) = ((((c).battr) & WA_ATTRIBUTES ) | ((w) << WCW_SHIFT )); \ -} while(/*CONSTCOND*/0) -#endif /* HAVE_WCHAR */ - #define __LDATASIZE (sizeof(__LDATA)) struct __line { @@ -139,6 +128,7 @@ struct __window { /* Window structure. attr_t wattr; /* Character attributes */ wchar_t bch; /* Background character */ attr_t battr; /* Background attributes */ + uint32_t wcols; /* Background column width */ int scr_t, scr_b; /* Scrolling region top, bottom */ SCREEN *screen; /* Screen for this window */ int pbegy, pbegx, @@ -299,15 +289,8 @@ struct __screen { bool slk_hidden; struct __slk_label *slk_labels; -/* - * XXX: This conflicts with the value in <limits.h> (32) - * which should be used here instead of defining a different value, - * but I am not changing it because it is also used in the WCOL() - * macro and I don't understand the effects of it. - */ -#define MB_LEN_MAX 8 +#define MAX_CBUF_SIZE 8 #ifdef HAVE_WCHAR -#define MAX_CBUF_SIZE MB_LEN_MAX int cbuf_head; /* header to cbuf */ int cbuf_tail; /* tail to cbuf */ int cbuf_cur; /* the current char in cbuf */ @@ -351,7 +334,7 @@ void __CTRACE(int, const char *, ...) _ ((_sp)->ch != (_bch) || \ ((_sp)->attr & WA_ATTRIBUTES) != (_battr) || \ (_sp)->nsp != NULL || \ - WCOL(*_sp) < 0) + (_sp)->wcols < 0) #else #define __NEED_ERASE(_sp, _bch, _battr) \ ((_sp)->ch != (_bch) || (_sp)->attr != (_battr)) @@ -442,4 +425,5 @@ extern int __noqch; extern attr_t __mask_op, __mask_me, __mask_ue, __mask_se; extern WINDOW *__virtscr; extern int __using_color; +extern int __do_color_init; extern attr_t __default_color; Index: src/lib/libcurses/delch.c diff -u src/lib/libcurses/delch.c:1.26 src/lib/libcurses/delch.c:1.27 --- src/lib/libcurses/delch.c:1.26 Sun Jun 9 07:40:14 2019 +++ src/lib/libcurses/delch.c Tue Jan 25 03:05:06 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: delch.c,v 1.26 2019/06/09 07:40:14 blymn Exp $ */ +/* $NetBSD: delch.c,v 1.27 2022/01/25 03:05:06 blymn Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)delch.c 8.2 (Berkeley) 5/4/94"; #else -__RCSID("$NetBSD: delch.c,v 1.26 2019/06/09 07:40:14 blymn Exp $"); +__RCSID("$NetBSD: delch.c,v 1.27 2022/01/25 03:05:06 blymn Exp $"); #endif #endif /* not lint */ @@ -111,11 +111,11 @@ wdelch(WINDOW *win) end = &win->alines[win->cury]->line[win->maxx - 1]; sx = win->curx; temp1 = &win->alines[win->cury]->line[win->curx]; - cw = WCOL(*temp1); + cw = temp1->wcols; if (cw < 0) { temp1 += cw; sx += cw; - cw = WCOL(*temp1); + cw = temp1->wcols; } np = temp1->nsp; if (np) { @@ -138,7 +138,7 @@ wdelch(WINDOW *win) temp1->attr = 0; if (_cursesi_copy_nsp(win->bnsp, temp1) == ERR) return ERR; - SET_WCOL(*temp1, 1); + temp1->wcols = 1; temp1++; } __touchline(win, (int)win->cury, sx, (int)win->maxx - 1); Index: src/lib/libcurses/insch.c diff -u src/lib/libcurses/insch.c:1.26 src/lib/libcurses/insch.c:1.27 --- src/lib/libcurses/insch.c:1.26 Mon Jul 6 22:46:50 2020 +++ src/lib/libcurses/insch.c Tue Jan 25 03:05:06 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: insch.c,v 1.26 2020/07/06 22:46:50 uwe Exp $ */ +/* $NetBSD: insch.c,v 1.27 2022/01/25 03:05:06 blymn Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)insch.c 8.2 (Berkeley) 5/4/94"; #else -__RCSID("$NetBSD: insch.c,v 1.26 2020/07/06 22:46:50 uwe Exp $"); +__RCSID("$NetBSD: insch.c,v 1.27 2022/01/25 03:05:06 blymn Exp $"); #endif #endif /* not lint */ @@ -116,7 +116,7 @@ winsch(WINDOW *win, chtype ch) #ifdef HAVE_WCHAR if (_cursesi_copy_nsp(win->bnsp, temp1) == ERR) return ERR; - SET_WCOL(*temp1, 1); + temp1->wcols = 1; #endif /* HAVE_WCHAR */ __touchline(win, (int)win->cury, (int)win->curx, (int)win->maxx - 1); if (win->cury == LINES - 1 && Index: src/lib/libcurses/erase.c diff -u src/lib/libcurses/erase.c:1.33 src/lib/libcurses/erase.c:1.34 --- src/lib/libcurses/erase.c:1.33 Mon Sep 6 07:03:49 2021 +++ src/lib/libcurses/erase.c Tue Jan 25 03:05:06 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: erase.c,v 1.33 2021/09/06 07:03:49 rin Exp $ */ +/* $NetBSD: erase.c,v 1.34 2022/01/25 03:05:06 blymn Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)erase.c 8.2 (Berkeley) 5/4/94"; #else -__RCSID("$NetBSD: erase.c,v 1.33 2021/09/06 07:03:49 rin Exp $"); +__RCSID("$NetBSD: erase.c,v 1.34 2022/01/25 03:05:06 blymn Exp $"); #endif #endif /* not lint */ @@ -92,7 +92,7 @@ werase(WINDOW *win) #ifdef HAVE_WCHAR if (_cursesi_copy_nsp(win->bnsp, sp) == ERR) return ERR; - SET_WCOL(*sp, 1); + sp->wcols = 1; #endif } } Index: src/lib/libcurses/resize.c diff -u src/lib/libcurses/resize.c:1.33 src/lib/libcurses/resize.c:1.34 --- src/lib/libcurses/resize.c:1.33 Tue Sep 7 01:23:09 2021 +++ src/lib/libcurses/resize.c Tue Jan 25 03:05:06 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: resize.c,v 1.33 2021/09/07 01:23:09 rin Exp $ */ +/* $NetBSD: resize.c,v 1.34 2022/01/25 03:05:06 blymn Exp $ */ /* * Copyright (c) 2001 @@ -33,7 +33,7 @@ #if 0 static char sccsid[] = "@(#)resize.c blymn 2001/08/26"; #else -__RCSID("$NetBSD: resize.c,v 1.33 2021/09/07 01:23:09 rin Exp $"); +__RCSID("$NetBSD: resize.c,v 1.34 2022/01/25 03:05:06 blymn Exp $"); #endif #endif /* not lint */ @@ -357,7 +357,7 @@ __resizewin(WINDOW *win, int nlines, int sp->nsp = NULL; if (_cursesi_copy_nsp(win->bnsp, sp) == ERR) return ERR; - SET_WCOL(*sp, 1); + sp->wcols = 1; #endif /* HAVE_WCHAR */ } lp->hash = __hash_line(lp->line, ncols); Index: src/lib/libcurses/in_wch.c diff -u src/lib/libcurses/in_wch.c:1.7 src/lib/libcurses/in_wch.c:1.8 --- src/lib/libcurses/in_wch.c:1.7 Sun Jun 9 07:40:14 2019 +++ src/lib/libcurses/in_wch.c Tue Jan 25 03:05:06 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: in_wch.c,v 1.7 2019/06/09 07:40:14 blymn Exp $ */ +/* $NetBSD: in_wch.c,v 1.8 2022/01/25 03:05:06 blymn Exp $ */ /* * Copyright (c) 2005 The NetBSD Foundation Inc. @@ -36,7 +36,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: in_wch.c,v 1.7 2019/06/09 07:40:14 blymn Exp $"); +__RCSID("$NetBSD: in_wch.c,v 1.8 2022/01/25 03:05:06 blymn Exp $"); #endif /* not lint */ #include "curses.h" @@ -84,7 +84,7 @@ win_wch(WINDOW *win, cchar_t *wcval) { nschar_t *np; __LDATA *lp = &win->alines[win->cury]->line[win->curx]; - int cw = WCOL(*lp); + int cw = lp->wcols; if (cw < 0) lp += cw; Index: src/lib/libcurses/in_wchstr.c diff -u src/lib/libcurses/in_wchstr.c:1.9 src/lib/libcurses/in_wchstr.c:1.10 --- src/lib/libcurses/in_wchstr.c:1.9 Sun Aug 15 15:12:36 2021 +++ src/lib/libcurses/in_wchstr.c Tue Jan 25 03:05:06 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: in_wchstr.c,v 1.9 2021/08/15 15:12:36 rillig Exp $ */ +/* $NetBSD: in_wchstr.c,v 1.10 2022/01/25 03:05:06 blymn Exp $ */ /* * Copyright (c) 2005 The NetBSD Foundation Inc. @@ -36,7 +36,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: in_wchstr.c,v 1.9 2021/08/15 15:12:36 rillig Exp $"); +__RCSID("$NetBSD: in_wchstr.c,v 1.10 2022/01/25 03:05:06 blymn Exp $"); #endif /* not lint */ #include "curses.h" @@ -132,7 +132,7 @@ win_wchnstr(WINDOW *win, cchar_t *wchstr start = &win->alines[win->cury]->line[win->curx]; x = win->curx; - cw = WCOL(*start); + cw = start->wcols; if (cw < 0) { start += cw; x += cw; @@ -140,7 +140,7 @@ win_wchnstr(WINDOW *win, cchar_t *wchstr wcp = wchstr; /* (n - 1) to leave room for the trailing 0 element */ while ((x < win->maxx) && ((n < 0) || ((n > 1) && (cnt < n - 1)))) { - cw = WCOL(*start); + cw = start->wcols; wcp->vals[0] = start->ch; wcp->attributes = start->attr; wcp->elements = 1; Index: src/lib/libcurses/insstr.c diff -u src/lib/libcurses/insstr.c:1.9 src/lib/libcurses/insstr.c:1.10 --- src/lib/libcurses/insstr.c:1.9 Mon Sep 6 07:03:49 2021 +++ src/lib/libcurses/insstr.c Tue Jan 25 03:05:06 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: insstr.c,v 1.9 2021/09/06 07:03:49 rin Exp $ */ +/* $NetBSD: insstr.c,v 1.10 2022/01/25 03:05:06 blymn Exp $ */ /* * Copyright (c) 2005 The NetBSD Foundation Inc. @@ -36,7 +36,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: insstr.c,v 1.9 2021/09/06 07:03:49 rin Exp $"); +__RCSID("$NetBSD: insstr.c,v 1.10 2022/01/25 03:05:06 blymn Exp $"); #endif /* not lint */ #include <string.h> @@ -187,7 +187,7 @@ winsnstr(WINDOW *win, const char *str, i temp1->ch = (wchar_t)*scp & __CHARTEXT; temp1->attr = win->wattr; #ifdef HAVE_WCHAR - SET_WCOL(*temp1, 1); + temp1->wcols = 1; #endif /* HAVE_WCHAR */ } #ifdef DEBUG Index: src/lib/libcurses/inwstr.c diff -u src/lib/libcurses/inwstr.c:1.9 src/lib/libcurses/inwstr.c:1.10 --- src/lib/libcurses/inwstr.c:1.9 Sun Aug 15 15:12:36 2021 +++ src/lib/libcurses/inwstr.c Tue Jan 25 03:05:06 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: inwstr.c,v 1.9 2021/08/15 15:12:36 rillig Exp $ */ +/* $NetBSD: inwstr.c,v 1.10 2022/01/25 03:05:06 blymn Exp $ */ /* * Copyright (c) 2005 The NetBSD Foundation Inc. @@ -36,7 +36,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: inwstr.c,v 1.9 2021/08/15 15:12:36 rillig Exp $"); +__RCSID("$NetBSD: inwstr.c,v 1.10 2022/01/25 03:05:06 blymn Exp $"); #endif /* not lint */ #include "curses.h" @@ -136,7 +136,7 @@ winnwstr(WINDOW *win, wchar_t *wstr, int start = &win->alines[win->cury]->line[win->curx]; x = win->curx; - cw = WCOL(*start); + cw = start->wcols; if (cw < 0) { start += cw; x += cw; @@ -145,7 +145,7 @@ winnwstr(WINDOW *win, wchar_t *wstr, int wcp = wstr; /* (n - 1) to leave room for the trailing 0 element */ while ((x < win->maxx) && ((n < 0) || ((n > 1) && (cnt < n - 1)))) { - cw = WCOL(*start); + cw = start->wcols; *wcp = start->ch; wcp++; cnt++; Index: src/lib/libcurses/ins_wch.c diff -u src/lib/libcurses/ins_wch.c:1.17 src/lib/libcurses/ins_wch.c:1.18 --- src/lib/libcurses/ins_wch.c:1.17 Mon Sep 6 07:03:49 2021 +++ src/lib/libcurses/ins_wch.c Tue Jan 25 03:05:06 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: ins_wch.c,v 1.17 2021/09/06 07:03:49 rin Exp $ */ +/* $NetBSD: ins_wch.c,v 1.18 2022/01/25 03:05:06 blymn Exp $ */ /* * Copyright (c) 2005 The NetBSD Foundation Inc. @@ -36,7 +36,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: ins_wch.c,v 1.17 2021/09/06 07:03:49 rin Exp $"); +__RCSID("$NetBSD: ins_wch.c,v 1.18 2022/01/25 03:05:06 blymn Exp $"); #endif /* not lint */ #include <string.h> @@ -134,7 +134,7 @@ wins_wch(WINDOW *win, const cchar_t *wch lnp = win->alines[y]; start = &win->alines[y]->line[x]; sx = x; - pcw = WCOL(*start); + pcw = start->wcols; if (pcw < 0) { start += pcw; sx += pcw; @@ -150,7 +150,7 @@ wins_wch(WINDOW *win, const cchar_t *wch __CTRACE(__CTRACE_INPUT, "wins_wch: shift all characters\n"); temp1 = &win->alines[y]->line[win->maxx - 1]; temp2 = temp1 - cw; - pcw = WCOL(*(temp2 + 1)); + pcw = (temp2 + 1)->wcols; if (pcw < 0) { __CTRACE(__CTRACE_INPUT, "wins_wch: clear EOL\n"); temp2 += pcw; @@ -168,7 +168,7 @@ wins_wch(WINDOW *win, const cchar_t *wch if (_cursesi_copy_nsp(win->bnsp, temp1) == ERR) return ERR; temp1->attr = win->battr; - SET_WCOL(*temp1, 1); + temp1->wcols = 1; temp1--; } } @@ -181,7 +181,7 @@ wins_wch(WINDOW *win, const cchar_t *wch start->nsp = NULL; start->ch = wch->vals[0]; start->attr = wch->attributes & WA_ATTRIBUTES; - SET_WCOL(*start, cw); + start->wcols = cw; if (wch->elements > 1) { for (i = 1; i < wch->elements; i++) { np = malloc(sizeof(nschar_t)); @@ -198,7 +198,7 @@ wins_wch(WINDOW *win, const cchar_t *wch ex = x + 1; while (ex - x < cw) { temp1->ch = wch->vals[0]; - SET_WCOL(*temp1, x - ex); + temp1->wcols = x - ex; temp1->nsp = NULL; ex++, temp1++; } Index: src/lib/libcurses/insdelln.c diff -u src/lib/libcurses/insdelln.c:1.19 src/lib/libcurses/insdelln.c:1.20 --- src/lib/libcurses/insdelln.c:1.19 Mon Sep 6 07:03:49 2021 +++ src/lib/libcurses/insdelln.c Tue Jan 25 03:05:06 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: insdelln.c,v 1.19 2021/09/06 07:03:49 rin Exp $ */ +/* $NetBSD: insdelln.c,v 1.20 2022/01/25 03:05:06 blymn Exp $ */ /* * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: insdelln.c,v 1.19 2021/09/06 07:03:49 rin Exp $"); +__RCSID("$NetBSD: insdelln.c,v 1.20 2022/01/25 03:05:06 blymn Exp $"); #endif /* not lint */ /* @@ -124,7 +124,7 @@ winsdelln(WINDOW *win, int nlines) lp = &win->alines[y]->line[i]; if (_cursesi_copy_nsp(win->bnsp, lp) == ERR) return ERR; - SET_WCOL(*lp, 1); + lp->wcols = 1; #endif /* HAVE_WCHAR */ } for (y = last; y >= win->cury; --y) @@ -166,7 +166,7 @@ winsdelln(WINDOW *win, int nlines) win->alines[y]->line[i].ch = (wchar_t)btowc((int)win->bch); lp = &win->alines[y]->line[i]; - SET_WCOL( *lp, 1 ); + lp->wcols = 1; if (_cursesi_copy_nsp(win->bnsp, lp) == ERR) return ERR; #endif /* HAVE_WCHAR */ Index: src/lib/libcurses/newwin.c diff -u src/lib/libcurses/newwin.c:1.63 src/lib/libcurses/newwin.c:1.64 --- src/lib/libcurses/newwin.c:1.63 Tue Oct 19 06:41:03 2021 +++ src/lib/libcurses/newwin.c Tue Jan 25 03:05:06 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: newwin.c,v 1.63 2021/10/19 06:41:03 blymn Exp $ */ +/* $NetBSD: newwin.c,v 1.64 2022/01/25 03:05:06 blymn 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.63 2021/10/19 06:41:03 blymn Exp $"); +__RCSID("$NetBSD: newwin.c,v 1.64 2022/01/25 03:05:06 blymn Exp $"); #endif #endif /* not lint */ @@ -166,7 +166,7 @@ __newwin(SCREEN *screen, int nlines, int #else sp->ch = (wchar_t)btowc((int) win->bch); sp->nsp = NULL; - SET_WCOL(*sp, 1); + sp->wcols = 1; #endif /* HAVE_WCHAR */ } lp->hash = __hash_line(lp->line, maxx); @@ -351,7 +351,7 @@ __makenew(SCREEN *screen, int nlines, in win->battr = 0; #ifdef HAVE_WCHAR win->bnsp = NULL; - SET_BGWCOL(*win, 1); + win->wcols = 1; #endif /* HAVE_WCHAR */ win->scr_t = 0; win->scr_b = win->maxy - 1; Index: src/lib/libcurses/refresh.c diff -u src/lib/libcurses/refresh.c:1.117 src/lib/libcurses/refresh.c:1.118 --- src/lib/libcurses/refresh.c:1.117 Fri Dec 17 03:50:18 2021 +++ src/lib/libcurses/refresh.c Tue Jan 25 03:05:06 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: refresh.c,v 1.117 2021/12/17 03:50:18 uwe Exp $ */ +/* $NetBSD: refresh.c,v 1.118 2022/01/25 03:05:06 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.117 2021/12/17 03:50:18 uwe Exp $"); +__RCSID("$NetBSD: refresh.c,v 1.118 2022/01/25 03:05:06 blymn Exp $"); #endif #endif /* not lint */ @@ -316,22 +316,25 @@ _wnoutrefresh(WINDOW *win, int begy, int vlp->line[x_off].ch = wlp->line[wx].ch; /* Copy attributes */ vlp->line[x_off].attr = wlp->line[wx].attr; - /* Check for nca conflict with colour */ - if ((vlp->line[x_off].attr & __COLOR) && - (vlp->line[x_off].attr & screen->nca)) - vlp->line[x_off].attr &= ~__COLOR; +#ifdef HAVE_WCHAR + vlp->line[x_off].wcols = wlp->line[wx].wcols; +#endif /* HAVE_WCHAR */ if (win->flags & __ISDERWIN) { dwlp->line[dx_off].ch = wlp->line[wx].ch; dwlp->line[dx_off].attr = wlp->line[wx].attr; +#ifdef HAVE_WCHAR + dwlp->line[dx_off].wcols = + wlp->line[wx].wcols; +#endif /* HAVE_WCHAR */ } #ifdef HAVE_WCHAR if (wlp->line[wx].ch == (wchar_t)btowc((int) win->bch)) { vlp->line[x_off].ch = win->bch; - SET_WCOL(vlp->line[x_off], 1); + vlp->line[x_off].wcols = win->wcols; if (_cursesi_copy_nsp(win->bnsp, &vlp->line[x_off]) == ERR) @@ -339,7 +342,8 @@ _wnoutrefresh(WINDOW *win, int begy, int if (win->flags & __ISDERWIN) { dwlp->line[dx_off].ch = win->bch; - SET_WCOL(dwlp->line[dx_off], 1); + dwlp->line[dx_off].wcols = + win->wcols; if (_cursesi_copy_nsp(win->bnsp, &dwlp->line[dx_off]) == ERR) @@ -602,6 +606,13 @@ doupdate(void) __CTRACE(__CTRACE_REFRESH, " %x", curscr->alines[i]->line[j].attr); __CTRACE(__CTRACE_REFRESH, "\n"); +#ifdef HAVE_WCHAR + __CTRACE(__CTRACE_REFRESH, " wcols:"); + for (j = 0; j < curscr->maxx; j++) + __CTRACE(__CTRACE_REFRESH, " %d", + curscr->alines[i]->line[j].wcols); + __CTRACE(__CTRACE_REFRESH, "\n"); +#endif /* HAVE_WCHAR */ __CTRACE(__CTRACE_REFRESH, "W: %d:", i); __CTRACE(__CTRACE_REFRESH, " 0x%x \n", win->alines[i]->hash); @@ -617,6 +628,11 @@ doupdate(void) win->alines[i]->line[j].attr); __CTRACE(__CTRACE_REFRESH, "\n"); #ifdef HAVE_WCHAR + __CTRACE(__CTRACE_REFRESH, " wcols:"); + for (j = 0; j < win->maxx; j++) + __CTRACE(__CTRACE_REFRESH, " %d", + win->alines[i]->line[j].wcols); + __CTRACE(__CTRACE_REFRESH, "\n"); __CTRACE(__CTRACE_REFRESH, " nsp:"); for (j = 0; j < curscr->maxx; j++) __CTRACE(__CTRACE_REFRESH, " %p", @@ -731,13 +747,15 @@ cleanup: for (i = 0; i < curscr->maxy; i++) { for (j = 0; j < curscr->maxx; j++) __CTRACE(__CTRACE_REFRESH, - "[%d,%d](%x,%x,%p)-(%x,%x,%p)\n", + "[%d,%d](%x,%x,%d,%p)-(%x,%x,%d,%p)\n", i, j, curscr->alines[i]->line[j].ch, curscr->alines[i]->line[j].attr, + curscr->alines[i]->line[j].wcols, curscr->alines[i]->line[j].nsp, _cursesi_screen->__virtscr->alines[i]->line[j].ch, _cursesi_screen->__virtscr->alines[i]->line[j].attr, + _cursesi_screen->__virtscr->alines[i]->line[j].wcols, _cursesi_screen->__virtscr->alines[i]->line[j].nsp); } } @@ -954,13 +972,14 @@ putch(__LDATA *nsp, __LDATA *csp, int wy #ifdef HAVE_WCHAR if (_cursesi_copy_nsp(nsp->nsp, csp) == ERR) return ERR; + csp->wcols = nsp->wcols; #endif /* HAVE_WCHAR */ } #ifndef HAVE_WCHAR __cputchar((int)nsp->ch); #else - if (WCOL(*nsp) <= 0) + if (nsp->wcols <= 0) goto out; __cputwchar((int)nsp->ch); __CTRACE(__CTRACE_REFRESH, @@ -995,8 +1014,8 @@ putchbr(__LDATA *nsp, __LDATA *csp, __LD /* We need to insert characters. */ #ifdef HAVE_WCHAR - cw = WCOL(*nsp); - pcw = WCOL(*psp); + cw = nsp->wcols; + pcw = psp->wcols; if (cw < 1 || pcw < 1) return ERR; /* Nothing to insert */ @@ -1056,7 +1075,7 @@ makech(int wy) __LDATA *nsp, *csp, *cp, *cep, *fsp; __LINE *wlp; size_t clsp, nlsp; /* Last space in lines. */ - int lch, wx, chw; + int lch, wx, owx, chw; const char *ce; attr_t lspc; /* Last space colour */ @@ -1072,7 +1091,7 @@ makech(int wy) blank.attr = 0; if (_cursesi_copy_nsp(win->bnsp, &blank) == ERR) return ERR; - SET_WCOL(blank, 1); + blank.wcols = win->wcols; #endif /* HAVE_WCHAR */ #ifdef DEBUG #if HAVE_WCHAR @@ -1087,12 +1106,12 @@ makech(int wy) lp = &curscr->alines[wy]->line[x]; vlp = &__virtscr->alines[wy]->line[x]; __CTRACE(__CTRACE_REFRESH, - "[%d,%d](%x,%x,%x,%x,%p)-" - "(%x,%x,%x,%x,%p)\n", - wy, x, lp->ch, lp->attr, - win->bch, win->battr, lp->nsp, - vlp->ch, vlp->attr, - win->bch, win->battr, vlp->nsp); + "[%d,%d](%x,%x,%d,%x,%x,%d,%p)-" + "(%x,%x,%d,%x,%x,%d,%p)\n", + wy, x, lp->ch, lp->attr, lp->wcols, + win->bch, win->battr, win->wcols, lp->nsp, + vlp->ch, vlp->attr, vlp->wcols, + win->bch, win->battr, win->wcols, vlp->nsp); } } #endif /* HAVE_WCHAR */ @@ -1163,23 +1182,29 @@ makech(int wy) #ifndef HAVE_WCHAR __CTRACE(__CTRACE_REFRESH, "makech: wx=%d,lch=%d\n", wx, lch); #else - __CTRACE(__CTRACE_REFRESH, "makech: nsp=(%x,%x,%x,%x,%p)\n", - nsp->ch, nsp->attr, win->bch, win->battr, nsp->nsp); - __CTRACE(__CTRACE_REFRESH, "makech: csp=(%x,%x,%x,%x,%p)\n", - csp->ch, csp->attr, win->bch, win->battr, csp->nsp); + __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); + __CTRACE(__CTRACE_REFRESH, "makech: csp=(%x,%x,%d,%x,%x,%d,%p)\n", + csp->ch, csp->attr, csp->wcols, win->bch, win->battr, + win->wcols, csp->nsp); #endif if (!(wlp->flags & __ISFORCED) && #ifdef HAVE_WCHAR - ((nsp->attr & __WCWIDTH) != __WCWIDTH) && + ((nsp->wflags & WCA_CONTINUATION) != WCA_CONTINUATION) && #endif celleq(nsp, csp)) { if (wx <= lch) { while (wx <= lch && celleq(nsp, csp)) { +#ifdef HAVE_WCHAR + wx += nsp->wcols; +#else + wx++; +#endif nsp++; if (!_cursesi_screen->curwin) ++csp; - ++wx; } continue; } @@ -1193,6 +1218,7 @@ makech(int wy) wx, _cursesi_screen->ly, _cursesi_screen->lx, wy, wx); _cursesi_screen->ly = wy; _cursesi_screen->lx = wx; + owx = wx; while (wx <= lch && ((wlp->flags & __ISFORCED) || !celleq(nsp, csp))) { @@ -1246,7 +1272,7 @@ makech(int wy) csp->ch = ' '; /* XXX */ #else csp->ch = (wchar_t)btowc((int)' '); - SET_WCOL( *csp, 1 ); + csp->wcols = 1; #endif /* HAVE_WCHAR */ assert(csp != &blank); csp++; @@ -1257,12 +1283,13 @@ makech(int wy) } #ifdef HAVE_WCHAR - chw = WCOL(*nsp); + chw = nsp->wcols; if (chw < 0) chw = 0; /* match putch() */ #else chw = 1; #endif /* HAVE_WCHAR */ + owx = wx; if (wx + chw >= win->maxx && wy == win->maxy - 1 && !_cursesi_screen->curwin) { @@ -1304,14 +1331,28 @@ makech(int wy) putattr_out(nsp); } wx += chw; - nsp++; + nsp += chw; __CTRACE(__CTRACE_REFRESH, "makech: 2: wx = %d, lx = %d\n", wx, _cursesi_screen->lx); } if (_cursesi_screen->lx == wx) /* If no change. */ break; - _cursesi_screen->lx = wx; + + /* + * We need to work out if the cursor has been put in the + * middle of a wide character so check if curx is between + * where we were and where we are and we are on the right + * line. If so, move the cursor now. + */ + if ((wy == win->cury) && (wx > win->curx) && + (owx < win->curx)) { + _cursesi_screen->lx = win->curx; + domvcur(win, _cursesi_screen->ly, wx, + _cursesi_screen->ly, _cursesi_screen->lx); + } else + _cursesi_screen->lx = wx; + if (_cursesi_screen->lx >= COLS && auto_right_margin) _cursesi_screen->lx = COLS - 1; else @@ -1339,12 +1380,12 @@ makech(int wy) lp = &curscr->alines[wy]->line[x]; vlp = &__virtscr->alines[wy]->line[x]; __CTRACE(__CTRACE_REFRESH, - "[%d,%d](%x,%x,%x,%x,%p)-" - "(%x,%x,%x,%x,%p)\n", - wy, x, lp->ch, lp->attr, - win->bch, win->battr, lp->nsp, - vlp->ch, vlp->attr, - win->bch, win->battr, vlp->nsp); + "[%d,%d](%x,%x,%d,%x,%x,%d,%p)-" + "(%x,%x,%d,%x,%x,%d,%p)\n", + wy, x, lp->ch, lp->attr, lp->wcols, + win->bch, win->battr, win->wcols, lp->nsp, + vlp->ch, vlp->attr, vlp->wcols, + win->bch, win->battr, win->wcols, vlp->nsp); } } #endif /* HAVE_WCHAR */ @@ -1556,12 +1597,12 @@ done: } #else if (buf[0].ch != (wchar_t)btowc((int)curscr->bch )) { - for (i = 0; i < BLANKSIZE; i++) { + for (i = 0; i < BLANKSIZE; i++) { /* XXXX: BLANKSIZE may not be valid if wcols > 1 */ buf[i].ch = (wchar_t)btowc((int)curscr->bch); if (_cursesi_copy_nsp(curscr->bnsp, &buf[i]) == ERR) return; buf[i].attr = 0; - SET_WCOL(buf[i], 1); + buf[i].wcols = curscr->wcols; } } #endif /* HAVE_WCHAR */ Index: src/lib/libcurses/slk.c diff -u src/lib/libcurses/slk.c:1.18 src/lib/libcurses/slk.c:1.19 --- src/lib/libcurses/slk.c:1.18 Thu Jan 6 20:50:18 2022 +++ src/lib/libcurses/slk.c Tue Jan 25 03:05:06 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: slk.c,v 1.18 2022/01/06 20:50:18 blymn Exp $ */ +/* $NetBSD: slk.c,v 1.19 2022/01/25 03:05:06 blymn Exp $ */ /*- * Copyright (c) 2017 The NetBSD Foundation, Inc. @@ -30,8 +30,9 @@ */ #include <sys/cdefs.h> +#include <limits.h> #ifndef lint -__RCSID("$NetBSD: slk.c,v 1.18 2022/01/06 20:50:18 blymn Exp $"); +__RCSID("$NetBSD: slk.c,v 1.19 2022/01/25 03:05:06 blymn Exp $"); #endif /* not lint */ #include <ctype.h>