This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
|
programming:ncurses [2022/03/19 04:25] nanodano created |
programming:ncurses [2022/03/19 23:56] (current) nanodano |
||
|---|---|---|---|
| Line 37: | Line 37: | ||
| </ | </ | ||
| - | The man pages with API documentation will be in '' | + | 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 '' |
| - | 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 | + | ===== Documentation ===== |
| + | |||
| + | ==== Man pages ===== | ||
| + | |||
| + | There are a few '' | ||
| + | |||
| + | If you aren't sure which man pages mean what, run '' | ||
| <code bash> | <code bash> | ||
| + | # 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 | ||
| + | </ | ||
| + | |||
| + | |||
| + | ===== Online Docs ===== | ||
| + | |||
| + | * Online tutorial [[https:// | ||
| + | |||
| + | Other resources: | ||
| + | |||
| + | * https:// | ||
| + | * https:// | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | ===== ncurses6-config tool ===== | ||
| + | |||
| + | Ncurses comes with a helper function useful for these tasks, '' | ||
| + | |||
| + | <code bash> | ||
| + | # For compiling and specifying include dirs | ||
| + | ncurses6-config --cflags | ||
| + | # -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600 -I/ | ||
| + | |||
| + | # For linking and specifying lib dirs | ||
| ncurses6-config --libs | ncurses6-config --libs | ||
| # -L/ | # -L/ | ||
| - | ncurses6-config --cflags | + | # For LD_LIBRARY_PATH when executing and linking dynamically |
| - | #-D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600 -I/ | + | ncurses6-config |
| + | #/ | ||
| </ | </ | ||
| + | ===== Examples ===== | ||
| + | ==== Hello world ==== | ||
| + | <code cpp hello_curses.cpp> | ||
| + | // g++ hello_curses.cpp -lncurses | ||
| + | // add -static for static binary | ||
| + | #include < | ||
| + | |||
| + | 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; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | |||
| + | <code cpp example.cpp> | ||
| + | // A more robust example, taken from | ||
| + | // https:// | ||
| + | |||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | |||
| + | static void finish(int sig); | ||
| + | |||
| + | int | ||
| + | main(int argc, char *argv[]) | ||
| + | { | ||
| + | int num = 0; | ||
| + | |||
| + | /* initialize your non-curses data structures here */ | ||
| + | |||
| + | (void) signal(SIGINT, | ||
| + | |||
| + | (void) initscr(); | ||
| + | keypad(stdscr, | ||
| + | (void) nonl(); | ||
| + | (void) cbreak(); | ||
| + | (void) echo(); | ||
| + | |||
| + | if (has_colors()) | ||
| + | { | ||
| + | start_color(); | ||
| + | |||
| + | /* | ||
| + | * Simple color assignment, often all we need. Color pair 0 cannot | ||
| + | * be redefined. | ||
| + | * pair as for the foreground color, though of course that is not | ||
| + | * necessary: | ||
| + | */ | ||
| + | init_pair(1, | ||
| + | init_pair(2, | ||
| + | init_pair(3, | ||
| + | init_pair(4, | ||
| + | init_pair(5, | ||
| + | init_pair(6, | ||
| + | init_pair(7, | ||
| + | } | ||
| + | |||
| + | for (;;) | ||
| + | { | ||
| + | int c = getch(); | ||
| + | attrset(COLOR_PAIR(num % 8)); | ||
| + | num++; | ||
| + | |||
| + | /* process the command keystroke */ | ||
| + | } | ||
| + | |||
| + | finish(0); | ||
| + | } | ||
| + | |||
| + | static void finish(int sig) | ||
| + | { | ||
| + | endwin(); | ||
| + | |||
| + | /* do your non-curses wrapup here */ | ||
| + | |||
| + | exit(0); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== Shelling out ==== | ||
| + | |||
| + | <code cpp shell_out.cpp> | ||
| + | // From https:// | ||
| + | addstr(" | ||
| + | def_prog_mode(); | ||
| + | endwin(); | ||
| + | system(" | ||
| + | addstr(" | ||
| + | refresh(); | ||
| + | </ | ||
| + | |||
| + | |||
| + | ==== Test mouse input ==== | ||
| + | |||
| + | <code cpp mouse_test.cpp> | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | |||
| + | void redrawBorder() { | ||
| + | clear(); | ||
| + | box(stdscr, | ||
| + | |||
| + | } | ||
| + | |||
| + | int main() { | ||
| + | |||
| + | initscr(); | ||
| + | mousemask(ALL_MOUSE_EVENTS, | ||
| + | | ||
| + | /** | ||
| + | | ||
| + | */ | ||
| + | if (has_colors()) { start_color(); | ||
| + | // | ||
| + | init_pair(1, | ||
| + | init_pair(2, | ||
| + | | ||
| + | cbreak(); | ||
| + | keypad(stdscr, | ||
| + | nonl(); | ||
| + | noecho(); | ||
| + | curs_set(0); | ||
| + | | ||
| + | attrset(COLOR_PAIR(1)); | ||
| + | redrawBorder(); | ||
| + | // | ||
| + | | ||
| + | | ||
| + | | ||
| + | // short id; /* ID to distinguish multiple devices */ | ||
| + | // int x, y, z; /* event coordinates */ | ||
| + | // mmask_t bstate; | ||
| + | |||
| + | while (true) { | ||
| + | int c = getch(); | ||
| + | switch (c) { | ||
| + | case ' | ||
| + | endwin(); | ||
| + | exit(0); | ||
| + | case KEY_MOUSE: | ||
| + | MEVENT event; | ||
| + | if (getmouse(& | ||
| + | clear(); | ||
| + | redrawBorder(); | ||
| + | |||
| + | attrset(COLOR_PAIR(2)); | ||
| + | mvaddstr(5, | ||
| + | mvaddstr(6, | ||
| + | mvaddstr(7, | ||
| + | addstr(std:: | ||
| + | if (event.bstate & BUTTON1_PRESSED) { | ||
| + | addstr(" | ||
| + | } else if (event.bstate & BUTTON1_DOUBLE_CLICKED) { | ||
| + | addstr(" | ||
| + | } | ||
| + | attrset(COLOR_PAIR(1)); | ||
| + | |||
| + | } | ||
| + | break; | ||
| + | |||
| + | /** | ||
| + | BUTTON1_PRESSED | ||
| + | BUTTON1_RELEASED | ||
| + | BUTTON1_CLICKED | ||
| + | BUTTON1_DOUBLE_CLICKED | ||
| + | BUTTON1_TRIPLE_CLICKED | ||
| + | BUTTON2_PRESSED | ||
| + | BUTTON2_RELEASED | ||
| + | BUTTON2_CLICKED | ||
| + | BUTTON2_DOUBLE_CLICKED | ||
| + | BUTTON2_TRIPLE_CLICKED | ||
| + | BUTTON3_PRESSED | ||
| + | BUTTON3_RELEASED | ||
| + | BUTTON3_CLICKED | ||
| + | BUTTON3_DOUBLE_CLICKED | ||
| + | BUTTON3_TRIPLE_CLICKED | ||
| + | BUTTON4_PRESSED | ||
| + | BUTTON4_RELEASED | ||
| + | BUTTON4_CLICKED | ||
| + | BUTTON4_DOUBLE_CLICKED | ||
| + | BUTTON4_TRIPLE_CLICKED | ||
| + | BUTTON_SHIFT | ||
| + | BUTTON_CTRL | ||
| + | BUTTON_ALT | ||
| + | ALL_MOUSE_EVENTS | ||
| + | REPORT_MOUSE_POSITION | ||
| + | */ | ||
| + | |||
| + | case KEY_RESIZE: | ||
| + | redrawBorder(); | ||
| + | mvaddstr(10, | ||
| + | break; | ||
| + | |||
| + | default: | ||
| + | break; | ||
| + | } | ||
| + | } | ||
| + | |||
| + | |||
| + | |||
| + | /** | ||
| + | * Cleanup and shutdown | ||
| + | */ | ||
| + | endwin(); | ||
| + | return 0; | ||
| + | } | ||
| + | |||
| + | </ | ||
| + | |||
| + | |||
| + | ==== Modifier keys ==== | ||
| + | |||
| + | <code cpp> | ||
| + | |||
| + | // int c = getch(); | ||
| + | // switch (c) | ||
| + | case ctrl(' | ||
| + | addstr(" | ||
| + | break; | ||
| + | default: | ||
| + | if (c == KEY_ENTER) { | ||
| + | addstr(" | ||
| + | } | ||
| + | if (c == 27) { // Alt key was down when key pressed | ||
| + | // Get the next char that came with the alt | ||
| + | c = getch(); | ||
| + | addstr(" | ||
| + | addch(c); // could be ' | ||
| + | } | ||
| + | |||
| + | </ | ||
| + | |||
| + | |||
| + | ===== Important variables and functions ===== | ||
| + | |||
| + | |||
| + | <code cpp> | ||
| + | initscr(); // Initialize ncurses | ||
| + | endwin(); // Cleanup for exit or shell out (refresh will bring state) | ||
| + | getmaxyx() // get terminal size | ||
| + | |||
| + | cbreak() | ||
| + | nonl() | ||
| + | noecho() | ||
| + | curs_set() | ||
| + | |||
| + | |||
| + | newwin() | ||
| + | |||
| + | // Add chars to window | ||
| + | mvaddch(y, | ||
| + | addstr() | ||
| + | printw() | ||
| + | addch() | ||
| + | |||
| + | |||
| + | // Get input | ||
| + | getch() | ||
| + | wgetstr() | ||
| + | wscanw() | ||
| + | keypad(stdscr, | ||
| + | |||
| + | if (has_colors()) { start_color(); | ||
| + | use_default_colors() | ||
| + | |||
| + | |||
| + | refresh() // Refresh from stdscr | ||
| + | wrefresh() // Refresh using non-stdscr window | ||
| + | wnoutrefresh() // Disable auto update on window update (pair with doupdate) | ||
| + | doupdate() // Manually repaint all updates | ||
| + | touchwin() | ||
| + | |||
| + | box() | ||
| + | border() | ||
| + | |||
| + | // Colors | ||
| + | init_pair() | ||
| + | COLOR_PAIR | ||
| + | |||
| + | attron() | ||
| + | attroff() | ||
| + | attrset() | ||
| + | |||
| + | move(y, x) | ||
| + | |||
| + | |||
| + | |||
| + | mousemask(ALL_MOUSE_EVENTS, | ||
| + | MEVENT // data type with bits set for specific mouse events like BUTTON1_CLICKED | ||
| + | |||
| + | // Special events from wgetch() | ||
| + | KEY_MOUSE // Mouse event (use getmouse()) | ||
| + | KEY_RESIZE // Terminal was resized and adjusted | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | scrollok() | ||
| + | leaveok() | ||
| + | |||
| + | derwin() | ||
| + | subwin() | ||
| + | delwin() | ||
| + | |||
| + | |||
| + | define_key() // function-key control sequences | ||
| + | keyok() // toggle the listening for special control sequences | ||
| + | </ | ||