Path: utzoo!attcan!uunet!seismo!sundc!pitstop!sun!amdcad!ames!mailrus!uflorida!gatech!ulysses!kpv From: kpv@ulysses.homer.nj.att.com (Phong Vo[eww]) Newsgroups: comp.lang.c Subject: Re: Getchar w/wout echo Summary: curses has been much improved since you last looked Message-ID: <10608@ulysses.homer.nj.att.com> Date: 16 Sep 88 16:26:20 GMT References: <371@marob.MASA.COM> <225800052@uxe.cso.uiuc.edu> <65197@sun.uucp> <628@wsccs.UUCP> Organization: AT&T Bell Laboratories, Murray Hill Lines: 208 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@wsccs.UUCP>, terry@wsccs.UUCP (Every system needs one) writes: > In article <313@quintus.UUCP>, ok@quintus.uucp (Richard A. O'Keefe) writes: > > In article <65474@sun.uucp> swilson@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 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