ncurses - paper.pdf

(281 KB) Pobierz
411322 UNPDF
ncurses
Elaine de Claro
February 22,
2002
Mico Galang
Mr. William Yu
Fina Mesina
CS150.3
Athena Rebong
Kenneth Talamayan
INTRODUCTION
Ncurses
The curses package is a subroutine library for terminal-independent screen-painting and
input-event handling which presents a high level screen model to the programmer, hiding
differences between terminal types and doing automatic optimization of output to change one
screenfull of text into another. Curses uses terminfo, which is a database format that can describe
the capabilities of thousands of different terminals.
The curses API may seem something of an archaism on UNIX desktops increasingly
dominated by X, Motif, and Tcl/Tk. Nevertheless, UNIX still supports tty lines and X supports
xterm(1) ; the curses API has advantages such as back-portability to character-cell terminals, being
light weight, and simplicity. For an application that does not require bit-mapped graphics and
multiple fonts, an interface implementation using curses will typically be a great deal simpler and
less expensive than one using an X toolkit.
The curses library consists of a number of functions which your program can call. Those
functions know the various cursor-movement character sequences for a large variety of terminals
(this information is in the file /etc/termcap). The significance of this is that your program does
not have to know that information; it simply calls the curses functions, and those functions will
use your TERM value to check the /etc/termcap file and then send the proper cursor-movement
characters. For example, if your program wanted to clear the screen, it would not (directly) use
any character sequences like those above. Instead, it would simply make the call clear(); and
curses would do the work on the program's behalf. The Curses library forms a wrapper over
working with raw terminal codes, and provides highly flexible and efficient API (Application
Programming Interface).
Ncurses not only creates a wrapper over terminal capabilities, but also gives a robust
framework to create nice looking UI (User Interface)s in text mode. It provides functions to create
windows etc. Its sister libraries panel, menu and form provide an extension to the basic curses
library. These libraries usually come along with curses. One can create applications that contain
multiple windows, menus, panels and forms. Windows can be managed independently, can provide
'scrollability' and even can be hidden.
Menus provide the user with an easy command selection option. Forms allow the creation
of easy-to-use data entry and display windows. Panels extend the capabilities of ncurses to deal
with overlapping and stacked windows.
These are just some of the basic things we can do with ncurses. As we move along,
We will see all the capabilities of these libraries.
Ncurses (new curses) is a freely distributable "clone" of System V Release 4.0 (SVr4)
curses. Curses is a pun on the term "cursor optimization". It is a library of functions that manage
an application's display on character-cell terminals (e.g., VT100). It uses terminfo format, supports
pads, colors, multiple highlights, form characters and function key mapping.
History
Many programs need to make use of a terminal's cursor-movement capabilities. A familiar
example is vi ; most of its commands make use of such capabilities. For example, hitting the `j'
key while in vi will make the cursor move up one line. But a potential problem with this is that
different terminals have different ways in which to specify a given type of cursor motion. For
example, if a program wants to make the cursor move up one line on a
VT100 terminal, the program needs to send the characters Escape, `[', and `A' which is,
printf("%c%c%c",27,'[','A'); while the character code for the Escape key is 27. But for a Televideo
920C terminal, the program would have to send the ctrl-K character, which has code 11,
printf("%c",11);
Clearly, the authors of programs like vi would have a very difficult time trying to write
different versions for every terminal, and worse yet, anyone else writing a program which needed
cursor movement would have to ``re-invent the wheel,'' which is a very big waste of time. This
is why the curses library was developed.
The first ancestor of curses was the routines written to provide screen-handling for the
game rogue; these used the already- existing termcap database facility for describing terminal
capabilities. These routines were abstracted into a documented library and first released with the
early BSD UNIX versions. System III UNIX from Bell Labs featured a rewritten and much-
improved curses library. It introduced the terminfo format. Terminfo is based on Berkeley's termcap
database, but contains a number of improvements and extensions. Parameterized capabilities
strings were introduced, making it possible to describe multiple video attributes, and colors and to
handle far more unusual terminals than possible with termcap. In the later AT&T System V
releases, curses evolved to use more facilities and offer more capabilities, going far beyond BSD
curses in power and flexibility.
Ncurses has an evolved history. The package was originated as pcurses , written by
Pavel Curtis around 1982, maintained by various people through 1986. It was later polished (e.g.,
ANSI prototypes, reformatted, some bug fixes, but still essentially the same package) and re-
issued as ncurses 1.8.1 in late 1993 by Zeyd Ben-Halim. Subsequent work (through 1.8.8) was
driven by Eric Raymond, who eradicated previous signs of authorship with the current copyright
notice between 1.8.7 and 1.8.8, early 1995. Later, this extended to incorporating the forms and
menus libraries written by Juergen Pfeifer, and a panel library written by Warren Tucker.
CONCEPTS
A Window
A window is an internal data representation of an image of what a particular rectangular
section of the terminal display may look like. The terminal display as a whole could be said to
be a window, its dimensions defined by its outermost extremeties, those being the side of the
cathode ray tube.
That said, we could then say that the window with the dimensions of one character in
length and one character in height is in fact a window of the size of one character. This is the
smallest window that curses could possibly handle, but a window could also have the dimensions
of 128 characters in length and 50 characters in height. Unfortunately, this would be bigger than
the size of most terminals, but in theory, anyway, it is a window.
A curses window is not a physical entity. It is only a data representation of how you
would like a rectangular portion of the physical screen to look. A window is a preallocated
resource stored in the machine’s memory. As you manipulate it, nothing actually happens to the
physical screen until you are ready to update it. When you are ready, you used the curses
function wrefresh() to update the physical screen. This overwrites or superimposes the internal
window on the physical screen.
Curses provides a default window which represents your terminal screen. Its size is
defined by the dimensions of the terminal screen your curses program is to work with. Curses
allows you to manipulate several windows individually, or all at the same time. It also allows
windows to contain windows within themselves, known as sub-windows. You can create as many
windows as you want; the only limitation is the amount of memory available which your program
can use.
The philosophy behind curses is really quite simple. You can work with the default
window provided by curses, or you can create your own window or windows. You may choose to
use both methods; you can use the default window provided, as well as create and work with
your own. Either way, curses does not care.
The Curses Window
The curses internal representation of a window is defined in the data structure:
struct _win_st
This structure is defined in the /usr/include/curses.h include file and is typedef WINDOW.
The WINDOW structure below is taken from a UNIX system V.2 version of curses.
s truct _win_st {
short _cury, _curx;
short _maxy, _maxx;
short _begy, _begx;
short _flags;
chtype _attrs;
bool _clear;
bool _leave;
bool _scroll;
bool _use _ idl;
bool _use_keypad;
bool _use_meta;
bool _nodelay;
chtype **_y;
short *_firstch;
short *_lastch;
short _tmarg, _bmarg;
};
typedef struct _win_st WINDOW;
extern WINDOW *stdscr, *curscr;
The defenition of the above curses data structure is found in the <curses.h>. The first line of this
code is an ifndef, that is an #ifndef WINDOW, the corresponding #endif of which is at the bottom
of the file. This is useful for adminestering multiple source files.
This structure is curses’ internal representation of a window. It contains all the necessary
data and information which curses needs to manage the window on the terminal screen. Anything
inside or belonging to a window is modifiable. Anything outside is undefined and usually illegal.
Even if you want to print some texts on the screen, curses requires you to place the desired
texts into a window. It is important to realize that almost all the curses routines totally depend on
this window structure.
It is equally important to realize that, although window structure is an internal
representation of a curses window, it may not necessarily bear any relation to what is really
being displayed on the terminal screen. The window structure is used solely to hold data and
information which describes a window, and is used to build a potential image of a portion of the
true terminal screen. It is like a buffer area set aside to represent a portion of the screen which
you can modify by using the routines provided in the curses library.
Example: The Hello World!!! Program
#include <ncurses.h>
int main()
{
initscr(); /* Start curses mode */
printw("Hello World !!!"); /* Print Hello World */
refresh(); /* Refresh it on to the real screen */
endwin(); /* End curses mode */
return 0;
}
The above program prints "Hello World!!!" to the screen and exits. This program shows
how to initialize curses and do screen manipulation and end curses mode. Let's dissect it line by
line.
The function initscr ( ) initializes the terminal in curses mode. In some implementations it
clears the screen and presents a blank screen. To do any screen manipulation using curses
package this has to be called first. This function initializes the curses system and allocates
memory for our present window which is called 'stdscr' and some other data structures. Under
extreme cases this function might fail due to insufficient memory to allocate memory for curses
library's data structures.
After this is done we can do a variety of initializations to customize our curses settings.
These details will be explained later.
The next line printw prints the string "Hello World!!!" on to the screen. This function is
analogous to normal printf in all respects except that it prints the data in a window called stdscr
at the current (y, x) co-ordinates. Since our present co-ordinates are at 0, 0 the string is printed
at the left hand corner of the window.
This brings us to that mysterious refresh ( ). Well, when we did printw actually the data
is written to an imaginary window called stdscr, which is not updated on the screen yet. The job
of printw is to update a few flags and data structures and write the data to a buffer
corresponding to stdscr. In order to bring it to the screen we need to call refresh () and tell the
curses system to dump the contents on the screen.
The philosophy behind all this is to allow the programmer to do multiple updates on the
imaginary screen or windows and do a refresh once all his screen update is done. refresh ( )
checks the window and updates only the portion which has been changed. This gives good
response and offers greater flexibility too. But it is sometimes frustrating to beginners. A common
mistake committed by beginners is to forget to call refresh ( ) after they did some update through
printw( ) class of functions.
And finally don't forget to end the curses mode. Otherwise your terminal might behave
strangely after the program quits. endwin() frees the memory taken by curses sub-system and its
data structures and puts the terminal in normal mode. This function must be called after you are
done with the curses mode.
The Terminal Screen
Before curses can manage your terminal screen it needs to know what it looks like.
When curses starts up, the first thing it does is clear the screen it then places the cursor in the
home position, which is the top left-hand corner of the screen. Curses then knows exactly what
your physical screen looks like and where the cursor is situated.
Curses also needs to know how the programmer would like it to look. For this reason,
curses provides two WINDOW data structures, curscr and stdscr .
Zgłoś jeśli naruszono regulamin