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
This commit is contained in:
roy 2018-10-02 17:35:44 +00:00
parent 277582e5d7
commit d34c5681a4
9 changed files with 80 additions and 55 deletions

View File

@ -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);

View File

@ -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

View File

@ -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 <sys/cdefs.h>
#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;

View File

@ -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;
}

View File

@ -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)

View File

@ -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 &&

View File

@ -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 <sys/cdefs.h>
#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

View File

@ -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;

View File

@ -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;