Module Name: src Committed By: roy Date: Wed Jan 11 20:43:03 UTC 2017
Modified Files: src/lib/libcurses: Makefile curses_private.h mvwin.c resize.c screen.c setterm.c Added Files: src/lib/libcurses: ripoffline.c Log Message: Move the ripoffline logic out of screen.c and into ripoffline.c. Store ripped off lines in the SCREEN structure so we can repaint then when the terminal is resized. Fix mvwin(3) so it can move windows in the ripped off area. To generate a diff of this commit: cvs rdiff -u -r1.82 -r1.83 src/lib/libcurses/Makefile cvs rdiff -u -r1.58 -r1.59 src/lib/libcurses/curses_private.h cvs rdiff -u -r1.20 -r1.21 src/lib/libcurses/mvwin.c cvs rdiff -u -r1.24 -r1.25 src/lib/libcurses/resize.c cvs rdiff -u -r0 -r1.1 src/lib/libcurses/ripoffline.c cvs rdiff -u -r1.28 -r1.29 src/lib/libcurses/screen.c cvs rdiff -u -r1.60 -r1.61 src/lib/libcurses/setterm.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/Makefile diff -u src/lib/libcurses/Makefile:1.82 src/lib/libcurses/Makefile:1.83 --- src/lib/libcurses/Makefile:1.82 Tue Jan 10 10:13:24 2017 +++ src/lib/libcurses/Makefile Wed Jan 11 20:43:03 2017 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.82 2017/01/10 10:13:24 roy Exp $ +# $NetBSD: Makefile,v 1.83 2017/01/11 20:43:03 roy Exp $ # @(#)Makefile 8.2 (Berkeley) 1/2/94 .include <bsd.own.mk> @@ -22,9 +22,9 @@ SRCS= acs.c addbytes.c addch.c addchnstr idcok.c immedok.c inch.c inchstr.c initscr.c insch.c insdelln.c \ insertln.c instr.c keypad.c keyname.c leaveok.c line.c meta.c move.c \ mvwin.c newwin.c nodelay.c notimeout.c overlay.c overwrite.c pause.c \ - printw.c putchar.c refresh.c resize.c scanw.c screen.c scroll.c \ - scrollok.c setterm.c standout.c syncok.c timeout.c toucholap.c \ - touchwin.c tstp.c tty.c unctrl.c underscore.c + printw.c putchar.c refresh.c resize.c ripoffline.c scanw.c screen.c \ + scroll.c scrollok.c setterm.c standout.c syncok.c timeout.c \ + toucholap.c touchwin.c tstp.c tty.c unctrl.c underscore.c MAN= curses.3 curses_addch.3 curses_addchstr.3 curses_addstr.3 \ curses_attributes.3 curses_background.3 curses_border.3 \ Index: src/lib/libcurses/curses_private.h diff -u src/lib/libcurses/curses_private.h:1.58 src/lib/libcurses/curses_private.h:1.59 --- src/lib/libcurses/curses_private.h:1.58 Tue Jan 10 10:13:24 2017 +++ src/lib/libcurses/curses_private.h Wed Jan 11 20:43:03 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: curses_private.h,v 1.58 2017/01/10 10:13:24 roy Exp $ */ +/* $NetBSD: curses_private.h,v 1.59 2017/01/11 20:43:03 roy Exp $ */ /*- * Copyright (c) 1998-2000 Brett Lymn @@ -189,6 +189,13 @@ struct __pair { typedef struct keymap keymap_t; + +#define MAX_RIPS 5 +struct __ripoff { + int nlines; + WINDOW *win; +}; + /* this is the encapsulation of the terminal definition, one for * each terminal that curses talks to. */ @@ -201,8 +208,8 @@ struct __screen { int lx, ly; /* loop parameters for refresh */ int COLS; /* Columns on the screen. */ int LINES; /* Lines on the screen. */ - int ripped_top; /* Lines ripped from the top of the screen. */ - int ripped_bottom; /* Lines ripped from the bottom. */ + int nripped; /* Number of ripofflines. */ + struct __ripoff ripped[MAX_RIPS]; /* ripofflines. */ int ESCDELAY; /* Delay between keys in esc seq's. */ #define ESCDELAY_DEFAULT 300 /* milliseconds. */ int TABSIZE; /* Size of a tab. */ @@ -342,6 +349,9 @@ void __restore_meta_state(void); void __restore_termios(void); void __restore_stophandler(void); void __restore_winchhandler(void); +int __ripoffscreen(SCREEN *, int *); +void __ripoffresize(SCREEN *); +int __rippedlines(const SCREEN *); void __save_termios(void); void __set_color(WINDOW *win, attr_t attr); void __set_stophandler(void); Index: src/lib/libcurses/mvwin.c diff -u src/lib/libcurses/mvwin.c:1.20 src/lib/libcurses/mvwin.c:1.21 --- src/lib/libcurses/mvwin.c:1.20 Fri Jan 6 13:53:18 2017 +++ src/lib/libcurses/mvwin.c Wed Jan 11 20:43:03 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: mvwin.c,v 1.20 2017/01/06 13:53:18 roy Exp $ */ +/* $NetBSD: mvwin.c,v 1.21 2017/01/11 20:43:03 roy Exp $ */ /* * Copyright (c) 1981, 1993, 1994 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "@(#)mvwin.c 8.2 (Berkeley) 5/4/94"; #else -__RCSID("$NetBSD: mvwin.c,v 1.20 2017/01/06 13:53:18 roy Exp $"); +__RCSID("$NetBSD: mvwin.c,v 1.21 2017/01/11 20:43:03 roy Exp $"); #endif #endif /* not lint */ @@ -102,7 +102,8 @@ mvwin(WINDOW *win, int by, int bx) WINDOW *orig; int dy, dx; - if (by < 0 || by + win->maxy > LINES || bx < 0 || bx + win->maxx > COLS) + if (by < 0 || by + win->maxy > win->screen->LINES || + bx < 0 || bx + win->maxx > win->screen->COLS) return ERR; dy = by - win->begy; dx = bx - win->begx; @@ -117,9 +118,9 @@ mvwin(WINDOW *win, int by, int bx) } while (win != orig); } else { if (by < orig->begy || win->maxy + dy > orig->maxy) - return (ERR); + return ERR; if (bx < orig->begx || win->maxx + dx > orig->maxx) - return (ERR); + return ERR; win->begy = by; win->begx = bx; __swflags(win); Index: src/lib/libcurses/resize.c diff -u src/lib/libcurses/resize.c:1.24 src/lib/libcurses/resize.c:1.25 --- src/lib/libcurses/resize.c:1.24 Tue Jan 10 23:28:45 2017 +++ src/lib/libcurses/resize.c Wed Jan 11 20:43:03 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: resize.c,v 1.24 2017/01/10 23:28:45 roy Exp $ */ +/* $NetBSD: resize.c,v 1.25 2017/01/11 20:43:03 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.24 2017/01/10 23:28:45 roy Exp $"); +__RCSID("$NetBSD: resize.c,v 1.25 2017/01/11 20:43:03 roy Exp $"); #endif #endif /* not lint */ @@ -163,11 +163,19 @@ resizeterm(int nlines, int ncols) __CTRACE(__CTRACE_WINDOW, "resizeterm: (%d, %d)\n", nlines, ncols); #endif + if (!is_term_resized(nlines, ncols)) return OK; result = resize_term(nlines, ncols); + + /* Screen contents are unknown, libcurses is not libpanel, we don't + * know the correct draw order. */ clearok(curscr, TRUE); + + /* We know how to repaint the ripoffs */ + __ripoffresize(_cursesi_screen); + return result; } @@ -180,6 +188,7 @@ resize_term(int nlines, int ncols) { WINDOW *win; struct __winlist *list; + int rlines; #ifdef DEBUG __CTRACE(__CTRACE_WINDOW, "resize_term: (%d, %d)\n", nlines, ncols); @@ -192,11 +201,13 @@ resize_term(int nlines, int ncols) return ERR; if (__resizeterm(__virtscr, nlines, ncols) == ERR) return ERR; - nlines -= _cursesi_screen->ripped_top - _cursesi_screen->ripped_bottom; - if (__resizeterm(stdscr, nlines, ncols) == ERR) + rlines = nlines - __rippedlines(_cursesi_screen); + if (__resizeterm(stdscr, rlines, ncols) == ERR) return ERR; - LINES = nlines; + _cursesi_screen->LINES = nlines; + _cursesi_screen->COLS = ncols; + LINES = rlines; COLS = ncols; /* tweak the flags now that we have updated the LINES and COLS */ Index: src/lib/libcurses/screen.c diff -u src/lib/libcurses/screen.c:1.28 src/lib/libcurses/screen.c:1.29 --- src/lib/libcurses/screen.c:1.28 Tue Jan 10 10:13:24 2017 +++ src/lib/libcurses/screen.c Wed Jan 11 20:43:03 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: screen.c,v 1.28 2017/01/10 10:13:24 roy Exp $ */ +/* $NetBSD: screen.c,v 1.29 2017/01/11 20:43:03 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.28 2017/01/10 10:13:24 roy Exp $"); +__RCSID("$NetBSD: screen.c,v 1.29 2017/01/11 20:43:03 roy Exp $"); #endif #endif /* not lint */ @@ -45,41 +45,8 @@ __RCSID("$NetBSD: screen.c,v 1.28 2017/0 static int filtered; -/* List of ripoffline calls */ -#define NRIPS 5 -static struct ripoff { - int nlines; - int (*init)(WINDOW *, int); -} ripoffs[NRIPS]; -static int nrips; -/* - * filter has to be called before either initscr or newterm. - */ -void -filter(void) -{ - - filtered = TRUE; -} - -/* - *ripoffline -- - * Ripoff a line from the top of bottom of stdscr. - * Must be called before initscr or newterm. - */ -int -ripoffline(int line, int (*init)(WINDOW *, int)) -{ - - if (nrips >= NRIPS || init == NULL) - return ERR; /* This makes sense, but not standards compliant. */ - if (line == 0) - return OK; - ripoffs[nrips].nlines = line < 0 ? -1 : 1; - ripoffs[nrips++].init = init; - return OK; -} +static void __delscreen(SCREEN *); /* * set_term -- @@ -98,8 +65,7 @@ set_term(SCREEN *new) old_screen->rawmode = __rawmode; old_screen->noqch = __noqch; old_screen->COLS = COLS; - old_screen->LINES = LINES - + old_screen->ripped_top + old_screen->ripped_bottom; + old_screen->LINES = LINES + __rippedlines(old_screen); old_screen->COLORS = COLORS; old_screen->COLOR_PAIRS = COLOR_PAIRS; old_screen->GT = __GT; @@ -114,7 +80,7 @@ set_term(SCREEN *new) __rawmode = new->rawmode; __noqch = new->noqch; COLS = new->COLS; - LINES = new->LINES - new->ripped_top - new->ripped_bottom; + LINES = new->LINES - __rippedlines(new); COLORS = new->COLORS; COLOR_PAIRS = new->COLOR_PAIRS; __GT = new->GT; @@ -151,7 +117,7 @@ newterm(char *type, FILE *outfd, FILE *i { SCREEN *new_screen; char *sp; - int i; + int rtop; sp = type; if (type == NULL && (sp = getenv("TERM")) == NULL) @@ -211,43 +177,14 @@ newterm(char *type, FILE *outfd, FILE *i if ((new_screen->__virtscr = __newwin(new_screen, 0, 0, 0, 0, FALSE)) == NULL) - { - delwin(new_screen->curscr); goto error_exit; - } - for (i = 0; i < nrips; i++) { - const struct ripoff *r = &ripoffs[i]; - int nlines = r->nlines < 0 ? -r->nlines : r->nlines; - WINDOW *w; - - w = __newwin(new_screen, nlines, 0, - r->nlines < 0 ? LINES + r->nlines : new_screen->ripped_top, - 0, FALSE); - if (w != NULL) { - if (r->nlines < 0) - new_screen->ripped_bottom += nlines; - else - new_screen->ripped_top += nlines; - LINES -= nlines; - } - r->init(w, COLS); -#ifdef DEBUG - if (w != NULL) - __CTRACE(__CTRACE_SCREEN, - "newterm: ripped %d lines from the %s\n", - nlines, r->nlines < 0 ? "bottom" : "top"); -#endif - } - nrips = 0; /* Reset the stack. */ + if (__ripoffscreen(new_screen, &rtop) == ERR) + goto error_exit; - new_screen->stdscr = __newwin(new_screen, LINES, 0, - new_screen->ripped_top, 0, FALSE); - if (new_screen->stdscr == NULL) { - delwin(new_screen->curscr); - delwin(new_screen->__virtscr); + new_screen->stdscr = __newwin(new_screen, LINES, 0, rtop, 0, FALSE); + if (new_screen->stdscr == NULL) goto error_exit; - } clearok(new_screen->stdscr, 1); @@ -278,8 +215,7 @@ newterm(char *type, FILE *outfd, FILE *i return new_screen; error_exit: - if (new_screen->term != NULL) - (void)del_curterm(new_screen->term); + __delscreen(new_screen); free(new_screen->unget_list); free(new_screen); @@ -294,21 +230,12 @@ newterm(char *type, FILE *outfd, FILE *i void delscreen(SCREEN *screen) { - struct __winlist *list; #ifdef DEBUG __CTRACE(__CTRACE_SCREEN, "delscreen(%p)\n", screen); #endif - /* free up the terminfo stuff */ - del_curterm(screen->term); - /* walk the window list and kill all the parent windows */ - while ((list = screen->winlistp) != NULL) { - delwin(list->winp); - if (list == screen->winlistp) - /* sanity - abort if window didn't remove itself */ - break; - } + __delscreen(screen); /* free the storage of the keymaps */ _cursesi_free_keymap(screen->base_keymap); @@ -319,3 +246,21 @@ delscreen(SCREEN *screen) _cursesi_screen = NULL; free(screen); } + +static void +__delscreen(SCREEN *screen) +{ + struct __winlist *list; + + /* free up the terminfo stuff */ + if (screen->term != NULL) + del_curterm(screen->term); + + /* walk the window list and kill all the parent windows */ + while ((list = screen->winlistp) != NULL) { + delwin(list->winp); + if (list == screen->winlistp) + /* sanity - abort if window didn't remove itself */ + break; + } +} Index: src/lib/libcurses/setterm.c diff -u src/lib/libcurses/setterm.c:1.60 src/lib/libcurses/setterm.c:1.61 --- src/lib/libcurses/setterm.c:1.60 Tue Jan 10 10:13:24 2017 +++ src/lib/libcurses/setterm.c Wed Jan 11 20:43:03 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: setterm.c,v 1.60 2017/01/10 10:13:24 roy Exp $ */ +/* $NetBSD: setterm.c,v 1.61 2017/01/11 20:43:03 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.60 2017/01/10 10:13:24 roy Exp $"); +__RCSID("$NetBSD: setterm.c,v 1.61 2017/01/11 20:43:03 roy Exp $"); #endif #endif /* not lint */ @@ -150,7 +150,7 @@ _cursesi_setterm(char *type, SCREEN *scr if (screen->COLS <= 4) return ERR; - LINES = screen->LINES - screen->ripped_top - screen->ripped_bottom; + LINES = screen->LINES - __rippedlines(screen); COLS = screen->COLS; ESCDELAY = screen->ESCDELAY; TABSIZE = screen->TABSIZE; @@ -282,7 +282,7 @@ void _cursesi_resetterm(SCREEN *screen) { - LINES = screen->LINES - screen->ripped_top - screen->ripped_bottom; + LINES = screen->LINES - __rippedlines(screen); COLS = screen->COLS; ESCDELAY = screen->ESCDELAY; TABSIZE = screen->TABSIZE; Added files: Index: src/lib/libcurses/ripoffline.c diff -u /dev/null src/lib/libcurses/ripoffline.c:1.1 --- /dev/null Wed Jan 11 20:43:03 2017 +++ src/lib/libcurses/ripoffline.c Wed Jan 11 20:43:03 2017 @@ -0,0 +1,156 @@ +/* $NetBSD: ripoffline.c,v 1.1 2017/01/11 20:43:03 roy Exp $ */ + +/*- + * Copyright (c) 2017 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Roy Marples. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +#ifndef lint +__RCSID("$NetBSD: ripoffline.c,v 1.1 2017/01/11 20:43:03 roy Exp $"); +#endif /* not lint */ + +#include "curses.h" +#include "curses_private.h" + +/* List of ripoffline calls */ +static struct ripoff { + int nlines; + int (*init)(WINDOW *, int); +} ripoffs[MAX_RIPS]; +static int nrips; + +/* + * ripoffline -- + * Ripoff a line from the top of bottom of stdscr. + * Must be called before initscr or newterm. + */ +int +ripoffline(int line, int (*init)(WINDOW *, int)) +{ + +#ifdef DEBUG + __CTRACE(__CTRACE_SCREEN, "ripoffline: %d\n", line); +#endif + + if (nrips >= MAX_RIPS || init == NULL) + return ERR; /* This makes sense, but not standards compliant. */ + if (line == 0) + return OK; + ripoffs[nrips].nlines = line < 0 ? -1 : 1; + ripoffs[nrips++].init = init; + return OK; +} + +/* + * __rippedlines -- + * Returns the number of ripped lines from the screen. + */ +int +__rippedlines(const SCREEN *screen) +{ + const struct __ripoff *rip; + int i, n; + + n = 0; + for (i = 0, rip = screen->ripped; i < screen->nripped; i++, rip++) { + if (rip->nlines < 0) + n += -rip->nlines; + else + n += rip->nlines; + } + return n; +} + +/* + * __ripoffscreen -- + * Rips lines from the screen by creating a WINDOW per ripoffline call. + * Although the POSIX API only allows for one line WINDOWS to be created, + * this implemenation allows for N lines if needed. + */ +int +__ripoffscreen(SCREEN *screen, int *rtop) +{ + int i, nlines; + const struct ripoff *srip; + struct __ripoff *rip; + WINDOW *w; + + *rtop = 0; + rip = screen->ripped; + for (i = 0, srip = ripoffs; i < nrips; i++, srip++) { + nlines = srip->nlines < 0 ? -srip->nlines : srip->nlines; + w = __newwin(screen, nlines, 0, + srip->nlines < 0 ? LINES - nlines : *rtop, + 0, 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->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"); +#endif + } + nrips = 0; /* Reset the stack. */ + return OK; +} + +/* + * __ripoffresize -- + * Called from resizeterm to ensure the ripped off lines are correctly + * placed and refreshed. + */ +void +__ripoffresize(SCREEN *screen) +{ + int rbot = _cursesi_screen->LINES, i; + struct __ripoff *rip; + + for (i = 0, rip = _cursesi_screen->ripped; + i < _cursesi_screen->nripped; + i++, rip++) + { + if (rip->nlines > 0) + touchwin(rip->win); + else { + /* Reposition the lower windows. */ + mvwin(rip->win, rbot + rip->nlines, 0); + rbot += rip->nlines; + } + wnoutrefresh(rip->win); + } +}