📄 ncurses-intro.doc
字号:
not follow it are those for which a window must always be specified. In order to move the current (y, x) coordinates from one point to another, the routines move() and wmove() are provided. However, it is often desirable to first move and then perform some I/O operation. In order to avoid clumsiness, most I/O routines can be preceded by the prefix 'mv' and the desired (y, x) coordinates prepended to the arguments to the function. For example, the calls move(y, x); addch(ch); can be replaced by mvaddch(y, x, ch); and wmove(win, y, x); waddch(win, ch); can be replaced by mvwaddch(win, y, x, ch); Note that the window description pointer (win) comes before the added (y, x) coordinates. If a function requires a window pointer, it is always the first parameter passed. Variables The curses library sets some variables describing the terminal capabilities. type name description ------------------------------------------------------------------ int LINES number of lines on the terminal int COLS number of columns on the terminal The curses.h also introduces some #define constants and types of general usefulness: bool boolean type, actually a `char' (e.g., bool doneit;) TRUE boolean `true' flag (1). FALSE boolean `false' flag (0). ERR error flag returned by routines on a failure (-1). OK error flag returned by routines when things go right.Using the Library Now we describe how to actually use the screen package. In it, we assume all updating, reading, etc. is applied to stdscr. These instructions will work on any window, providing you change the function names and parameters as mentioned above. Here is a sample program to motivate the discussion:#include <curses.h>#include <signal.h>static void finish(int sig);intmain(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're done */}static void finish(int sig){ endwin(); /* do your non-curses wrapup here */ exit(0);} Starting up In order to use the screen package, the routines must know about terminal characteristics, and the space for curscr and stdscr must be allocated. These function initscr() does both these things. Since it must allocate space for the windows, it can overflow memory when attempting to do so. On the rare occasions this happens, initscr() will terminate the program with an error message. initscr() must always be called before any of the routines which affect windows are used. If it is not, the program will core dump as soon as either curscr or stdscr are referenced. However, it is usually best to wait to call it until after you are sure you will need it, like after checking for startup errors. Terminal status changing routines like nl() and cbreak() should be called after initscr(). Once the screen windows have been allocated, you can set them up for your program. If you want to, say, allow a screen to scroll, use scrollok(). If you want the cursor to be left in place after the last change, use leaveok(). If this isn't done, refresh() will move the cursor to the window's current (y, x) coordinates after updating it. You can create new windows of your own using the functions newwin(), derwin(), and subwin(). The routine delwin() will allow you to get rid of old windows. All the options described above can be applied to any window. Output Now that we have set things up, we will want to actually update the terminal. The basic functions used to change what will go on a window are addch() and move(). addch() adds a character at the current (y, x) coordinates. move() changes the current (y, x) coordinates to whatever you want them to be. It returns ERR if you try to move off the window. As mentioned above, you can combine the two into mvaddch() to do both things at once. The other output functions, such as addstr() and printw(), all call addch() to add characters to the window. After you have put on the window what you want there, when you want the portion of the terminal covered by the window to be made to look like it, you must call refresh(). In order to optimize finding changes, refresh() assumes that any part of the window not changed since the last refresh() of that window has not been changed on the terminal, i.e., that you have not refreshed a portion of the terminal with an overlapping window. If this is not the case, the routine touchwin() is provided to make it look like the entire window has been changed, thus making refresh() check the whole subsection of the terminal for changes. If you call wrefresh() with curscr as its argument, it will make the screen look like curscr thinks it looks like. This is useful for implementing a command which would redraw the screen in case it get messed up. Input The complementary function to addch() is getch() which, if echo is set, will call addch() to echo the character. Since the screen package needs to know what is on the terminal at all times, if characters are to be echoed, the tty must be in raw or cbreak mode. Since initially the terminal has echoing enabled and is in ordinary ``cooked'' mode, one or the other has to changed before calling getch(); otherwise, the program's output will be unpredictable. When you need to accept line-oriented input in a window, the functions wgetstr() and friends are available. There is even a wscanw() function that can do scanf()(3)-style multi-field parsing on window input. These pseudo-line-oriented functions turn on echoing while they execute. The example code above uses the call keypad(stdscr, TRUE) to enable support for function-key mapping. With this feature, the getch() code watches the input stream for character sequences that correspond to arrow and function keys. These sequences are returned as pseudo-character values. The #define values returned are listed in the curses.h The mapping from sequences to #define values is determined by key_ capabilities in the terminal's terminfo entry. Using Forms Characters The addch() function (and some others, including box() and border()) can accept some pseudo-character arguments which are specially defined by ncurses. These are #define values set up in the curses.h header; see there for a complete list (look for the prefix ACS_). The most useful of the ACS defines are the forms-drawing characters. You can use these to draw boxes and simple graphs on the screen. If the terminal does not have such characters, curses.h will map them to a recognizable (though ugly) set of ASCII defaults. Character Attributes and Color The ncurses package supports screen highlights including standout, reverse-video, underline, and blink. It also supports color, which is treated as another kind of highlight. Highlights are encoded, internally, as high bits of the pseudo-character type (chtype) that curses.h uses to represent the contents of a screen cell. See the curses.h header file for a complete list of highlight mask values (look for the prefix A_). There are two ways to make highlights. One is to logical-or the value of the highlights you want into the character argument of an addch() call, or any other output call that takes a chtype argument. The other is to set the current-highlight value. This is logical-or'ed with any highlight you specify the first way. You do this with the functions attron(), attroff(), and attrset(); see the manual pages for details. Color is a special kind of highlight. The package actually thinks in terms of color pairs, combinations of foreground and background colors. The sample code above sets up eight color pairs, all of the guaranteed-available colors on black. Note that each color pair is, in effect, given the name of its foreground color. Any other range of eight non-conflicting values could have been used as the first arguments of the init_pair() values. Once you've done an init_pair() that creates color-pair N, you can use COLOR_PAIR(N) as a highlight that invokes that particular color combination. Note that COLOR_PAIR(N), for constant N, is itself a compile-time constant and can be used in initializers. Mouse Interfacing The ncurses library also provides a mouse interface. NOTE: this facility is specific to ncurses, it is not part of either the XSI Curses standard, nor of System V Release 4, nor BSD curses. System V Release 4 curses contains code with similar interface definitions, however it is not documented. Other than by disassembling the library, we have no way to determine exactly how that mouse code works. Thus, we recommend that you wrap mouse-related code in an #ifdef using the feature macro NCURSES_MOUSE_VERSION so it will not be compiled and linked on non-ncurses systems. Presently, mouse event reporting works in the following environments: * xterm and similar programs such as rxvt. * Linux console, when configured with gpm(1), Alessandro Rubini's mouse server. * FreeBSD sysmouse (console) * OS/2 EMX The mouse interface is very simple. To activate it, you use the function mousemask(), passing it as first argument a bit-mask that specifies what kinds of events you want your program to be able to see. It will return the bit-mask of events that actually become visible, which may differ from the argument if the mouse device is not capable of reporting some of the event types you specify. Once the mouse is active, your application's command loop should watch for a return value of KEY_MOUSE from wgetch(). When you see this, a mouse event report has been queued. To pick it off the queue, use the function getmouse() (you must do this before the next wgetch(),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -