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.