[net.lang.c] Abusing `curses' WINDOW structure

yost@bty.UUCP (Brian Yost) (09/20/86)

I have a question concerning termcap -vs- terminfo implementations
of the curses library.

I'm writing a program which uses the curses library, and need to
include a "print screen" type of utility.  Rather than reproducing
my display logic in order to print a text file image, I was thinking
of simply copying the screen from stdscr->_y directly into my textfile
(adding newlines where appropriate).  Something along these lines:

	PrintScr(f, win)
	FILE *f;
	WINDOW *win;
	{
		register short i, j;

		for (i = 0; i < win->_begy; i++)
			fputc('\n', f);

		for (i = 0; i < win->_maxy; i++) {
			for (j = 0; j < win->_begx; j++)
				fputc(' ', f);
			for (j = 0; j < win->_maxx; j++)
				fputc(win->_y[i][j], f);
			fputc('\n', f);
		}
		fflush(f);
	}

Now, my machine uses termcap, and this seems to work OK.  The question
is, is the WINDOW structure different in the terminfo implementation?
And if so, can the routine above be rewritten and made to work?

Please reply by mail, and thanks.

Brian Yost		 {clyde,topaz}!infopro!bty!yost

``This is a sic (sic) joke.''

guy@sun.uucp (Guy Harris) (09/24/86)

> I'm writing a program which uses the curses library, and need to
> include a "print screen" type of utility.  Rather than reproducing
> my display logic in order to print a text file image, I was thinking
> of simply copying the screen from stdscr->_y directly into my textfile
> (adding newlines where appropriate). ...
> Now, my machine uses termcap, and this seems to work OK.  The question
> is, is the WINDOW structure different in the terminfo implementation?
> And if so, can the routine above be rewritten and made to work?

"Abusing" is right!  Assuming you "know" what an unadvertised data structure
of a package looks like is a great way to get into trouble.

Yes, the window structure is different, although that sort of thing will
sort of work.  Don't do it, though.  There is a macro "winch" that returns
the "character" at the current position on the screen.  Use that instead.
"character" is in quotes, because it masks out the character attributes in
the 4BSD "curses" but not the S5 "curses".  You should mask the result of
that operation with 0177 if you just want the character.  (Note that your
sample code would not work properly for characters in standout mode; the raw
data in the screen buffer has high bits set if the character has an
attribute turned on.)

This stuff is documented both in the 4.2BSD and the S5 "curses"
documentation.  Please, people, before you decide you have no choice but to
sneak around the back door of a facility, check out the documentation - in
painful detail, if need be - first!
-- 
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.com (or guy@sun.arpa)

brett@wjvax.UUCP (Brett Galloway) (09/25/86)

In article <7565@sun.uucp> guy@sun.uucp (Guy Harris) writes:
>> I'm writing a program which uses the curses library, and need to
>> include a "print screen" type of utility.  Rather than reproducing
>> my display logic in order to print a text file image, I was thinking
>> of simply copying the screen from stdscr->_y directly into my textfile
>> (adding newlines where appropriate). ...
>> Now, my machine uses termcap, and this seems to work OK.  The question
>> is, is the WINDOW structure different in the terminfo implementation?
>> And if so, can the routine above be rewritten and made to work?
>
>"Abusing" is right!  Assuming you "know" what an unadvertised data structure
>of a package looks like is a great way to get into trouble.

One nit is that at least in 4.2 BSD the WINDOW structure IS advertised --
in appendix B of the document, Screen Updating and Cursor Movement
Optimization: A Library Package, by Kenneth Arnold.

Nonetheless, I do agree that use of the internals of WINDOW is
dangerous.  However, there are cases where such use is unavoidable.

I have a program in which a WINDOW is passed as an argument to a function
which needs to know the bounds of the window.  At least in 4.2BSD, I know
of no portable way to deduce that from the WINDOW structure, although the
fields are apparent enough.  Therefore, I used the _maxx and _maxy fields.
Further, the only portable way I know to get the current coordinates in a
window is to use getyx(win,y,x); but frequently one only wants one of the
coordinates and not both.  Getyx() forces the user to provide variables for
both coordinates, and then lint barks about a variable set but not used.
In short, curses (at least 4.2BSD) doesn't provide enough functionality
through macros to avoid nonportable uses.

More generally, I find curses well-named.  Even excluding the many bugs
that exist in the 4.2 BSD implementation, it does not provide sufficient
functionality, and it is virtually possible to extend its
functionality in a portable manner.  What I would like to see is someone
define and implement a new package similar to curses but more powerful.
This package should have a well-defined interface to the
underlying terminal driver library, allowing termcap and terminfo drivers
to be written for it, and even drivers for certain pc's.  It should also
have separate drivers for controlling system-dependent information, such
as the BSD job-control-dependent stuff in 4.2 BSD curses.  It
should provide a more coherent and general mechanism for performing
input through windows.  Finally, it should provide a rational method to
treat dynamic window resizing, which I understand occurs on at least one
system, SUN, and which can be expected to appear on others.

I don't understand why it would not be possible to take the display end of
one of the powerful, portable editors and turn it into a display package of
this sort.  If done right, the core of the package could be completely
portable across systems both unix and non-unix.  As such, the package could
become a de facto standard for video character display handling for the C
language.  Far too often people keep re-inventing this package for different
editors, even under unix systems (because curses isn't powerful or general
enough).

-- 
-------------
Brett Galloway
{pesnta,twg,ios,qubix,turtlevax,tymix,vecpyr,certes,isi}!wjvax!brett