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