Subject: Re: pkg/37129: ncmpc segvaults & dumps core when xterm is resized
To: None <pkg-manager@netbsd.org, gnats-admin@netbsd.org,>
From: Julian Coleman <jdc@coris.org.uk>
List: pkgsrc-bugs
Date: 10/24/2007 20:45:02
The following reply was made to PR pkg/37129; it has been noted by GNATS.

From: Julian Coleman <jdc@coris.org.uk>
To: gnats-bugs@netbsd.org
Cc: jdc@netbsd.org
Subject: Re: pkg/37129: ncmpc segvaults & dumps core when xterm is resized
Date: Wed, 24 Oct 2007 21:42:47 +0100

 > I need to check what the ncurses-compatible fix is for this - probably to
 > move the origin of any window which is not the size of the screen and whose
 > bottom or right margins have been shrunk.
 
 It seems that the fix is to only resize the standard curses windows.  I
 believe that the following patch will fix ncmpc.  If you're able to test
 it, that would be great.
 
 I still need to check the behaviour when resizing a window containing
 sub-windows.
 
 Thanks,
 
 J
 
   - - 8< - - - - - - - - - - - - - Cut here - - - - - - - - - - - - - >8 - -
 diff -ur /usr/src/lib/libcurses/curses_screen.3 ./curses_screen.3
 --- /usr/src/lib/libcurses/curses_screen.3	2007-07-13 12:16:11.000000000 +0100
 +++ ./curses_screen.3	2007-10-24 21:10:38.000000000 +0100
 @@ -30,7 +30,7 @@
  .\" SUCH DAMAGE.
  .\"
  .\"
 -.Dd February 24, 2004
 +.Dd October 24, 2007
  .Dt CURSES_SCREEN 3
  .Os
  .Sh NAME
 @@ -151,6 +151,11 @@
  with the updated number of lines and columns.
  This will resize the curses internal data structures to accommodate the
  changed terminal geometry.
 +The
 +.Dv curscr
 +and
 +.Dv stdscr
 +windows will be resized to fit the new screen size.
  The application must redraw the screen after a call to
  .Fn resizeterm .
  .Pp
 diff -ur /usr/src/lib/libcurses/curses_window.3 ./curses_window.3
 --- /usr/src/lib/libcurses/curses_window.3	2006-01-15 16:57:45.000000000 +0000
 +++ ./curses_window.3	2007-10-24 21:10:00.000000000 +0100
 @@ -30,7 +30,7 @@
  .\" SUCH DAMAGE.
  .\"
  .\"
 -.Dd January 15, 2006
 +.Dd October 24, 2007
  .Dt CURSES_WINDOW 3
  .Os
  .Sh NAME
 @@ -192,9 +192,6 @@
  .Fa begin_y
  +
  .Fa cols .
 -If the terminal, or in the case of a subwindow the enclosing window,
 -is resized then the window size will be recalculated so that the window
 -ends the same number of columns from the far edge.
  .Pp
  .Fn subwin
  is similar to
 @@ -227,7 +224,14 @@
  .Fn wresize
  resizes the specified window to the new number of lines and columns
  given, all internal curses structures are resized.
 -The application must redraw the window after it has been resized.
 +In the case of a subwindow, if the enclosing window is resized, then the
 +window size will be recalculated so that the window ends the same number
 +of columns from the far edge.
 +The application must redraw the window after it has been resized.  Note that
 +.Dv curscr
 +and
 +.Dv stdscr
 +can not be resized to be larger than the size of the screen.
  .Sh RETURN VALUES
  Functions returning pointers will return
  .Dv NULL
 diff -ur /usr/src/lib/libcurses/resize.c ./resize.c
 --- /usr/src/lib/libcurses/resize.c	2007-08-27 20:54:29.000000000 +0100
 +++ ./resize.c	2007-10-24 20:59:38.000000000 +0100
 @@ -49,6 +49,7 @@
  #include "curses.h"
  #include "curses_private.h"
  
 +static int __resizeterm(WINDOW *win, int nlines, int ncols);
  static int __resizewin(WINDOW *win, int nlines, int ncols);
  
  /*
 @@ -71,15 +72,17 @@
  	nlines = req_nlines;
  	ncols = req_ncols;
  	if (win->orig == NULL) {
 -		/* bound window to screen */
 -		if (win->begy + nlines > LINES)
 -			nlines = 0;
 -		if (nlines <= 0)
 -			nlines += LINES - win->begy;
 -		if (win->begx + ncols > COLS)
 -			ncols = 0;
 -		if (ncols <= 0)
 -			ncols += COLS - win->begx;
 +		/* bound "our" windows by the screen size */
 +		if (win == curscr || win == __virtscr || win == stdscr) {
 +			if (win->begy + nlines > LINES)
 +				nlines = 0;
 +			if (nlines <= 0)
 +				nlines += LINES - win->begy;
 +			if (win->begx + ncols > COLS)
 +				ncols = 0;
 +			if (ncols <= 0)
 +				ncols += COLS - win->begx;
 +		}
  	} else {
  		/* subwins must fit inside the parent - check this */
  		if (win->begy + nlines > win->orig->begy + win->orig->maxy)
 @@ -118,7 +121,6 @@
  {
  	WINDOW *win;
  	struct __winlist *list;
 -	int newlines, newcols;
  
  	  /* don't worry if things have not changed... we would like to
  	     do this but some bastard programs update LINES and COLS before
 @@ -130,25 +132,12 @@
  	__CTRACE(__CTRACE_WINDOW, "resizeterm: (%d, %d)\n", nlines, ncols);
  #endif
  
 -
 -	for (list = _cursesi_screen->winlistp; list != NULL; list = list->nextp) {
 -		win = list->winp;
 -
 -		newlines = win->reqy;
 -		if (win->begy + newlines >= nlines)
 -			newlines = 0;
 -		if (newlines == 0)
 -			newlines = nlines - win->begy;
 -
 -		newcols = win->reqx;
 -		if (win->begx + newcols >= ncols)
 -			newcols = 0;
 -		if (newcols == 0)
 -			newcols = ncols - win->begx;
 -
 -		if (__resizewin(win, newlines, newcols) != OK)
 -			return ERR;
 -	}
 +	if (__resizeterm(curscr, nlines, ncols) == ERR)
 +		return ERR;
 +	if (__resizeterm(__virtscr, nlines, ncols) == ERR)
 +		return ERR;
 +	if (__resizeterm(stdscr, nlines, ncols) == ERR)
 +		return ERR;
  
  	LINES = nlines;
  	COLS = ncols;
 @@ -166,6 +155,30 @@
  }
  
  /*
 + * __resizeterm
 + *	Setup window for resizing.
 + */
 +static int
 +__resizeterm(WINDOW *win, int nlines, int ncols)
 +{
 +	int newlines, newcols;
 +
 +	newlines = win->reqy;
 +	if (win->begy + newlines >= nlines)
 +		newlines = 0;
 +	if (newlines == 0)
 +		newlines = nlines - win->begy;
 +
 +	newcols = win->reqx;
 +	if (win->begx + newcols >= ncols)
 +		newcols = 0;
 +	if (newcols == 0)
 +		newcols = ncols - win->begx;
 +
 +	return __resizewin(win, newlines, newcols);
 +}
 +
 +/*
   * __resizewin --
   *	Resize the given window.
   */
   - - 8< - - - - - - - - - - - - - Cut here - - - - - - - - - - - - - >8 - -
 -- 
   My other computer also runs NetBSD    /        Sailing at Newbiggin
         http://www.netbsd.org/        /   http://www.newbigginsailingclub.org/