Getchar w/wout echo

Phong Vo[eww] kpv at ulysses.homer.nj.att.com
Sat Sep 17 02:26:20 AEST 1988


Hi all. I've just been alerted by a friend to this discussion on curses.
Following are a few comments on the posting from Terry Lambert.
He brought up many relevant points about earlier versions of curses.
I sympathize with his frustration. In fact, the same frustration
prompted me a few years back to rewrite curses. The following comments
are germane to this new version of curses that is currently distributed
by the System V folks at Summit.

In article <628 at wsccs.UUCP>, terry at wsccs.UUCP (Every system needs one) writes:
> In article <313 at quintus.UUCP>, ok at quintus.uucp (Richard A. O'Keefe) writes:
> > In article <65474 at sun.uucp> swilson at sun.UUCP (Scott Wilson) writes:
> > >>Who _cares_ how much baggage comes with Curses?
> > >I care, other people care.  Some of us are developing C programs
> > >on machines like the Macintosh where you are trying to fit your
> > >OS stuff, your C programming tools, and your C project onto two
> > >800K floppies.  This is comp.lang.c, not comp.lang.c.on.a.big.machine.
> > >with.megabytes.of.disk.space.and.maybe.paging.  Size is important.
> > >And curses is not universally available.
> 
> Bravo, Scott!

Even on a big machine, keeping down program size is good.
Similarly, even on fast machines, you still want your programs to be efficient.
The version of curses that I wrote accomplished both.
The library efficiency comes from the following considerations:
1. Consolidating similar functions and reuse code whenever they
   make sense. For example, wclear and werase are implemented in
   a single piece of code. This piece of code, in turn, uses
   wclrtoeol to do the actual clearing. You'll be amazed at how
   much code duplication there is in older version of curses.
   This happens both at the user-level functions and at the internal
   curses functions such as subparts of wrefresh.
2. Structuring code so that an application only has to include what
   it uses. For example, if an application does not need function
   key detection for input or using the insert/delete line capabilities
   for screen update, these pieces of codes are not linked with the a.out.
   Believe me, these pieces of code are not trivial in size and complexity.
3. The code structuring, in fact, extends to the overall architecture of
   the library as well. The library conceptually consists of two
   parts. The top part is what you tend to think of as libcurses.a.
   The lower part allows access to either the termcap or the terminfo
   database and to do input/output to the terminal. This means that
   if you don't like curses windows, you don't have to pay for its code.
   But you can still do things like time-out reads and function key
   detections as well as all the ioctl-related functions such as noecho
   or cbreak.
4. Developing new screen update and cursor movement algorithms.
   The old algorithms in the original curses from BSD as well as the
   one in System V.2 curses contain many ad-hoc special case code.
   The new screen update algorithm is more theoretically sound and handles
   capabilities such as insert/delete chars and insert/delete lines more
   gracefully. And yes, magic-cookies terminals such as the HP 26* and
   the TVI950 are all handled correctly and "optimally". Of course,
   with the TVI950 and similar terminals where the cookies actually
   occupy screen space, correctness has to be taken with a grain of salt.

> Besides, curses is seriously buggy in a number of places, like:
> 
> 	XS,XN,AM,SG,UG,GG,tputs(), etc.
>
The problems with magic-cookies, margin etc.  are all taken care of
in the new screen update and cursor movement algorithms.

> 
> I can site specific examples; the one you are probably curious about, is,
> however, tputs().
> 
> 	1) It doesn't necessarily cause an I/O to occur in a single write
> 	   operation.  This is BAD as transparent printing gets more
> 	   popular, and seriously kills paged-screen multiple sessions.
>
Tputs itself does not output anything.
It calls a user-supplied function to output characters. Since your application
supplies this function, it ought to do whatever buffering is necessary to
ensure a single write. The window-level <curses> uses a large buffer for
this purpose.

> 
> 	2) Not all implementations know about pad characters, and instead
> 	   print the numbers on the screen.
> 
> The tgetent() does not malloc() the save area; you have to know how big
> the maximum area is going to be beforehand when you're coding your own
> code; that's bad enough... but if some idiot has a monster termcap/info
> entry, curses can't be made happy without kludges.
> 
This is only a problem with termcap-based curses not terminfo-based versions.
At the risk of being flamed, I'll add that vi initialization procedure is
part of the reason for avoiding malloc-ing when a termcap entry is read.

> Curses depends (according to SVID) on the terminfo file.  This is a kludge.
> 
> 	1) It is not extensible.  It depends on a struct compiled into
> 	   libcurses.
> 
> 	2) It is hard to fix.  Most manufacturers do not provide source.
>
I am not a big fan of terminfo myself but there are advantages in terminfo
beyond termcap. Most of these have been mentioned before by others. I only
emphasizes here that this conversation started partially with the problem of
fat and slow curses. The use of terminfo does speed up an application start-up
time considerably and does reduce the size of the application somewhat.
As I like the flexibility of termcap, my local version of curses provides
support for both termcap and terminfo. In fact, at start-up time, an application
can decide on what database to use.

> 
> 	3) Many terminal definitions are wrong; specifically, SCO Xenix
> 	   is the only system I've seen that has gotten the Wyse-50 and
> 	   the Televideo 950 graphics correct, and I had a lot to do with
> 	   that.  True, it's usually broken in termcap, but at least I
> 	   can fix that.
> 
Have you communicated these problems with Tony Hansen (att!pegasus!hansen)?
He maintains the most up to date termcap/terminfo source that I know of.
I did have a TVI950 and many flavors of the HP26* terminals that I used
to test the screen update algorithm.

> 	4) It will not work with a true VT100 terminal or emualation.
> 	   Since VT100's are probably the most emulated terminal, this
> 	   is stupid, and obviously a result of poor or no testing.  I
> 	   expect a company like AT&T to be able to afford one of each
> 	   of the terminals they say they support, considering what they
> 	   are charging for a liscence.  To get it to work, you have to
> 	   lie and say you are on a 'vt100-nam' or remove the "AM" attr.
> 
As far as I know, curses work as advertised. In fact, I have programs that
people use regularly without problems on their PCs with vt-100 emulation
packages.

> Curses is brain-damaged with windows.  The window implementation is
> bad in that it
> 
> 	1) Does not understand hardware scrolling (though this is more
> 	   a terminfo fault, in that it can not be extended to fix
> 	   this deficiency anyway).
> 
The new update algorithm knows about hardware scrolling to all its gory variations.
This includes all things such as scrolling regions, memory retained above
and below, scroll forward/backward and so on.

> 	2) Can not move a window in the background while leaving another
> 	   in the foreground untouched.  This is the fault of the model
> 	   used to implement the window and it's memory mapping.  Layered
> 	   windows were chosen to avoid "excessive memory allocation" for
> 	   the save buffer area.  The point of diminishing returns, to
> 	   correct this misinformation, is when all windows are n x m or
> 	   larger where n+1 x m+1 is the virtual screen size.
> 
I only understand the first sentence. With SYSV curses, you can use wnoutrefresh
to do a sequence of virtual window refreshes until you get the screen that you
want then call doupdate to get the screen changed. Admittedly this is not the
same as being able to move windows in the same way that windows on bit-map
terminals are moved but it is not hard to implement the bit-map window movement
model on top of the curses model. In fact, I know of at least a few such
implementations. The basic curses model is very useful in appropriate applications.

> There are no field input primitives.
> 
Are you talking about a form-like facility?
There are many packages for doing that. They are implemented on top of curses.
I developed a language called IFS (Interpretive Frame System) to write
form and menu programs. In fact, this work is what got me to rewrite curses.
Older versions were just too buggy and fat and slow to do what I wanted to do.

> Typical code sizes change from:
> 
> 	270k -> 288k
> 	508k -> 527k
> 
> when libcurses  is used instead of libtermcap.  While it is true that
> disk space is no longer a problem on most systems, space on distribution
> media is limited.  This is an 18-19k increase, and can force an additional
> disk if there are several executables and distribution space is already
> tight (it has in 3 cases at our company, due to the target system no
> longer supporting termcap).
> 
With the new curses, the size problem will not be as bad. I don't have specific
numbers but I was told that the new curses is at least 20% smaller than older
ones (except the original BSD version but that does not do much).

> 
> Internationalization is hard when most implementations use the 8th bit
> for their own nefariousness (using a short yields 9 attr bits that way).
> 
> It is ridiculous to think that a company would ship a product *HEAVILY*
> dependant on it's display without writing their own code or buying
> someone elses.
>
The new library is internationalized. It knows all about the European
character sets which are relatively simple. It also knows about Oriental
character sets which have multiple-byte and multiple-column characters.

Now, I would like to comment on the unnecessary bashing of earlier curses
implementations and AT&T. When curses was first built some 10 years ago,
machines were small and slow and the international market was non-existent.
Every bit and byte counts so the library was implemnted to save as much
space as possible. It is unlikely that either Ken Arnold or Mark Horton were
thinking of the Japanese market around that time. In fact, they were rather
clever in making use of these bits and bytes to get the desired functionality.
Only in the past few years that considerations for these other markets
become prominent and we begin to see inadequacies in current software.
People like myself and others (David Korn, Warren Montgomery, Tony Hansen just
to name a few) in AT&T do spend considerable amount of time and effort 
to improve our software and  make them generally applicable.

	Phong Vo, att!ulysses!kpv, 201-582-4869
	AT&T Bell Labs, 600 Mountain Ave, Murray Hill, NJ07974



More information about the Comp.lang.c mailing list