Handle cases where the application installs a SIGWINCH handler after the

curses one is installed by:

  1.  not reinstalling the curses one after restarting
  2.  not sending KEY_RESIZE

Also, update the size of curscr, stdscr and __virtscr to match the new
screen size, so that their sizes are always updated.

Fixes the cases where applications call endwin() and then refresh() in
their SIGWINCH handler (i.e. the resizing problems in PR pkg/27777).
This commit is contained in:
jdc 2006-08-25 17:04:32 +00:00
parent 753fce01f4
commit beb55bfff9

View File

@ -1,4 +1,4 @@
/* $NetBSD: tstp.c,v 1.33 2006/08/23 19:23:55 jdc Exp $ */
/* $NetBSD: tstp.c,v 1.34 2006/08/25 17:04:32 jdc Exp $ */
/*
* Copyright (c) 1981, 1993, 1994
@ -34,7 +34,7 @@
#if 0
static char sccsid[] = "@(#)tstp.c 8.3 (Berkeley) 5/4/94";
#else
__RCSID("$NetBSD: tstp.c,v 1.33 2006/08/23 19:23:55 jdc Exp $");
__RCSID("$NetBSD: tstp.c,v 1.34 2006/08/25 17:04:32 jdc Exp $");
#endif
#endif /* not lint */
@ -184,9 +184,23 @@ __restore_winchhandler(void)
#ifdef DEBUG
__CTRACE("__restore_winchhandler: %d\n", winch_set);
#endif
if (winch_set) {
sigaction(SIGWINCH, &owsa, NULL);
winch_set = 0;
if (winch_set > 0) {
struct sigaction cwsa;
sigaction(SIGWINCH, NULL, &cwsa);
if (cwsa.sa_handler == owsa.sa_handler) {
sigaction(SIGWINCH, &owsa, NULL);
winch_set = 0;
} else {
/*
* We're now using the programs WINCH handler,
* so don't restore the previous one.
*/
winch_set = -1;
#ifdef DEBUG
__CTRACE("cwsa.sa_handler = %p\n", cwsa.sa_handler);
#endif
}
}
}
@ -248,7 +262,12 @@ __restartwin(void)
__set_stophandler();
__set_winchhandler();
/* Check to see if the window size has changed */
/*
* Check to see if the window size has changed.
* If the application didn't update LINES and COLS,
* set the * resized flag to tell getch() to push KEY_RESIZE.
* Update curscr, stdscr and __virtscr to match the new size.
*/
if (ioctl(fileno(_cursesi_screen->outfd), TIOCGWINSZ, &win) != -1 &&
win.ws_row != 0 && win.ws_col != 0) {
if (win.ws_row != LINES) {
@ -260,6 +279,12 @@ __restartwin(void)
_cursesi_screen->resized = 1;
}
}
if (curscr->maxy != LINES || curscr->maxx != COLS)
wresize(curscr, LINES, COLS);
if (stdscr->maxy != LINES || stdscr->maxx != COLS)
wresize(stdscr, LINES, COLS);
if (__virtscr->maxy != LINES || __virtscr->maxx != COLS)
wresize(__virtscr, LINES, COLS);
/* save the new "default" terminal state */
(void) tcgetattr(fileno(_cursesi_screen->infd),