Question for curses experts (with bug demo program)

Dean Pentcheff dean at violet.berkeley.edu
Sat Nov 26 09:32:57 AEST 1988


Thanks to those of you who responded to my request for help on a curses
problem involving overwrite().  

After further experimentation, I wrote a program to test the curses function
overwrite().  It tests overwrite()ing to and from windows and subwindows.  The
depressing upshot of trying it on a Vax running BSD4.3 and a 286 box running
SVR2 (AT clone running Microport 2.2.1-L) is that there are bugs (but not the
same ones) in overwrite() on both those systems.  The one version of curses
that seems to get it right is the public domain PCurses by Bjorn Larssen 
running under MS-DOS (based on Pavel Curtis's ncurses).

*********************
My conclusion has been to avoid the use of overwrite() altogether, since it's
operation is dubious under some curses versions.
*********************

Appended below is the program, for your amusement and edification.

-Dean

Dean Pentcheff        dean at violet.berkeley.edu
----------------------------------------------
As an adolescent I aspired to lasting fame, I craved factual certainty, and I
thirsted for a meaningful vision of human life - so I became a scientist.  This
is like becoming an archbishop so you can meet girls.               M. Cartmill

------- cut here --------
/* owt.c
 * Overwrite test for curses.
 * An program which demonstrates bugs (though subtly different ones!) in
 *   both BSD and SYSV curses.  Tested on BSD4.3 (Vax), SVR2 (Microport 2.2.1-L
 *   2.2.1-L running on an AT clone) and DOS (using PCurses by Bjorn Larsson
 *   Turbo C 1.5).  The only version which works is the public domain PCurses
 *   version.  Sigh.
 * Compile with one of -DBSD, -DSYSV, or -DTURBOC as appropriate.
 *
 * Moral of the story: Avoid overwrite() (and probably overlay()) like the 
 *   plague.
 *
 * Dean Pentcheff
 * dean at violet.berkeley.edu
 */

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

#ifdef	BSD
/* no special defines, etc. */
#endif	BSD

#ifdef	TURBOC
#include	<process.h>
typedef	int chtype;
#define	_y	_line
#endif	TURBOC

#ifdef	SYSV
typedef	char chtype;
#endif	SYSV

void prwin();
void dumpwin();
void status();
void prcurscr();

WINDOW	*statwin = (WINDOW *)NULL;

void
main()
{
	WINDOW	*win1;
	WINDOW	*win2;
	WINDOW	*win3;
	WINDOW	*win4;
	WINDOW	*bkup;
	WINDOW	*substd;
	WINDOW	*subcur;

	/* Curses initialization */
	initscr();
	noecho();
	cbreak();

	/* Create all the windows and subwindows we'll use */
	win1 = newwin(10, 10, 10, 10);
	win2 = subwin(stdscr, 10, 10, 10, 15);
	win3 = newwin(10, 10, 10, 65);
	win4 = newwin(10, 10, 10, 50);
	subcur = subwin(curscr, 10, 15, 10, 10);
	substd = subwin(stdscr, 10, 15, 10, 10);
	bkup   = newwin(10, 15, 0, 0);

	/* Write into a window and refresh it */
	box(win1, '1', '1');
	mvwprintw(win1, 2, 1, "hello in");
	mvwprintw(win1, 3, 1, "side of");
	mvwprintw(win1, 4, 1, "window 1");
	mvwprintw(win1, 5, 1, "4th line");
	wrefresh(win1);
	status("-> window  (win 1 written into)");
	getch();

	/* Overwrite a subwindow of stdscr from a window */
	overwrite(win1, win2);
	wrefresh(win2);
	status("window -> subwin  (win1->win2)");
	getch();

	/* Write into a subwindow */
	mvwprintw(win2, 4, 1, "window 2");
	box(win2, '2', '2');
	wrefresh(win2);
	status("-> subwin  (win2 written into)");
	getch();

	/* Write into a window, again */
	box(win3, '3', '3');
	mvwprintw(win3, 4, 1, "window 3");
	wrefresh(win3);
	status("-> window  (win 3 written into)");
	getch();

	/* Overwrite a window from a subwindow of stdscr */
	overwrite(win2, win3);
	wrefresh(win3);
	status("subwin -> window  (win2->win3)");
	getch();

	/* Write in a window, again */
	box(win4, '4', '4');
	mvwprintw(win4, 4, 1, "window 4");
	wrefresh(win4);
	status("-> window  (win 4 written into)");
	getch();

	/* Overwrite a window from a window */
	overwrite(win1, win4);
	wrefresh(win4);
	status("window -> window  (win1->win4)");
	getch();

	/* Write into a window, again */
	box(bkup, 'B', 'B');
	mvwprintw(bkup, 4, 1, "bkup window");
	wrefresh(bkup);
	status("-> window  (bkup written into)");
	getch();

	/* Overwrite a window from a subwindow of stdscr */
	overwrite(substd, bkup);
	wrefresh(bkup);
	status("subwin -> window  (substd->bkup)");
	getch();

	/* Overwrite a window from a subwindow of curscr */
	overwrite(subcur, bkup);
	wrefresh(bkup);
	status("subwin -> window  (subcur->bkup)");
	getch();

	/* Crawl into a subwindow of stdscr and show it to me */
	prwin(substd, "substd");

	/* Crawl into a subwindow of curscr and show it to me */
	prwin(subcur, "subcur");

	/* Crawl into curscr and show all of it to me.  This takes a special
	 * routine, since in BSD, at least, the _maxx and _maxy of curscr are
	 * both set to 0 (cute, eh?). */
	prcurscr();

	/* Show us the WINDOW structure elements of our windows and subwins */
	/*
	dumpwin(win1, "win1");
	dumpwin(win2, "win2");
	dumpwin(win3, "win3");
	dumpwin(win4, "win4");
	dumpwin(stdscr, "stdscr");
	dumpwin(curscr, "curscr");
	dumpwin(subcur, "subcur");
	dumpwin(bkup, "bkup");
	*/

	endwin();
}

void
prwin(win, name)
	WINDOW	*win;
	char	*name;
{
	chtype **cpp;
	chtype *cp;

	fprintf(stderr, "\n");
	fprintf(stderr, "== %s  flags: 0%o ================\n", name, win->_flags);
	for (cpp = win->_y;  cpp - win->_y  <  win->_maxy;  ++cpp) {
		fprintf(stderr, "|");
		for (cp = *cpp; cp - *cpp < win->_maxx; ++cp)
			fprintf(stderr, "%c", (char)*cp);
		fprintf(stderr, "|\n");
	}
	fprintf(stderr, "== %s end =======================\n", name);
}

void
prcurscr()
{
	chtype **cpp;
	chtype *cp;

	fprintf(stderr, "\n");
	fprintf(stderr, "== curscr  flags: 0%o ================\n", curscr->_flags);
	for (cpp = curscr->_y ;  cpp - curscr->_y  <  LINES-1;  ++cpp) {
		for (cp = *cpp; cp - *cpp < COLS-1; ++cp)
			fprintf(stderr, "%c", (char)*cp);
		fprintf(stderr, "\n");
	}
	fprintf(stderr, "== curscr end========================\n");
}

void
dumpwin(w, name)
	WINDOW	*w;
	char	*name;
{
	fprintf(stderr, "\n");
	fprintf(stderr, "== %s DUMP ================\n", name);
	fprintf(stderr, "cury: %02d curx: %02d  flags: 0%02o\n",
					w->_cury, w->_curx, w->_flags);
	fprintf(stderr, "maxy: %02d maxx: %02d  begy: %02d begx: %02d\n",
					w->_maxy, w->_maxx, w->_begy, w->_begx);
#ifdef	BSD
	fprintf(stderr, "firstch: %02d lastch: %02d  tmarg: %02d bmarg: %02d\n",
					*(w->_firstch), *(w->_lastch), w->_tmarg, w->_bmarg);
	fprintf(stderr, "clear: %d leave: %d scroll: %d use_idl: %d\n",
					w->_clear, w->_leave, w->_scroll, w->_use_idl);
	fprintf(stderr, "use_keypad: %d use_meta: %d nodelay: %d\n",
					w->_use_keypad, w->_use_meta, w->_nodelay);
#endif	BSD
}

void
status(string)
	char	*string;
{
	if (statwin == (WINDOW *)NULL)
		statwin = newwin(1, COLS, LINES-1, 0);
	werase(statwin);
	mvwaddstr(statwin, 0, 0, string);
	wrefresh(statwin);
}

#ifdef BULLSHIT
WINDOW Structure for BSD:
struct _win_st {
	short		_cury, _curx, _maxy, _maxx, _begy, _begx, _flags, _ch_off;
	bool		_clear, _leave, _scroll,
	char		**_y;
	short		*_firstch, *_lastch;
	struct		_win_st *_nextp, *_orig;
}

WINDOW Structure and flags for SYSV:
# define	_SUBWIN		01
# define	_ENDLINE	02
# define	_FULLWIN	04
# define	_SCROLLWIN	010
# define	_FLUSH		020
# define	_ISPAD		040
# define	_STANDOUT	0200
# define	_NOCHANGE	-1
struct _win_st {
	short	_cury, _curx, _maxy, _maxx, _begy, _begx, _flags;
	chtype	_attrs;
	bool	_clear, _leave, _scroll, _use_idl, _use_keypad, use_meta, _nodelay;
	chtype	**_y;
	short	*_firstch, *_lastch;
	short	_tmarg, _bmarg;
};

WINDOW structure for PCurses:
typedef struct
  {
  int	   _cury, _curx, _maxy, _maxx, _begy, _begx, _flags, _attrs, _tabsize;
  bool	   _clear, _leave, _scroll, _nodelay, _keypad;
  int    **_line;
  int	  *_minchng, *_maxchng;
  int	   _regtop, _regbottom;
  char	   _borderchars[8];
  }	WINDOW;
#endif BULLSHIT
Dean Pentcheff        dean at violet.berkeley.edu
----------------------------------------------
As an adolescent I aspired to lasting fame, I craved factual certainty, and I
thirsted for a meaningful vision of human life - so I became a scientist.  This
is like becoming an archbishop so you can meet girls.               M. Cartmill



More information about the Comp.unix.questions mailing list