NCurses
NCurses "new curses" is a successor to the curses library. It's a C library to write text-based interfaces (e.g. interfaces in a terminal).
It's commonly used by Linux programs such as vim
.
$ # see also, [...]5-dev and [...]w5-dev
$ sudo apt-get install libncurses-dev
And, in your program, use:
#include <ncurses.h> // or, use curses.h
Features β
- π¨ Background/Foreground color for the text
- πͺ Multiple windows
- πΉ Keyboard/Mouse input
- π― Cursor implementation
- πΈ Extensions for forms, menus...
- ...
Documentation π
- NCURSES Programming HOWTO (examples are stored on git)
- Dan Gookin's Guide to Ncurses Programming
Window system
Creating windows
To use ncurses within a terminal, you first need to initialize it:
if ( initscr() == NULL ) {
// handle error
exit(1);
}
This will fill a global variable stdscr
of type Window*
which is the screen of your terminal. You may divide it into multiple separate windows:
WINDOW* w = subwin(stdscr, height, width, pos_x, pos_y);
box(w, ACS_VLINE, ACS_HLINE); // show borders
β‘οΈ It uses a coordinate system with the origin in the top-left corner. Use the global variables LINES
/COLS
to get the height/width of stdscr
.
Using windows
There are two kinds of macro/functions:
- those taking a window (
Window*
) - those not taking a window (
stdscr
is implicit)
Common functions are:
-
refresh()
/wrefresh(w)
: redraw the window -
clear()
/wclear(w)
: empty the window -
endwin()
/delwin(w)
: destroy a window
π Don't forget to call endwin()
at the end of your program. It will automatically destroy all sub-windows.
Display text
Cursor
The position of the cursor is where the text will be displayed, unless you specify a position explicitly.
// get
int cursor_x = getcurx(w); // cursor column
int cursor_y = getcury(w); // cursor line
// set
move(cursor_x, cursor_y);
Display a text using a sort of printf
// print where the cursor is
printw(format);
printw(format, args...);
// print at a specific location
mvwprintw(w, pos_x, pos_y, format);
mvwprintw(w, pos_x, pos_y, format, args...);
Display characters
// print where the cursor is
addch(char); // or, waddch(w, char);
addstr(char); // or, waddstr(w, char*);
// print at a specific location
mvwaddch(w, pos_x, pos_y, char);
mvwaddstr(w, pos_x, pos_y, char*);
Delete characters
deleteln(); // delete a line
mvwdelch(w, pos_x, pos_y); // delete a character
Colors
Colors can only be used if the terminal supports them.
if ( has_colors() == FALSE ) {
// don't support colors
} else {
// support colors, enable them
start_color();
}
Colors are represented by a number. It can go from 0 to 256, but some terminals only support 0 to 8. To use a color, you need to wrap it inside a pair. A pair has a foreground color, and a background color.
init_pair(pair_id, foreground, background);
β‘οΈ There are aliases for basic constants: COLOR_BLACK
...
To create new colors, use:
init_color(color_id, 0, 0, 0); // not support by all
To use a pair:
attron(COLOR_PAIR(pair_id)); // use for following text
attroff(COLOR_PAIR(pair_id)); // stop
wattron(w, COLOR_PAIR(pair_id)); // ...
Other text effects that can be enabled: A_BOLD
, A_STANDOUT
...
Reading input
You have to call some methods according to the behavior you want and the default settings (β ).
noecho(); // don't print pressed keys
echo(); // β
do print pressed keys
nocbreak(); // wait for <enter> to process input
cbreak(); // β
don't wait for <enter> to process input
curs_set(TRUE); // β
show cursor
curs_set(FALSE); // hide cursor
keypad(w, TRUE); // handle arrow keys as characters
keypad(w, FALSE); // β
don't handle arrow keys as characters
Mouse
...
Keyboard
If you're using cbreak()
, you'll most likely read character by character using getch()
. Otherwise, refer to getstr(buffer)
documentation.
π€ Both calls are blocking the program until they receive input.
int ch = getch();
switch(ch) {
case KEY_UP: // if keypad enabled
// ...
break;
case 'r': // normal key pressed
// ...
break;
case KEY_SEND: case KEY_ENTER: // enter pressed
// ...
break;
}
π» To-do π»
Stuff that I found, but never read/used yet.