A replacement for curses (Re: Abusing `curses' WINDOW structure)

Guido van Rossum guido at mcvax.uucp
Fri Oct 3 23:14:50 AEST 1986

In article <757 at wjvax.wjvax.UUCP> brett at wjvax.UUCP (Brett Galloway) writes:
>...					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

Well spoken.  Our group has designed and written a package which looks
like it would be a good start.  I am posting its specification here to
evoke reactions.  Implementations are available for Unix (termcap only,
runs under 4.{1,2,3} BSD, v7 and System 5) and MS-DOS (Monochrome or
Color (CGA, not EGA) monitor).  It wouldn't be hard to write a version
for the Macintosh, Amiga or Atari ST; in fact I once hacked together a
Mac version but it isn't in distributable form.

Some things it doesn't do for now: low-level character-I/O, comparable
to curses' move and addch; multiple overlapping windows (though
Emacs-style windows are trivial to implement on top of it).
What it does do, although it doesn't show from the specs, is extensive
optimization of redudant operations within a screen line (using
insert/delete character if available and useful, for instance).
Like Brett suggests, this package was designed as the display part of a
powerful, portable editor.  It has served in at least three different
editors I have written, one of which I am using right now to type this

If you want the code, write to me and I can mail it to you; it'll be
free but copyrighted and available for non-commercial use only.
However, the kind of reactions I would like to see most are those
proposing a kind of cooperation on the further development of this
package to fill the need of a larger group of users, and make it a
de-facto standard for portable screen/window manipulation.  Discussion
in this group seems also fine.

	Guido van Rossum, CWI, Amsterdam <guido at mcvax.uucp>

Note: these specs are public domain!
 * The VTRM package (Virtual TeRMinal).
 * This package uses termcap to determine the terminal capabilities.
 * The lines and columns of our virtual terminal are numbered 
 *	y = {0...lines-1} from top to bottom, and
 *	x = {0...cols-1} from left to right,
 * respectively.
 * The Visible Procedures in this package are:
 * trmstart(&lines, &cols, &flags)
 * 	Obligatory initialization call (sets tty modes etc.),
 * 	Returns the height and width of the screen to the integers
 * 	whose addresses are passed as parameters, and a word of flag
 *	bits that describe some capabilities (specs available on request).
 *	Function return value: 0 if all went well, an error code if there
 *	is any trouble.  No messages are printed for errors.
 * trmundefined()
 *	Sets internal representation of screen and attributes to undefined.
 *	This is necessary before a hard redraw, which would get optimized to
 *	oblivion.
 * trmsense(&y, &x)
 *	Performs a 'cursor sense' if available on the hardware.
 *	Returns the cursor position through its parameters
 *	after a possible manual change by the user; these are set
 *	to -1, -1 if no sense is possible (this may be a temporary
 *	or permanent condition).
 * trmputdata(yfirst, ylast, indent, data)
 * 	Fill lines {yfirst..ylast} with data, after skipping the initial
 *	'indent' positions. It is assumed that these positions do not contain
 *	anything dangerous (like standout cookies or null characters).
 * trmscrollup(yfirst, ylast, by)
 * 	Shift lines {yfirst..ylast} up by lines (down |by| if by < 0).
 * trmsync(y, x)
 * 	Call to output data to the terminal and set cursor position.
 * trmbell()
 *	Send a (possibly visible) bell, immediately (flushing stdout).
 * trmend()
 * 	Obligatory termination call (resets tty modes etc.).
 * You may call these as one or more cycles of:
 * 	+ trmstart
 * 	+    zero or more times any of the other routines
 * 	+ trmend
 * Trmend may be called even in the middle of trmstart; this makes it
 * possible to write an interrupt handler that resets the tty state
 * before exiting the program by simply calling trmend.
 * trminput()
 *	Return the next input character (with its parity bit cleared
 *	if any).  This value is a nonnegative int.  Returns -1 if the
 *	input can't be read any more.  Input is not echoed.
 * trmavail()
 *	Return 1 if there is an input character immediately available,
 *	0 if not.  Return -1 if unknown.
 * trminterrupt()
 *	Return 1 if an interrupt has occurred since the last call to
 *	trminput or trmavail, 0 else.  [Currently not implemented.]
 * trmsuspend()
 *	When called in the proper environment (4BSD with job control
 *	enabled), suspends the editor, temporarily popping back to
 *	the calling shell.  The caller should have called trmend()
 *	first, and must call trmstart again afterwards.
 *	BUG: there is a timing window where keyboard-generated
 *	signals (such as interrupt) can reach the program.

More information about the Comp.lang.c mailing list