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