Module Name: src Committed By: blymn Date: Tue Jun 22 07:26:45 UTC 2021
Modified Files: src/lib/libcurses: slk.c Log Message: Fix how the slk are drawn by making sure we use ins_wchar in the bottom left of the screen to avoid a scroll because this may cause an ERR if scrollok is false. To generate a diff of this commit: cvs rdiff -u -r1.8 -r1.9 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/slk.c diff -u src/lib/libcurses/slk.c:1.8 src/lib/libcurses/slk.c:1.9 --- src/lib/libcurses/slk.c:1.8 Sun Jul 28 00:51:59 2019 +++ src/lib/libcurses/slk.c Tue Jun 22 07:26:45 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: slk.c,v 1.8 2019/07/28 00:51:59 uwe Exp $ */ +/* $NetBSD: slk.c,v 1.9 2021/06/22 07:26:45 blymn Exp $ */ /*- * Copyright (c) 2017 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: slk.c,v 1.8 2019/07/28 00:51:59 uwe Exp $"); +__RCSID("$NetBSD: slk.c,v 1.9 2021/06/22 07:26:45 blymn Exp $"); #endif /* not lint */ #include <ctype.h> @@ -555,9 +555,21 @@ __slk_wset(SCREEN *screen, int labnum, c if (screen == NULL) return ERR; +#ifdef DEBUG + __CTRACE(__CTRACE_INPUT, "__slk_wset: entry\n"); +#endif olabel = label; - if ((len = wcsrtombs(NULL, &olabel, 0, &screen->sp)) == -1) + if ((len = wcsrtombs(NULL, &olabel, 0, &screen->sp)) == -1) { +#ifdef DEBUG + __CTRACE(__CTRACE_INPUT, "__slk_wset: conversion failed on char 0x%x\n", + (uint16_t) *olabel); +#endif return ERR; + } + +#ifdef DEBUG + __CTRACE(__CTRACE_INPUT, "__slk_wset: wcsrtombs %ld\n", len); +#endif len++; /* We need to store the NULL character. */ if ((str = malloc(len)) == NULL) return ERR; @@ -567,6 +579,10 @@ __slk_wset(SCREEN *screen, int labnum, c result = __slk_set(screen, labnum, str, justify); out: free(str); +#ifdef DEBUG + __CTRACE(__CTRACE_INPUT, "__slk_wset: return %s\n", + (result == OK)?"OK":"ERR"); +#endif return result; } #endif /* HAVE_WCHAR */ @@ -801,19 +817,69 @@ static int __slk_draw(SCREEN *screen, int labnum) { const struct __slk_label *l; + int retval, inc, lcnt, tx; + cchar_t cc; + wchar_t wc[2]; + char ts[MB_CUR_MAX]; if (screen->slk_hidden) return OK; + retval = OK; /* quiet gcc... */ + l = &screen->slk_labels[labnum]; if (screen->is_term_slk) return ti_putp(screen->term, ti_tiparm(screen->term, t_plab_norm(screen->term), labnum + 1, l->label)); - else if (screen->slk_window != NULL) - return mvwaddnstr(screen->slk_window, 0, l->x, - l->label, screen->slk_label_len); - else + else if (screen->slk_window != NULL) { + if ((labnum != screen->slk_nlabels - 1) || + (screen->slk_window->flags & __SCROLLOK) || + ((l->x + screen->slk_label_len) < screen->slk_window->maxx)) { + retval = mvwaddnstr(screen->slk_window, 0, l->x, + l->label, screen->slk_label_len); + } else { + lcnt = 0; + tx = 0; + while (lcnt < screen->slk_label_len) { + inc = wctomb(ts, l->label[lcnt]); + if (inc < 0) { + /* conversion failed, skip? */ + lcnt++; + continue; + } + +#ifdef DEBUG + __CTRACE(__CTRACE_INPUT, "__slk_draw: last label, (%d,%d) char[%d] 0x%x\n", + l->x + tx, 0, lcnt, l->label[lcnt]); + __CTRACE(__CTRACE_INPUT, "__slk_draw: label len %d, wcwidth %d\n", + screen->slk_label_len, wcwidth(l->label[lcnt])); +#endif + wc[0] = l->label[lcnt]; + wc[1] = L'\0'; + if (setcchar(&cc, wc, + screen->slk_window->wattr, 0, + NULL) == ERR) + return ERR; + + if (l->x + wcwidth(l->label[lcnt] + tx) >= + screen->slk_label_len) { + /* last character that will fit + * so insert it to avoid scroll + */ + retval = mvwins_wch(screen->slk_window, + 0, l->x + tx, &cc); + } else { + retval = mvwadd_wch(screen->slk_window, + 0, l->x + tx, &cc); + } + tx += wcwidth(l->label[lcnt]); + lcnt += inc; + } + } + + return retval; + } else return ERR; }