NCURSES – it is a C library which control process of sending a series of bytes by terminal. It’s quite oldschool approach, but it’s widely used even right now as internet works the same way: packets sending just series of bytes. So internet is kinda ‘big’ terminal thingy 🙂
So… NCURSES (1993) – rewrite of old non-free CURSES terminal which were made to develop Rogue game (1980).
Basically it’s all about terminal’s cursor control. This article based at tldp NCURSES guide and some other resources. Let’s start!
Contents:
NCURSES basic functions
initscr()
init terminal in curses mode and malloc() terminal window (called stdscr)
raw()
disable line buffering (so you won’t need press Enter
after input)
cbreak();
disable line buffering disabled; intercept and process input
noecho()
disable echo()
; eg to take user input to getch() without showing it on screen
keypad(stdscr, TRUE)
to be able to read arrows, F1-F12, etc unusual keys
printw("Hello")
prints stuff on stdscr window within current y,x coords
addch()
print single character with attributes
addstr()
print strings
refresh()
update terminal in particular place
halfdelay()
generates timeout after which prompt not possible
getyx()
gets the co-ordinates of the present cursor into the variables y, x
move()
moves the cursor to the co-ordinates given to it
getch()
user input similar to getchar(), but without line buffering (not need press Enter
after input)
attrset()
/ attron()
/ attroff()
assign attributes for output.
Also you can assign attribute macros to output directly, eg
addch(char | A_BOLD | A_UNDERLINE);
endwin()
exit curses mode doing free()
Output
mvaddch()
move the cursor to y,x and print. It means:
move(row,col); addch(ch);
waddch()
is the same as addch()
but in current window
mvwaddch()
add a character into the given window at the given coordinates
The same goes to:
printw()
print stuff
mvprintw(int y, int x, const char *fmt, ...)
print at certain y,x
wprintw()
print in certain window
mvwprintw()
print at certain y,x in a certain window
vwprintw()
print variable number of arguments
And:
addstr()
print character string into given window; repeats addch()
mvaddstr()
print string y,x
waddstr()
print into given window
mvwaddstr()
print string y,x into given window
addnstr()
puts n
characters into the screen
getmaxyx(stdscr,row,col)
get max the number of rows and columns in a given window. It’s not a function, but macro defined in ncurses.h
Input
getch()
get character; read a single character from the terminal
scanw()
get formatted input; like scanf(), but mvscanw()
– it can get the input from any y,x
getstr()
get strings; like getch() - get stuff until a \n
, CR
, EOF
etc. Result is a pointer to a string of characters.
Attributes
attrset()
sets the attributes of window; fully overrides whatever attributes the window previously had and sets it to the new attributes
attron()
/ attroff()
just switches on the attribute given to it
attr_set()
, attr_on
… the same as above, but they take parameters of type attr_t
dsd
standend()
like attrset(A_NORMAL); turns off all attributes and brings normal mode
attr_get()
gets the current attributes and color pair of the window (to scan areas of screen)
chgat()
set attributes for a group of characters without moving cursor (changes the attributes of a given number of characters starting at the current cursor location).
Family includes wchgat()
, mvchgat()
etc
Example: mvchgat(0, 0, -1, A_BLINK, 1, NULL);
- First two parameters specify the position at which to start
- Third parameter number of characters to update. -1 means till
end of line - Forth parameter is the normal attribute you wanted to give
to the charcter - Fifth is the color index. It is the index given during init_pair()
use 0 if you didn’t want color - Sixth one is always NULL
Windows
Standard window is stdscr
, but we can create more different windows to manipulate parts of the screen separately.
create_newwin(height, width, starty, startx);
create new “window” – abstraction of an imaginary window, which can be manipulated independent of other parts of screen. It returns a pointer to structure WINDOW, which can be passed to window related functions like wprintw()
etc
box()
draw a border around the window. Uses special extended characters to draw it (eg ACS_ULCORNER
)
delwin()
destroy window (deallocates memory for window structure)
Colors
start_color()
initialize colors
has_colors()
check: can terminal support color at all
init_pair()
initialize color pair (foreground color (to draw characters) and background color
COLOR_PAIR()
allows to use colors; eg via attron()
init_color(<color name>, <R>, <G>, <B>)
change the rgb values for the colors defined by curses initially. If your terminal cannot change the color definitions, the function returns ERR.
can_change_color()
check if terminal able to change colors. Returns 1 if it can do it
color_content()
/ pair_content()
find the color content
Mouse interaction
We got into keyboard interaction in first chapter (getch stuff), so lets take a peak into mouse.
mousemask (mmask_t newmask, mmask_t *oldmask)
1st argument is the events you want to listen to (by default, all the events are turned off).
2nd is the old events mask
Example:
mousemask(ALL_MOUSE_EVENTS | REPORT_MOUSE_POSITION, NULL);
List of events:
BUTTON1_PRESSED mouse button 1 down BUTTON1_RELEASED mouse button 1 up BUTTON1_CLICKED mouse button 1 clicked BUTTON1_DOUBLE_CLICKED mouse button 1 double clicked BUTTON1_TRIPLE_CLICKED mouse button 1 triple clicked ... BUTTON4_TRIPLE_CLICKED mouse button 4 triple clicked BUTTON_SHIFT shift was down during button state change BUTTON_CTRL control was down during button state change BUTTON_ALT alt was down during button state change ALL_MOUSE_EVENTS report all button state changes REPORT_MOUSE_POSITION report mouse movement
getmouse()
retrieve mouse event; returns the event into the pointer given to it; such structure:
typedef struct { short id; /* ID to distinguish multiple devices */ int x, y, z; /* event coordinates */ mmask_t bstate; /* button state bits */ }
mouse_trafo()
/ wmouse_trafo()
convert mouse co-ordinates to screen relative co-ordinates (see curs_mouse()
in man)
mouseinterval function sets the maximum time (in thousands of a second) that can elapse between press and release events in order for them to be recognized as a click
Note: Seems that some old code examples for mouse in NCURSES works a bit glitchy. I’ve tested in Ubuntu and Cygwin and some stuff didn’t work.
Screen manipulation
getyx(win, y, x);
gets the co-ordinates of the present cursor into the variables y, x.
win
– window pointer
y, x
co-ordinates will be put into this variables
getparyx()
gets the beginning co-ordinates of the sub window relative to the main window
getbegyx()
/ getmaxyx()
store current window’s beginning and maximum co-ordinates
scr_dump()
dump the screen contents to a file given as an argument
scr_restore()
restore the dump of the screen contents
putwin()
/ getwin()
store and restore windows
copywin()
copy a window completely onto another window; takes the source and destination windows as parameters and according to the rectangle specified, it copies the rectangular region from source to destination window. It’s last parameter specifies whether to overwrite or just overlay the contents on to the destination window. If this argument is true, then the copying is non-destructive.
Misc NCURSES stuff
curs_set()
make the cursor invisible. Params:
0 invisible / 1 normal / 2 very visible
How to leave Curses mode temporarily:
def_prog_mode()
save the tty modes → endwin()
To go back: reset_prog_mode()
→ refresh()
Useful libraries
panel.h
Panel object is a window that is implicitly treated as part of a deck including all other panel objects. The deck is treated as a stack with the top panel being completely visible and the other panels may or may not be obscured according to their positions:
newwin()
create the windows attached to the panelsnew_panel()
create panels with the chosen visibility order. Stack them up according to the desired visibility.update_panels()
write the panels to the virtual screen in correct visibility order.doupdate()
to show it on the screen.show_panel()
,hide_panel()
,move_panel()
etc. Make use of helper functions likepanel_hidden()
andpanel_window()
. Make use of user pointer to store custom data for a panel. Use the functionsset_panel_userptr()
andpanel_userptr()
to set and get the user pointer for a paneldel_panel()
delete the panel
menu.h
extension to basic curses to create menus. First you create items, and then post the menu to the display. After that, all the processing of user responses is done in an elegant function menu_driver()
which is the work horse of any menu program. Algorythm:
new_item()
create items; you can specify a name and description for themnew_menu()
create menu and specify the items to be attached with.menu_post()
post menu and refresh the screen.menu_driver()
process the user requests with a loop and do necessary updates to menumenu_unpost()
unpost the menufree_menu()
free the memory allocated to menufree_item()
free the memory allocated to the items
form.h
forms created with fields with new_field()
; the form is manipulated with form_driver()
– to send requests to move focus to a certain field, move cursor to end of the field etc. Algorythm kinda similar to menues:
new_field()
(you can specify the height and width of the field, and its position on the form)new_form()
by specifying the fields to be attached with.form_post()
and refresh the screenform_driver()
process the user requests with a loop and do necessary updates to formform_unpost()
free_form()
free_field()
CDK (Curses Development Kit) https://invisible-island.net/cdk/
dialog.h
to create dialog boxes http://invisible-island.net/dialog/
Perl Curses Modules CURSES::FORM and CURSES::WIDGETS:
http://cpan.org/modules/01modules.index.html
Default colors:
0. Black
1. Blue
2. Green
3. Cyan
4. Red
5. Magenta
6. Brown
7. White (Light Gray)
8. Bright Black (Gray)
9. Bright Blue
10. Bright Green
11. Bright Cyan
12. Bright Red
13. Bright Magenta
14. Yellow
15. Bright White
Useful resources
This article based at: https://tldp.org/HOWTO/NCURSES-Programming-HOWTO/
Manual https://invisible-island.net/ncurses/man/index.html
FAQ https://invisible-island.net/ncurses/ncurses.faq.html
Tutorial https://invisible-island.net/ncurses/ncurses-intro.html
Another variant of this library is PDCurses which works well at Windows OS