bugs in libcurses with test program and fixes

Cameron Davidson probe at mm730.uq.OZ
Tue Oct 15 11:51:23 AEST 1985


In the versions of libcurses I have seen, none has contained bug-free versions
of routines overlay and overwrite. Some don't work if the windows are not
starting at 0,0; some don't work if the overlaid window is not completely
within the boundary of the other, and some just don't work.

Below is a my version of overlay.c and if needed you can create a working
version of overwrite by removing the line "if( !isspace(*cp) )". It is not the
most efficient way to do overwrite but few seem to use it.

--------- overlay.c
# include	"curses.h"
# include	<ctype.h>

# define	min(a,b)	(a < b ? a : b)
# define	max(a,b)	(a > b ? a : b)

	/*
	 * find the maximum line and column of a window in screen coords
	 */
#define		MAX_LINE(win)	(win->_maxy + win->_begy)
#define		MAX_COL(win)	(win->_maxx + win->_begx)

/*
 *	This routine writes win1 on win2 non-destructively.
 *
 *	compile this routine and substitute for overlay.o in libcurses.a
 *	rewritten CJD UQ Min & Met Eng March 85 .
 */
overlay( win1, win2 )
	reg	WINDOW	    *win1, *win2;
{

	reg char	*cp, *end;
	reg int 	x2, i,
			endline, ytop,  y1,  y2,
			ncols,	xleft, x1start, x2start;

		/*
		 * ytop and xleft are starting line and col in terms
		 * of screen coordinates
		 */
	ytop = max( win1->_begy, win2->_begy );
	xleft = max( win1->_begx, win2->_begx );

		/* last line of  window 1 to look at */
	endline = min( MAX_LINE(win1),  MAX_LINE(win2) ) - win1->_begy;
	ncols	= min( MAX_COL(win1),  MAX_COL(win2) ) - xleft;
		/*
		 * y1 and x1start are starting row and line relative to window 1
		 */
	y1 = ytop - win1->_begy;
	x1start = xleft - win1->_begx;
	y2 = ytop - win2->_begy;
	x2start = xleft - win2->_begx;

	while ( y1 < endline ) {
		cp = &win1->_y[y1++][x1start];
		end = cp + ncols;
		x2 = x2start;
		for ( ; cp < end; cp++ ) {
			if ( !isspace( *cp ) ) {
				wmove( win2, y2, x2 );
				waddch( win2, *cp );
			}
			x2++;
		}
		y2++;
	}
}

=========== END OF overlay.c =============

------- cursetest.c

/*
 *	cursetest.c
 * a program to test overlay/overwrite routines in lib curses
 * the program should draw the following pattern in 4 places on the screen:

	 + + + + + + + + + +
	 + wwwwwwwwww+ + + +
	 + w        w+ + + +
	 + w    llllllllll +
	 + w    l   w+ + l +
	 + wwwwwlwwww+ + l +
	 + + + +l+ + + + l +
	 + + + +llllllllll +
	 + + + + + + + + + +
 *
 * and finally in the centre it should draw another pattern with the 'w'
 * and 'l' windows overlapping opposite corners of the base
 *	NOTE: only two sides of each should be visible
 */

#include	<stdio.h>
#include	<curses.h>


WINDOW	*Wbase,
	*Woverw,
	*Woverl;

main( ac, av )
	char	**av;
{
	initscr();
	normal_pattern( 0, 0 );
	normal_pattern( 10, 0 );
	normal_pattern( 0, 50 );
	normal_pattern( 10, 50 );
		/* now test when windows extend beyond base window */
	Wbase = newwin( 9, 19, 5, 25 );
	Woverw = newwin( 5, 10, 3, 22);
	Woverl = newwin( 5, 10, 11, 37);
	draw_pattern();
	mvcur( 0, COLS-1, LINES-1, 0);
}

	/*
	 * setup windows to draw patterns completely within base area
	 */
normal_pattern( base_y_begin, base_x_begin )
	int	base_y_begin, base_x_begin;
{
	if ( base_y_begin + 9 >= LINES  || base_x_begin + 19 >= COLS ) {
		fputs( "WON'T FIT\n", stderr);
		exit(1);
	}
	Wbase = newwin( 9, 19, base_y_begin, base_x_begin );
	Woverw = newwin( 5, 10, base_y_begin + 1, base_x_begin + 2);
	Woverl = newwin( 5, 10, base_y_begin + 3, base_x_begin + 7);
	draw_pattern();
}

draw_pattern( )
{
	register	int	line;

	for( line=0 ; line < 9 ; line++ )
		mvwaddstr( Wbase, line, 0, "+ + + + + + + + + +");
	wrefresh(Wbase);
	box( Woverw, 'w', 'w');
	box( Woverl, 'l', 'l');
	overwrite( Woverw, Wbase );
	wrefresh(Wbase);
	overlay( Woverl, Wbase );
	wrefresh(Wbase);
	delwin( Wbase );
	delwin( Woverw );
	delwin( Woverl );
}

======== END OF cursetest.c =========



More information about the Net.bugs mailing list