From d34c5681a41190044ebf9aa2942d1d0f669020b5 Mon Sep 17 00:00:00 2001 From: roy Date: Tue, 2 Oct 2018 17:35:44 +0000 Subject: [PATCH] curses: fix ripoffline When creating stdscr, ensure it's placed and sized in accordance with lines ripped off. LINES is no longer adjusted for lines ripped off. POSIX makes no mention that it should be adjusted. Bottom lines are now placed correctly. Lines ripped off are now displayed after calling initscr. ok kamil@ Fixes PR #53635 --- lib/libcurses/curses_private.h | 9 +++--- lib/libcurses/curses_screen.3 | 6 ++-- lib/libcurses/fileio.c | 6 ++-- lib/libcurses/initscr.c | 5 ++-- lib/libcurses/newwin.c | 24 ++++++++++------ lib/libcurses/resize.c | 8 +++--- lib/libcurses/ripoffline.c | 52 +++++++++++++++++++++++----------- lib/libcurses/screen.c | 17 ++++++----- lib/libcurses/setterm.c | 8 +++--- 9 files changed, 80 insertions(+), 55 deletions(-) diff --git a/lib/libcurses/curses_private.h b/lib/libcurses/curses_private.h index 651218e2879c..5c5989cbb618 100644 --- a/lib/libcurses/curses_private.h +++ b/lib/libcurses/curses_private.h @@ -1,4 +1,4 @@ -/* $NetBSD: curses_private.h,v 1.63 2018/09/27 14:05:26 roy Exp $ */ +/* $NetBSD: curses_private.h,v 1.64 2018/10/02 17:35:44 roy Exp $ */ /*- * Copyright (c) 1998-2000 Brett Lymn @@ -368,7 +368,7 @@ void __cursesi_chtype_to_cchar(chtype, cchar_t *); int __fgetc_resize(FILE *); int __unget(wint_t); int __mvcur(int, int, int, int, int); -WINDOW *__newwin(SCREEN *, int, int, int, int, int); +WINDOW *__newwin(SCREEN *, int, int, int, int, int, int); int __nodelay(void); int __notimeout(void); void __restartwin(void); @@ -378,9 +378,10 @@ void __restore_meta_state(void); void __restore_termios(void); void __restore_stophandler(void); void __restore_winchhandler(void); -int __ripoffscreen(SCREEN *, int *); +int __ripoffscreen(SCREEN *); void __ripoffresize(SCREEN *); -int __rippedlines(const SCREEN *); +void __ripofftouch(SCREEN *); +int __rippedlines(const SCREEN *, int); void __save_termios(void); void __set_color(WINDOW *win, attr_t attr); void __set_stophandler(void); diff --git a/lib/libcurses/curses_screen.3 b/lib/libcurses/curses_screen.3 index 2214164aa189..a8afca1bc74d 100644 --- a/lib/libcurses/curses_screen.3 +++ b/lib/libcurses/curses_screen.3 @@ -1,4 +1,4 @@ -.\" $NetBSD: curses_screen.3,v 1.24 2018/09/28 08:11:34 kamil Exp $ +.\" $NetBSD: curses_screen.3,v 1.25 2018/10/02 17:35:44 roy Exp $ .\" .\" Copyright (c) 2002 .\" Brett Lymn (blymn@NetBSD.org, brett_lymn@yahoo.com.au) @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" -.Dd September 28, 2018 +.Dd October 2, 2018 .Dt CURSES_SCREEN 3 .Os .Sh NAME @@ -239,8 +239,6 @@ or .Xr doupdate 3 , but may call .Xr wnoutrefresh 3 . -.Dv LINES -will be reduced by the total number of lines ripped off. .Fn ripoffline can be called up to five times. .Pp diff --git a/lib/libcurses/fileio.c b/lib/libcurses/fileio.c index e6d429ed8f2f..f30f82ec516d 100644 --- a/lib/libcurses/fileio.c +++ b/lib/libcurses/fileio.c @@ -1,4 +1,4 @@ -/* $NetBSD: fileio.c,v 1.5 2016/10/22 21:55:06 christos Exp $ */ +/* $NetBSD: fileio.c,v 1.6 2018/10/02 17:35:44 roy Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ #include #ifndef lint -__RCSID("$NetBSD: fileio.c,v 1.5 2016/10/22 21:55:06 christos Exp $"); +__RCSID("$NetBSD: fileio.c,v 1.6 2018/10/02 17:35:44 roy Exp $"); #endif /* not lint */ #include "curses.h" @@ -195,7 +195,7 @@ getwin(FILE *fp) if (fread(wtmp, sizeof(WINDOW), 1, fp) != 1) goto error0; win = __newwin(_cursesi_screen, wtmp->maxy, wtmp->maxx, - wtmp->begy, wtmp->begx, FALSE); + wtmp->begy, wtmp->begx, FALSE, FALSE); if (win == NULL) goto error0; win->cury = wtmp->cury; diff --git a/lib/libcurses/initscr.c b/lib/libcurses/initscr.c index 516f602fa298..86cbc06e3f32 100644 --- a/lib/libcurses/initscr.c +++ b/lib/libcurses/initscr.c @@ -1,4 +1,4 @@ -/* $NetBSD: initscr.c,v 1.32 2017/01/11 17:15:27 roy Exp $ */ +/* $NetBSD: initscr.c,v 1.33 2018/10/02 17:35:44 roy Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)initscr.c 8.2 (Berkeley) 5/4/94"; #else -__RCSID("$NetBSD: initscr.c,v 1.32 2017/01/11 17:15:27 roy Exp $"); +__RCSID("$NetBSD: initscr.c,v 1.33 2018/10/02 17:35:44 roy Exp $"); #endif #endif /* not lint */ @@ -70,6 +70,7 @@ initscr(void) set_term(_cursesi_screen); wrefresh(curscr); + __ripofftouch(_cursesi_screen); return stdscr; } diff --git a/lib/libcurses/newwin.c b/lib/libcurses/newwin.c index 72c6e2dd5947..537f8ffc8730 100644 --- a/lib/libcurses/newwin.c +++ b/lib/libcurses/newwin.c @@ -1,4 +1,4 @@ -/* $NetBSD: newwin.c,v 1.51 2017/09/18 10:18:13 roy Exp $ */ +/* $NetBSD: newwin.c,v 1.52 2018/10/02 17:35:44 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.51 2017/09/18 10:18:13 roy Exp $"); +__RCSID("$NetBSD: newwin.c,v 1.52 2018/10/02 17:35:44 roy Exp $"); #endif #endif /* not lint */ @@ -85,7 +85,8 @@ dupwin(WINDOW *win) WINDOW *new_one; if ((new_one = __newwin(_cursesi_screen, win->maxy, win->maxx, - win->begy, win->begx, FALSE)) == NULL) + win->begy, win->begx, FALSE, + win == stdscr ? TRUE : FALSE)) == NULL) return NULL; overwrite(win, new_one); @@ -100,7 +101,7 @@ WINDOW * newwin(int nlines, int ncols, int by, int bx) { - return __newwin(_cursesi_screen, nlines, ncols, by, bx, FALSE); + return __newwin(_cursesi_screen, nlines, ncols, by, bx, FALSE, FALSE); } /* @@ -113,22 +114,29 @@ newpad(int nlines, int ncols) if (nlines < 1 || ncols < 1) return NULL; - return __newwin(_cursesi_screen, nlines, ncols, 0, 0, TRUE); + return __newwin(_cursesi_screen, nlines, ncols, 0, 0, TRUE, FALSE); } WINDOW * -__newwin(SCREEN *screen, int nlines, int ncols, int by, int bx, int ispad) +__newwin(SCREEN *screen, int nlines, int ncols, int by, int bx, int ispad, + int isstdscr) { WINDOW *win; __LINE *lp; int i, j; - int maxy, maxx; + int ry, maxy, maxx; __LDATA *sp; if (by < 0 || bx < 0) return NULL; - maxy = nlines > 0 ? nlines : LINES - by + nlines; + if (isstdscr) { + ry = __rippedlines(screen, -1); + by += __rippedlines(screen, 1); + } else + ry = 0; + + maxy = nlines > 0 ? nlines : LINES - by - ry + nlines; maxx = ncols > 0 ? ncols : COLS - bx + ncols; if ((win = __makenew(screen, maxy, maxx, by, bx, 0, ispad)) == NULL) diff --git a/lib/libcurses/resize.c b/lib/libcurses/resize.c index f987c49950f7..49e84fa9156e 100644 --- a/lib/libcurses/resize.c +++ b/lib/libcurses/resize.c @@ -1,4 +1,4 @@ -/* $NetBSD: resize.c,v 1.27 2018/09/28 15:03:48 roy Exp $ */ +/* $NetBSD: resize.c,v 1.28 2018/10/02 17:35:44 roy Exp $ */ /* * Copyright (c) 2001 @@ -40,7 +40,7 @@ #if 0 static char sccsid[] = "@(#)resize.c blymn 2001/08/26"; #else -__RCSID("$NetBSD: resize.c,v 1.27 2018/09/28 15:03:48 roy Exp $"); +__RCSID("$NetBSD: resize.c,v 1.28 2018/10/02 17:35:44 roy Exp $"); #endif #endif /* not lint */ @@ -209,13 +209,13 @@ resize_term(int nlines, int ncols) return ERR; if (__resizeterm(__virtscr, nlines, ncols) == ERR) return ERR; - rlines = nlines - __rippedlines(_cursesi_screen); + rlines = nlines - __rippedlines(_cursesi_screen, 0); if (__resizeterm(stdscr, rlines, ncols) == ERR) return ERR; _cursesi_screen->LINES = nlines; _cursesi_screen->COLS = ncols; - LINES = rlines; + LINES = nlines; COLS = ncols; if (_cursesi_screen->slk_window != NULL && diff --git a/lib/libcurses/ripoffline.c b/lib/libcurses/ripoffline.c index e3144eb33a47..6a4618866456 100644 --- a/lib/libcurses/ripoffline.c +++ b/lib/libcurses/ripoffline.c @@ -1,4 +1,4 @@ -/* $NetBSD: ripoffline.c,v 1.3 2017/01/24 17:27:30 roy Exp $ */ +/* $NetBSD: ripoffline.c,v 1.4 2018/10/02 17:35:44 roy Exp $ */ /*- * Copyright (c) 2017 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ #include #ifndef lint -__RCSID("$NetBSD: ripoffline.c,v 1.3 2017/01/24 17:27:30 roy Exp $"); +__RCSID("$NetBSD: ripoffline.c,v 1.4 2018/10/02 17:35:44 roy Exp $"); #endif /* not lint */ #include "curses.h" @@ -54,7 +54,7 @@ ripoffline(int line, int (*init)(WINDOW *, int)) { #ifdef DEBUG - __CTRACE(__CTRACE_SCREEN, "ripoffline: %d\n", line); + __CTRACE(__CTRACE_WINDOW, "ripoffline: %d\n", line); #endif if (nrips >= MAX_RIPS || init == NULL) @@ -71,16 +71,16 @@ ripoffline(int line, int (*init)(WINDOW *, int)) * Returns the number of ripped lines from the screen. */ int -__rippedlines(const SCREEN *screen) +__rippedlines(const SCREEN *screen, int line) { const struct __ripoff *rip; int i, n; n = 0; for (i = 0, rip = screen->ripped; i < screen->nripped; i++, rip++) { - if (rip->nlines < 0) + if (line < 1 && rip->nlines < 0) n += -rip->nlines; - else + else if (line > 0 && rip->nlines > 0) n += rip->nlines; } return n; @@ -93,38 +93,40 @@ __rippedlines(const SCREEN *screen) * this implemenation allows for N lines if needed. */ int -__ripoffscreen(SCREEN *screen, int *rtop) +__ripoffscreen(SCREEN *screen) { - int i, nlines; + int i, nlines, rbot, rtop; const struct ripoff *srip; struct __ripoff *rip; WINDOW *w; - *rtop = 0; rip = screen->ripped; + rbot = LINES; + rtop = 0; for (i = 0, srip = ripoffs; i < nrips; i++, srip++) { if (srip->nlines == 0) continue; nlines = srip->nlines < 0 ? -srip->nlines : srip->nlines; w = __newwin(screen, nlines, 0, - srip->nlines < 0 ? LINES - nlines : *rtop, - 0, FALSE); + srip->nlines < 0 ? rbot - nlines : rtop, + 0, FALSE, FALSE); if (w != NULL) { rip->win = w; rip->nlines = srip->nlines; rip++; screen->nripped++; - if (rip->nlines > 0) - (*rtop) += rip->nlines; - LINES -= nlines; + if (srip->nlines > 0) + rtop += nlines; + else + rbot -= nlines; } if (srip->init(w, COLS) == ERR) return ERR; #ifdef DEBUG if (w != NULL) - __CTRACE(__CTRACE_SCREEN, - "newterm: ripped %d lines from the %s\n", - nlines, srip->nlines < 0 ? "bottom" : "top"); + __CTRACE(__CTRACE_WINDOW, + "newterm: %p ripped %d line(s) from the %s\n", + w, nlines, srip->nlines < 0 ? "bottom" : "top"); #endif } nrips = 0; /* Reset the stack. */ @@ -154,6 +156,22 @@ __ripoffresize(SCREEN *screen) } } +/* + * __ripofftouch -- + * Displays the ripped off lines from initscr. + */ +void +__ripofftouch(SCREEN *screen) +{ + int i; + struct __ripoff *rip; + + for (i = 0, rip = screen->ripped; i < screen->nripped; i++, rip++) { + touchwin(rip->win); + wnoutrefresh(rip->win); + } +} + /* * __unripoffline -- * Used by __slk_init to remove the ripoffline reservation it made diff --git a/lib/libcurses/screen.c b/lib/libcurses/screen.c index dfcd58ba6943..a3c63ef2082f 100644 --- a/lib/libcurses/screen.c +++ b/lib/libcurses/screen.c @@ -1,4 +1,4 @@ -/* $NetBSD: screen.c,v 1.33 2017/03/20 10:20:16 roy Exp $ */ +/* $NetBSD: screen.c,v 1.34 2018/10/02 17:35:44 roy Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)screen.c 8.2 (blymn) 11/27/2001"; #else -__RCSID("$NetBSD: screen.c,v 1.33 2017/03/20 10:20:16 roy Exp $"); +__RCSID("$NetBSD: screen.c,v 1.34 2018/10/02 17:35:44 roy Exp $"); #endif #endif /* not lint */ @@ -74,7 +74,7 @@ set_term(SCREEN *new) old_screen->rawmode = __rawmode; old_screen->noqch = __noqch; old_screen->COLS = COLS; - old_screen->LINES = LINES + __rippedlines(old_screen); + old_screen->LINES = LINES; old_screen->ESCDELAY = ESCDELAY; old_screen->TABSIZE = TABSIZE; old_screen->COLORS = COLORS; @@ -91,7 +91,7 @@ set_term(SCREEN *new) __rawmode = new->rawmode; __noqch = new->noqch; COLS = new->COLS; - LINES = new->LINES - __rippedlines(new); + LINES = new->LINES; ESCDELAY = new->ESCDELAY; TABSIZE = new->TABSIZE; COLORS = new->COLORS; @@ -130,7 +130,6 @@ newterm(char *type, FILE *outfd, FILE *infd) { SCREEN *new_screen; char *sp; - int rtop; sp = type; if (type == NULL && (sp = getenv("TERM")) == NULL) @@ -193,21 +192,21 @@ newterm(char *type, FILE *outfd, FILE *infd) new_screen->winlistp = NULL; if ((new_screen->curscr = __newwin(new_screen, 0, - 0, 0, 0, FALSE)) == NULL) + 0, 0, 0, FALSE, FALSE)) == NULL) goto error_exit; if ((new_screen->__virtscr = __newwin(new_screen, 0, - 0, 0, 0, FALSE)) == NULL) + 0, 0, 0, FALSE, FALSE)) == NULL) goto error_exit; /* If Soft Label Keys are setup, they will ripoffline. */ if (__slk_init(new_screen) == ERR) goto error_exit; - if (__ripoffscreen(new_screen, &rtop) == ERR) + if (__ripoffscreen(new_screen) == ERR) goto error_exit; - new_screen->stdscr = __newwin(new_screen, LINES, 0, rtop, 0, FALSE); + new_screen->stdscr = __newwin(new_screen, 0, 0, 0, 0, FALSE, TRUE); if (new_screen->stdscr == NULL) goto error_exit; diff --git a/lib/libcurses/setterm.c b/lib/libcurses/setterm.c index fd9766fe7631..a056e498d98b 100644 --- a/lib/libcurses/setterm.c +++ b/lib/libcurses/setterm.c @@ -1,4 +1,4 @@ -/* $NetBSD: setterm.c,v 1.66 2017/03/23 00:55:39 roy Exp $ */ +/* $NetBSD: setterm.c,v 1.67 2018/10/02 17:35:44 roy Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)setterm.c 8.8 (Berkeley) 10/25/94"; #else -__RCSID("$NetBSD: setterm.c,v 1.66 2017/03/23 00:55:39 roy Exp $"); +__RCSID("$NetBSD: setterm.c,v 1.67 2018/10/02 17:35:44 roy Exp $"); #endif #endif /* not lint */ @@ -122,7 +122,7 @@ _cursesi_setterm(char *type, SCREEN *screen) if (screen->COLS <= 4) return ERR; - LINES = screen->LINES - __rippedlines(screen); + LINES = screen->LINES; COLS = screen->COLS; ESCDELAY = screen->ESCDELAY; TABSIZE = screen->TABSIZE; @@ -248,7 +248,7 @@ void _cursesi_resetterm(SCREEN *screen) { - LINES = screen->LINES - __rippedlines(screen); + LINES = screen->LINES; COLS = screen->COLS; ESCDELAY = screen->ESCDELAY; TABSIZE = screen->TABSIZE;