📄 ncurses-intro.html
字号:
screen. The right way to handle this is to use <CODE>subwin()</CODE>, ornot touch <CODE>stdscr</CODE> at all and tile your screen with declaredwindows which you then <CODE>wnoutrefresh()</CODE> somewhere in your programevent loop, with a single <CODE>doupdate()</CODE> call to trigger actualrepainting. <P>You are much less likely to run into problems if you design your screenlayouts to use tiled rather than overlapping windows. Historically,curses support for overlapping windows has been weak, fragile, and poorlydocumented. The <CODE>ncurses</CODE> library is not yet an exception to thisrule. <P>There is a panels library included in the <CODE>ncurses</CODE>distribution that does a pretty good job of strengthening theoverlapping-windows facilities. <P>Try to avoid using the global variables LINES and COLS. Use<CODE>getmaxyx()</CODE> on the <CODE>stdscr</CODE> context instead. Reason:your code may be ported to run in an environment with window resizes,in which case several screens could be open with different sizes.<H3><A NAME="leaving">Temporarily Leaving NCURSES Mode</A></H3>Sometimes you will want to write a program that spends most of its time inscreen mode, but occasionally returns to ordinary `cooked' mode. A commonreason for this is to support shell-out. This behavior is simple to arrangein <CODE>ncurses</CODE>. <P>To leave <CODE>ncurses</CODE> mode, call <CODE>endwin()</CODE> as you would if youwere intending to terminate the program. This will take the screen back tocooked mode; you can do your shell-out. When you want to return to<CODE>ncurses</CODE> mode, simply call <CODE>refresh()</CODE> or <CODE>doupdate()</CODE>.This will repaint the screen. <P>There is a boolean function, <CODE>isendwin()</CODE>, which code can use totest whether <CODE>ncurses</CODE> screen mode is active. It returns <CODE>TRUE</CODE>in the interval between an <CODE>endwin()</CODE> call and the following<CODE>refresh()</CODE>, <CODE>FALSE</CODE> otherwise. <P>Here is some sample code for shellout:<PRE> addstr("Shelling out..."); def_prog_mode(); /* save current tty modes */ endwin(); /* restore original tty modes */ system("sh"); /* run shell */ addstr("returned.\n"); /* prepare return message */ refresh(); /* restore save modes, repaint screen */</PRE><H3><A NAME="xterm">Using NCURSES under XTERM</A></H3>A resize operation in X sends SIGWINCH to the application running under xterm.The <CODE>ncurses</CODE> library provides an experimental signalhandler, but in general does not catch this signal, because it cannotknow how you want the screen re-painted. You will usually have to write theSIGWINCH handler yourself. Ncurses can give you some help. <P>The easiest way to code your SIGWINCH handler is to have it do an<CODE>endwin</CODE>, followed by an <CODE>refresh</CODE> and a screen repaint you codeyourself. The <CODE>refresh</CODE> will pick up the new screen size from thexterm's environment. <P>That is the standard way, of course (it even works with some vendor's cursesimplementations).Its drawback is that it clears the screen to reinitialize the display, and doesnot resize subwindows which must be shrunk.<CODE>Ncurses</CODE> provides an extension which works better, the<CODE>resizeterm</CODE> function. That function ensures that all windowsare limited to the new screen dimensions, and pads <CODE>stdscr</CODE>with blanks if the screen is larger. <P>Finally, ncurses can be configured to provide its own SIGWINCH handler,based on <CODE>resizeterm</CODE>.<H3><A NAME="screens">Handling Multiple Terminal Screens</A></H3>The <CODE>initscr()</CODE> function actually calls a function named<CODE>newterm()</CODE> to do most of its work. If you are writing a program thatopens multiple terminals, use <CODE>newterm()</CODE> directly. <P>For each call, you will have to specify a terminal type and a pair of filepointers; each call will return a screen reference, and <CODE>stdscr</CODE> will beset to the last one allocated. You will switch between screens with the<CODE>set_term</CODE> call. Note that you will also have to call<CODE>def_shell_mode</CODE> and <CODE>def_prog_mode</CODE> on each tty yourself.<H3><A NAME="testing">Testing for Terminal Capabilities</A></H3>Sometimes you may want to write programs that test for the presence of variouscapabilities before deciding whether to go into <CODE>ncurses</CODE> mode. An easyway to do this is to call <CODE>setupterm()</CODE>, then use the functions<CODE>tigetflag()</CODE>, <CODE>tigetnum()</CODE>, and <CODE>tigetstr()</CODE> to do yourtesting. <P>A particularly useful case of this often comes up when you want totest whether a given terminal type should be treated as `smart'(cursor-addressable) or `stupid'. The right way to test this is to seeif the return value of <CODE>tigetstr("cup")</CODE> is non-NULL. Alternatively,you can include the <CODE>term.h</CODE> file and test the value of themacro <CODE>cursor_address</CODE>.<H3><A NAME="tuning">Tuning for Speed</A></H3>Use the <CODE>addchstr()</CODE> family of functions for fastscreen-painting of text when you know the text doesn't contain anycontrol characters. Try to make attribute changes infrequent on yourscreens. Don't use the <CODE>immedok()</CODE> option!<H3><A NAME="special">Special Features of NCURSES</A></H3>The <CODE>wresize()</CODE> function allows you to resize a window in place.The associated <CODE>resizeterm()</CODE> function simplifies the constructionof <a HREF="#xterm">SIGWINCH</a> handlers, for resizing all windows. <P>The <CODE>define_key()</CODE> function allows youto define at runtime function-key control sequences which are not in theterminal description.The <CODE>keyok()</CODE> function allows you to temporarilyenable or disable interpretation of any function-key control sequence. <P>The <CODE>use_default_colors()</CODE> function allows you to constructapplications which can use the terminal's default foreground andbackground colors as an additional "default" color.Several terminal emulators support this feature, which is based on ISO 6429. <P>Ncurses supports up 16 colors, unlike SVr4 curses which defines only 8.While most terminals which provide color allow only 8 colors, abouta quarter (including XFree86 xterm) support 16 colors.<H2><A NAME="compat">Compatibility with Older Versions</A></H2>Despite our best efforts, there are some differences between <CODE>ncurses</CODE>and the (undocumented!) behavior of older curses implementations. These arisefrom ambiguities or omissions in the documentation of the API.<H3><A NAME="refbug">Refresh of Overlapping Windows</A></H3>If you define two windows A and B that overlap, and then alternately scribbleon and refresh them, the changes made to the overlapping region under historic<CODE>curses</CODE> versions were often not documented precisely. <P>To understand why this is a problem, remember that screen updates arecalculated between two representations of the <EM>entire</EM> display. Thedocumentation says that when you refresh a window, it is first copied to to thevirtual screen, and then changes are calculated to update the physical screen(and applied to the terminal). But "copied to" is not very specific, andsubtle differences in how copying works can produce different behaviors in thecase where two overlapping windows are each being refreshed at unpredictableintervals. <P>What happens to the overlapping region depends on what <CODE>wnoutrefresh()</CODE>does with its argument -- what portions of the argument window it copies to thevirtual screen. Some implementations do "change copy", copying down onlylocations in the window that have changed (or been marked changed with<CODE>wtouchln()</CODE> and friends). Some implementations do "entire copy",copying <EM>all</EM> window locations to the virtual screen whether or notthey have changed. <P>The <CODE>ncurses</CODE> library itself has not always been consistent on thisscore. Due to a bug, versions 1.8.7 to 1.9.8a did entire copy. Versions1.8.6 and older, and versions 1.9.9 and newer, do change copy. <P>For most commercial curses implementations, it is not documented and not knownfor sure (at least not to the <CODE>ncurses</CODE> maintainers) whether they dochange copy or entire copy. We know that System V release 3 curses has logicin it that looks like an attempt to do change copy, but the surrounding logicand data representations are sufficiently complex, and our knowledgesufficiently indirect, that it's hard to know whether this is reliable.It is not clear what the SVr4 documentation and XSI standard intend. The XSICurses standard barely mentions wnoutrefresh(); the SVr4 documents seem to bedescribing entire-copy, but it is possible with some effort and straining toread them the other way. <P>It might therefore be unwise to rely on either behavior in programs that mighthave to be linked with other curses implementations. Instead, you can do anexplicit <CODE>touchwin()</CODE> before the <CODE>wnoutrefresh()</CODE> call toguarantee an entire-contents copy anywhere. <P>The really clean way to handle this is to use the panels library. If,when you want a screen update, you do <CODE>update_panels()</CODE>, it willdo all the necessary <CODE>wnoutrfresh()</CODE> calls for whatever panelstacking order you have defined. Then you can do one <CODE>doupdate()</CODE>and there will be a <EM>single</EM> burst of physical I/O that will doall your updates.<H3><A NAME="backbug">Background Erase</A></H3>If you have been using a very old versions of <CODE>ncurses</CODE> (1.8.7 orolder) you may be surprised by the behavior of the erase functions. In olderversions, erased areas of a window were filled with a blank modified by thewindow's current attribute (as set by <STRONG>wattrset()</STRONG>, <STRONG>wattron()</STRONG>,<STRONG>wattroff()</STRONG> and friends). <P>In newer versions, this is not so. Instead, the attribute of erased blanksis normal unless and until it is modified by the functions <CODE>bkgdset()</CODE>or <CODE>wbkgdset()</CODE>. <P>This change in behavior conforms <CODE>ncurses</CODE> to System V Release 4 andthe XSI Curses standard.<H2><A NAME="xsifuncs">XSI Curses Conformance</A></H2>The <CODE>ncurses</CODE> library is intended to be base-level conformant with theXSI Curses standard from X/Open. Many extended-level features (in fact, almostall features not directly concerned with wide characters andinternationalization) are also supported. <P>One effect of XSI conformance is the change in behavior described under<A HREF="#backbug">"Background Erase -- Compatibility with Old Versions"</A>. <P>Also, <CODE>ncurses</CODE> meets the XSI requirement that every macroentry point have a corresponding function which may be linked (andwill be prototype-checked) if the macro definition is disabled with<CODE>#undef</CODE>.<H1><A NAME="panels">The Panels Library</A></H1>The <CODE>ncurses</CODE> library by itself provides good support for screendisplays in which the windows are tiled (non-overlapping). In the moregeneral case that windows may overlap, you have to use a series of<CODE>wnoutrefresh()</CODE> calls followed by a <CODE>doupdate()</CODE>, and becareful about the order you do the window refreshes in. It has to bebottom-upwards, otherwise parts of windows that should be obscured willshow through. <P>When your interface design is such that windows may dive deeper into thevisibility stack or pop to the top at runtime, the resulting book-keepingcan be tedious and difficult to get right. Hence the panels library. <P>The <CODE>panel</CODE> library first appeared in AT&T System V. Theversion documented here is the <CODE>panel</CODE> code distributedwith <CODE>ncurses</CODE>.<H2><A NAME="pcompile">Compiling With the Panels Library</A></H2>Your panels-using modules must import the panels library declarations with<PRE> #include <panel.h></PRE>and must be linked explicitly with the panels library using an<CODE>-lpanel</CODE> argument. Note that they must also link the<CODE>ncurses</CODE> library with <CODE>-lncurses</CODE>. Many linkersare two-pass and will accept either order, but it is still good practiceto put <CODE>-lpanel</CODE> first and <CODE>-lncurses</CODE> second.<H2><A NAME="poverview">Overview of Panels</A></H2>A panel object is a window that is implicitly treated as part of a<DFN>deck</DFN> including all other panel objects. The deck has an implicitbottom-to-top visibility order. The panels library includes an updatefunction (analogous to <CODE>refresh()</CODE>) that displays all panels in thedeck in the proper order to resolve overlaps. The standard window,<CODE>stdscr</CODE>, is considered below all panels. <P>Details on the panels functions are available in the man pages. We'll justhit the highlights here. <P>You create a panel from a window by calling <CODE>new_panel()</CODE> on awindow pointer. It then becomes the top of the deck. The panel's windowis available as the value of <CODE>panel_window()</CODE> called with thepanel pointer as argument.<P>You can delete a panel (removing it from the deck) with <CODE>del_panel</CODE>.This will not deallocate the associated window; you have to do that yourself.You can replace a panel's window with a different window by calling<CODE>replace_window</CODE>. The new window may be of different size;the panel code will re-compute all overlaps. This operation doesn'tchange the panel's position in the deck. <P>To move a panel's window, use <CODE>move_panel()</CODE>. The<CODE>mvwin()</CODE> function on the panel's window isn't sufficient because itdoesn't update the panels library's representation of where the windows are.This operation leaves the panel's depth, contents, and size unchanged. <P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -