ncurses is a library for screen and terminal handling. It includes basic functionality that was traditionally supplied by libraries like termcap such as clearing the screen and changing text colors It also has support for more sophisticated pseudo-GUI elements like text based menus and windows.

It is part of the GNU project and is thus licensed under the GPL. It is a standard part of any linux system I've ever encountered. It (or one of its equivalents) is commonly used for anything from running a shell to menuconfiging the linux kernel.

The current version is 5.3. However, it is actively maintained and there are official patches to this which are essential if you're using gcc-3.x, compiling for a powerpc, or like secure, stable software. The latest patch, as a gziped shar is available at ftp://dickey.his.com/ncurses/5.2/something.sh.gz

Technical writeup ahead. Non-programmers may waste valuable seconds of their lives unless they turn back NOW... Seconds you may never get back.

M'kay... one of the big caveats that has kept me from writing any serious programs using ncurses (until now) is that ncurses and xterm* have had trouble getting along in the past. That is, an ncurses program that ran fine on a real vterm might also run fine on a default-sized xterm window, but start to spew sheared garbage when invoked in an oversized xterm.

To add insult to injury, all (third-party) ncurses-based programs that I tried under similar conditions would work fine... apparently they had coaxed the secret out of the murky depths of the swampy documention, but no such secrets had made their way to the wholesome sunlit world above.

After some experimentation, I have come up with the following workaround, and dammit, I'm probably not the first (or the last!) person to work this out on his own.

if( strcmp(getenv("TERM"), "xterm") == 0 ) {
  /* use the termcap entries for a default-sized xterm */
    use_env(FALSE);
} else {
 /* use LINES and COLUMNS environment variables, if available */
    use_env(TRUE);
}

Even with the workaround, you might want to avoid writing to the very bottom-right character-slot on the screen, as some xterms are stupid and will leak some extra characters. Ever wonder why curses-based programs (Nethack, vim, et al.) always seem to use the bottom line of screen real estate as a status line?

It's really not very difficult, but the documentation is shoddy in places, and it's really something that ought to be written down somewhere.

So, fellow code-happy Everythingians, you have one less excuse not to try ncurses! :-)


* and Eterm and rxvt
(PS. If you, intrepid reader, know of a better way, /msg me posthaste!)
Addendum, 21 Dec 2002: When using colors, you may also want to put use_default_colors(); someplace after initscr(); but before actually drawing things onscreen. This prevents your background colors from "leaking" off the edge of the drawable screen. (Without it, ncurses assumes that the default background color is COLOR_BLACK, which may prevent you from seeing your nice Eterm backgrounds, f'rinstance. :-)
Bigger addendum, 21 Dec 2002:

Another way to avoid the xterm nastiness is to make sure you write to the entire width of the screen.

So, instead of the above snippet, you'd use use_env(TRUE); before the initscr() sequence, and use the macro getmaxyx(stdscr, y, x); to get the screen's dimensions. (Your screen's coordinates range from (0,0), to (x-1, y-1).)

If the xterm is resized, you'll have to tell ncurses to resize its idea of what the screen ought to look like as well. On being resized, xterm sends the applications running under it a signal SIGWINCH, and you can trap that signal and tell ncurses to do its resizing thing.

(Fortunately, that technique is fairly well documented. See the ncurses FAQ: http://dickey.his.com/ncurses/ncurses.faq.html#handle_resize and the manpage for signal(2). An example of how it might look in practice can be found at http://www.apmaths.uwo.ca/~xli/ncurses.html#xterm )


grabakskd says re your writeup for coding ncurses (for use in an xterm), try the getmaxyx(3X) macro for your initial window size; and if you handle the SIGWINCH signal and make appropriate use of wresize(3X) and resizeterm(3X), you can cleanly rescale your application when the user resizes their xterm window.

Log in or register to write something here or to contact authors.