DevDungeon
- Labs
Knowledge
Social
DevDungeon
Knowledge
Social
This is an old revision of the document!
https://invisible-island.net/ncurses/announce.html
Ncurses ftp://ftp.invisible-island.net/ncurses/ncurses.tar.gz
In Debian, the easiest way to install is with:
sudo apt install libncurses6
To build from source, get the latest version from the download page.
# Download ncurses wget ftp://ftp.invisible-island.net/ncurses/ncurses.tar.gz # Extract tar xzf ncurses.tar.gz # Enter the directory cd ncurses-6.3 # Typical build steps ./configure --help | less # Set to install in home rather than system ./configure --prefix=$HOME/.local --with-shared make make install
If you install to your home rather than the system, when compiling, linking, and running, you may need to specify where the header files and libraries are. With gcc
, that's the -I
and -L
options. When running, set the environment variable LD_LIBRARY_PATH
to include path to libraries.
There are a few man
pages that are particularly helpful. The man pages with API documentation will be in ~/.local/share/man/man{1,3,5,7}
if you used the home prefix.
If you aren't sure which man pages mean what, run man man
which tells you which man page number corresponds to which section. (1 is executable, 3 is library calls, 5 is file formats, 7 is misc).
# Read the developer documentation (page 3) # This page tells you the #include statement to use, # how to link against it, and instructions on how to # initialize and use the library itself. # It also lists out all the man pages for each function man 3 ncurses man 3 initscr man 3 getch man 3 getmouse man 1 ncurses6-config
Ncurses comes with a helper function useful for these tasks, ncurses6-config
which will be in ~/.local/bin/
if you used the home prefix.
# For compiling and specifying include dirs ncurses6-config --cflags # -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600 -I/home/dano/.local/include/ncurses -I/home/dano/.local/include # For linking and specifying lib dirs ncurses6-config --libs # -L/home/dano/.local/lib -lncurses # For LD_LIBRARY_PATH when executing and linking dynamically ncurses6-config --libdir #/home/dano/.local/lib
// g++ hello_curses.cpp -lncurses #include <curses.h> int main(int argc, char* argv[]) { initscr(); // Take over terminal and start managing it with curses endwin(); // Cleanup or terminal will be left in a weird state return 0; }
// Allow CTRL-C to kill app // Near beginning, link signal to callback signal(SIGINT, finish); static void finish(int sig) { endwin(); /* do your non-curses wrapup here */ exit(0); }
// A more robust example, taken from // https://invisible-island.net/ncurses/ncurses-intro.html#using #include <stdlib.h> #include <curses.h> #include <signal.h> static void finish(int sig); int main(int argc, char *argv[]) { int num = 0; /* initialize your non-curses data structures here */ (void) signal(SIGINT, finish); /* arrange interrupts to terminate */ (void) initscr(); /* initialize the curses library */ keypad(stdscr, TRUE); /* enable keyboard mapping */ (void) nonl(); /* tell curses not to do NL->CR/NL on output */ (void) cbreak(); /* take input chars one at a time, no wait for \n */ (void) echo(); /* echo input - in color */ if (has_colors()) { start_color(); /* * Simple color assignment, often all we need. Color pair 0 cannot * be redefined. This example uses the same value for the color * pair as for the foreground color, though of course that is not * necessary: */ init_pair(1, COLOR_RED, COLOR_BLACK); init_pair(2, COLOR_GREEN, COLOR_BLACK); init_pair(3, COLOR_YELLOW, COLOR_BLACK); init_pair(4, COLOR_BLUE, COLOR_BLACK); init_pair(5, COLOR_CYAN, COLOR_BLACK); init_pair(6, COLOR_MAGENTA, COLOR_BLACK); init_pair(7, COLOR_WHITE, COLOR_BLACK); } for (;;) { int c = getch(); /* refresh, accept single keystroke of input */ attrset(COLOR_PAIR(num % 8)); num++; /* process the command keystroke */ } finish(0); /* we are done */ } static void finish(int sig) { endwin(); /* do your non-curses wrapup here */ exit(0); }
initscr(); // Initialize ncurses endwin(); // Cleanup and shutdown stdscr(); // Buffer holding data that gets pushed to curscr curscr(); // What is actually presented (don't modify directly) refresh(); // Refresh from stdscr wrefresh(); // Refresh using non-stdscr window