SSSSccccrrrreeeeeeeennnn UUUUppppddddaaaattttiiiinnnngggg aaaannnndddd CCCCuuuurrrrssssoooorrrr MMMMoooovvvveeeemmmmeeeennnntttt OOOOppppttttiiiimmmmiiiizzzzaaaattttiiiioooonnnn:::: AAAA LLLLiiiibbbbrrrraaaarrrryyyy PPPPaaaacccckkkkaaaaggggeeee _K_e_n_n_e_t_h _C_. _R_. _C_. _A_r_n_o_l_d _E_l_a_n _A_m_i_r Computer Science Division Department of Electrical Engineering and Computer Science University of California, Berkeley Berkeley, California 94720 _AA_BB_SS_TT_RR_AA_CC_TT This document describes a package of C library functions which allow the user to: 1) update a screen with reasonable optimization, 2) get input from the terminal in a screen-oriented fashion, and 3) independent from the above, move the cursor opti- mally from one point to another. These routines all use the _t_e_r_m_c_a_p(5) database to describe the capabilities of the terminal. AAAAcccckkkknnnnoooowwwwlllleeeeddddggggeeeemmmmeeeennnnttttssss This package would not exist without the work of Bill Joy, who, in writing his editor, created the capability to generally describe terminals, wrote the routines which read this database, and, most importantly, those which implement optimal cursor movement, which routines I have simply lifted nearly intact. Doug Merritt and Kurt Shoens also were extremely important, as were both willing to waste time lis- tening to me rant and rave. The help and/or support of Ken Abrams, Alan Char, Mark Horton, and Joe Kalash, was, and is, also greatly appreciated. _K_e_n _A_r_n_o_l_d _1_6 _A_p_r_i_l _1_9_8_6 The help and/or support of Kirk McKusick and Keith Bostic (public vi!) was invaluable in bringing the package ``into the 90's'', which now includes completely new data structures and screen refresh optimization routines. _E_l_a_n _A_m_i_r _2_9 _D_e_c_e_m_b_e_r _1_9_9_2 SSSSccccrrrreeeeeeeennnn PPPPaaaacccckkkkaaaaggggeeee PPPPSSSS1111::::11119999----1111 1111.... OOOOvvvveeeerrrrvvvviiiieeeewwww In making available the generalized terminal descrip- tions in _t_e_r_m_c_a_p(5), much information was made available to the programmer, but little work was taken out of one's hands. The purpose of this package is to allow the C pro- grammer to do the most common type of terminal dependent functions, those of movement optimization and optimal screen updating, without doing any of the dirty work, and with nearly as much ease as is necessary to simply print or read things. 1111....1111.... TTTTeeeerrrrmmmmiiiinnnnoooollllooooggggyyyy In this document, the following terminology is used: wwwwiiiinnnnddddoooowwww: An internal representation containing an image of what a section of the terminal screen may look like at some point in time. This subsection can either encom- pass the entire terminal screen, or any smaller portion down to a single character within that screen. tttteeeerrrrmmmmiiiinnnnaaaallll: Sometimes called tttteeeerrrrmmmmiiiinnnnaaaallll ssssccccrrrreeeeeeeennnn. The package's idea of what the terminal's screen currently looks like, _i_._e_., what the user sees now. This is a special _s_c_r_e_e_n: ssssccccrrrreeeeeeeennnn: This is a subset of windows which are as large as the terminal screen, _i_._e_., they start at the upper left hand corner and encompass the lower right hand corner. One of these, _s_t_d_s_c_r, is automatically provided for the programmer. 1111....2222.... CCCCoooommmmppppiiiilllliiiinnnngggg AAAApppppppplllliiiiccccaaaattttiiiioooonnnnssss In order to use the library, it is necessary to have certain types and variables defined. Therefore, the pro- grammer must have a line: ####iiiinnnncccclllluuuuddddeeee <<<>>> at the top of the program source. Compilations should have the following form: _c_c [ flags ] file ... _-_l_c_u_r_s_e_s _-_l_t_e_r_m_c_a_p 1111....3333.... SSSSccccrrrreeeeeeeennnn UUUUppppddddaaaattttiiiinnnngggg In order to update the screen optimally, it is neces- sary for the routines to know what the screen currently looks like and what the programmer wants it to look like next. For this purpose, a data type (structure) named SSSSccccrrrreeeeeeeennnn PPPPaaaacccckkkkaaaaggggeeee PPPPSSSS1111::::11119999----3333 _W_I_N_D_O_W is defined which describes a window image to the rou- tines, including its starting position on the screen (the (y, x) co-ordinates of the upper left hand corner) and its size. One of these (called _c_u_r_s_c_r for _c_u_r_r_e_n_t _s_c_r_e_e_n) is a screen image of what the terminal currently looks like. Another screen (called _s_t_d_s_c_r, for _s_t_a_n_d_a_r_d _s_c_r_e_e_n) is pro- vided by default to make changes on. A window is a purely internal representation. It is used to build and store a potential image of a portion of the terminal. It doesn't bear any necessary relation to what is really on the terminal screen. It is more like an array of characters on which to make changes. When one has a window which describes what some part the terminal should look like, the routine refresh() (or wrefresh() if the window is not _s_t_d_s_c_r) is called. Refresh() makes the terminal, in the area covered by the window, look like that window. Note, therefore, that chang- ing something on a window _d_o_e_s _nn_oo_tt _c_h_a_n_g_e _t_h_e _t_e_r_m_i_n_a_l. Actual updates to the terminal screen are made only by call- ing refresh() or wrefresh(). This allows the programmer to maintain several different ideas of what a portion of the terminal screen should look like. Also, changes can be made to windows in any order, without regard to motion effi- ciency. Then, at will, the programmer can effectively say "make it look like this", and the package will execute the changes in an optimal way. 1111....4444.... NNNNaaaammmmiiiinnnngggg CCCCoooonnnnvvvveeeennnnttttiiiioooonnnnssss As hinted above, the routines can use several windows, but two are always available: _c_u_r_s_c_r, which is the image of what the terminal looks like at present, and _s_t_d_s_c_r, which is the image of what the programmer wants the terminal to look like next. The user should not access _c_u_r_s_c_r directly. Changes should be made to the appropriate screen, and then the routine refresh() (or wrefresh()) should be called. Many functions are set up to deal with _s_t_d_s_c_r as a default screen. For example, to add a character to _s_t_d_s_c_r, one calls addch() with the desired character. If a differ- ent window is to be used, the routine waddch() (for wwwwindow- specific addch()) is provided1. This convention of prepend- ing function names with a "_w" when they are to be applied to specific windows is consistent. The only routines which do _n_o_t do this are those to which a window must always be ____________________ 1 Actually, addch() is really a "#define" macro with ar- guments, as are most of the "functions" which act upon _s_t_d_- _s_c_r. PPPPSSSS1111::::11119999----4444 SSSSccccrrrreeeeeeeennnn PPPPaaaacccckkkkaaaaggggeeee specified. In order to move the current (y, x) co-ordinates 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 clumsi- ness, most I/O routines can be preceded by the prefix "_m_v" and the desired (y, x) co-ordinates can then be added 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 (_w_i_n) comes before the added (y, x) co-ordinates. If a window pointer is needed, it is always the first parameter passed. 2222.... VVVVaaaarrrriiiiaaaabbbblllleeeessss Many variables which are used to describe the terminal environment are available to the programmer. They are: type name description ------------------------------------------------------------------- WINDOW *curscr current version of the screen (terminal screen). WINDOW *stdscr standard screen. Most updates are usually done here. char * Def_termdefault terminal type if type cannot be determined bool My_term use the terminal specification in _D_e_f___t_e_r_m as ter- minal, irrelevant of real terminal type char * ttytype full name of the current terminal. int LINES number of lines on the terminal int COLS number of columns on the terminal int ERR error flag returned by routines on a fail. int OK flag returned by routines upon success. SSSSccccrrrreeeeeeeennnn PPPPaaaacccckkkkaaaaggggeeee PPPPSSSS1111::::11119999----5555 3333.... UUUUssssaaaaggggeeee This is a description of how to actually use the screen package. For simplicity, we assume all updating, reading, etc. is applied to _s_t_d_s_c_r, although a different window can of course be specified. 3333....1111.... IIIInnnniiiittttiiiiaaaalllliiiizzzzaaaattttiiiioooonnnn In order to use the screen package, the routines must know about terminal characteristics, and the space for _c_u_r_s_c_r and _s_t_d_s_c_r must be allocated. These functions are performed by initscr(). Since it must allocate space for the windows, it can overflow core when attempting to do so. On this rather rare occasion, initscr() returns ERR. Initscr() must _aa_ll_ww_aa_yy_ss 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 _c_u_r_s_c_r or _s_t_d_s_c_r are refer- enced. 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(). After the initial window allocation done by initscr(), specific window characteristics can be set. Scrolling can be enabled by calling scrollok(). If you want the cursor to be left after the last change, use leaveok(). If this isn't done, refresh() will move the cursor to the window's current (y, x) co-ordinates after updating it. Additional windows can be created by using the functions newwin() and subwin(). Delwin() allows you to delete an exisiting window. The variables _L_I_N_E_S and _C_O_L_S control the size of the terminal. They are initially implicitly set by initscr(), but can be altered explicitly by the user followed by a call to initscr(). Note that any call to initscr(), will always delete any existing _s_t_d_s_c_r and/or _c_u_r_s_c_r before creating new ones so this change is best done before the initial call to initscr(). 3333....2222.... OOOOuuuuttttppppuuuutttt 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) co-ordinates, returning ERR if it would cause the window to illegally scroll, _i_._e_., printing a char- acter in the lower right-hand corner of a terminal which automatically scrolls if scrolling is not allowed. Move() changes the current (y, x) co-ordinates to whatever you want them to be. It returns ERR if you try to move off the win- dow. As mentioned above, you can combine the two into mvad- dch() to do both things in one call. PPPPSSSS1111::::11119999----6666 SSSSccccrrrreeeeeeeennnn PPPPaaaacccckkkkaaaaggggeeee The other output functions (such as addstr() and printw()) all call addch() to add characters to the window. After a change has been made to the window, you must call refresh(). when you want the portion of the terminal covered by the window to reflect the change. In order to optimize finding changes, refresh() assumes that any part of the window not changed since the last refresh() of that win- dow has not been changed on the terminal, _i_._e_., that you have not refreshed a portion of the terminal with an over- lapping window. If this is not the case, the routines touchwin(), touchline(), and touchoverlap() are provided to make it look like a desired part of window has been changed, thus forcing refresh() to check that whole subsection of the terminal for changes. If you call wrefresh() with _c_u_r_s_c_r, it will make the screen look like the image of _c_u_r_s_c_r. This is useful for implementing a command which would redraw the screen in case it got messed up. 3333....3333.... IIIInnnnppppuuuutttt Input is essentially a mirror image of output. 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. If it is not, getch() sets it to be cbreak, and then reads in the character. 3333....4444.... TTTTeeeerrrrmmmmiiiinnnnaaaattttiiiioooonnnn In order to perform certain optimizations, and, on some terminals, to work at all, some things must be done before the screen routines start up. These functions are performed in getttmode() and setterm(), which are called by initscr(). In order to clean up after the routines, the routine end- win() is provided. It restores tty modes to what they were when initscr() was first called. The terminal state module uses the variable _c_u_r_s_e_s___t_e_r_m_i_o_s to save the original termi- nal state which is then restored upon a call to endwin(). Thus, anytime after the call to initscr, endwin() should be called before exiting. Note however, that endwin() should always be called bbbbeeeeffffoooorrrreeee the final calls to delwin(), which free the storage of the windows. 4444.... CCCCuuuurrrrssssoooorrrr MMMMoooovvvveeeemmmmeeeennnntttt OOOOppppttttiiiimmmmiiiizzzzaaaattttiiiioooonnnnssss One of the most difficult things to do properly is motion optimization. After using gettmode() and setterm() to get the terminal descriptions, the function mvcur() deals with this task. It usage is simple: simply tell it where SSSSccccrrrreeeeeeeennnn PPPPaaaacccckkkkaaaaggggeeee PPPPSSSS1111::::11119999----7777 you are now and where you want to go. For example mvcur(0, 0, LINES/2, COLS/2); would move the cursor from the home position (0, 0) to the middle of the screen. If you wish to force absolute addressing, you can use the function tgoto() from the tttteeeerrrrmmmmlllliiiibbbb(7) routines, or you can tell mvcur() that you are impossibly far away, For example, to absolutely address the lower left hand corner of the screen from anywhere just claim that you are in the upper right hand corner: mvcur(0, COLS-1, LINES-1, 0); 5555.... CCCChhhhaaaarrrraaaacccctttteeeerrrr OOOOuuuuttttppppuuuutttt aaaannnndddd SSSSccccrrrroooolllllllliiiinnnngggg The character output policy deals with the following problems. First, where is the location of the cursor after a character is printed, and secondly, when does the screen scroll if scrolling is enabled. In the normal case the characters are output as expected, with the cursor occupying the position of the next character to be output. However, when the cursor is on the last column of the line, the cursor will remain on that position after the last character on the line is output and will only assume the position on the next line when the next character (the first on the next line) is output. Likewise, if scrolling is enabled, a scroll will be invoked only when the first character on he first line past the bottom line of the window is output. If scrolling is not enabled the chracters will to be output to the bottom right corner of the window which is the cursor location. This policy allows consistent behavior of the cursor at the boundary conditions. Furthermore, it prevents a scroll from happening before it is actually needed (the old package used to scroll when the bottom right position was output a character). As a precendent, it models the _x_t_e_r_m character output conventions. 6666.... TTTTeeeerrrrmmmmiiiinnnnaaaallll SSSSttttaaaatttteeee HHHHaaaannnnddddlllliiiinnnngggg The variable _c_u_r_s_e_s___t_e_r_m_i_o_s contains the terminal state of the terminal. Certain historical routines return infor- mation: baudrate(), erasechar(), killchar(), and ospeed(). These routines are obsolete and exist only for backward com- patibility. If you wish to use the information in the _c_u_r_s_e_s___t_e_r_m_i_o_s structure, you should use the _t_s_e_t_a_t_t_r(3) routines. PPPPSSSS1111::::11119999----8888 SSSSccccrrrreeeeeeeennnn PPPPaaaacccckkkkaaaaggggeeee 7777.... SSSSuuuubbbbwwwwiiiinnnnddddoooowwwwssss Subwindows are windows which do not have an independent text structure, _i_._e_., they are windows whose text is a sub- set of the text of a larger window: the _p_a_r_e_n_t window. One consequence of this is that changes to either the parent or the child window are destructive to the other, _i_._e_., a change to the subwindow is also a change to the parent win- dow and a change to the parent window in the region defined by the subwindow is implicitly a change to the subwindow as well. Apart from this detail, subwindows function like any other window. 8888.... TTTThhhheeee FFFFuuuunnnnccccttttiiiioooonnnnssss In the following definitions, "[*]" means that the "function" is really a "#define" macro with arguments. addch_(_c_h_a_r _c_h_)_;_|_- Add the character _c_h on the window at the current (y, x) co-ordinates. If the character is a newline ('\n') the line will be cleared to the end, and the current (y, x) co-ordinates will be changed to the beginning off the next line if newline mapping is on, or to the next line at the same x co-ordinate if it is off. A return ('\r') will move to the beginning of the line on the window. Tabs ('\t') will be expanded into spaces in the normal tabstop positions of every eight characters. This returns ERR if it would cause the screen to scroll illegally. addstr_(_c_h_a_r _*_s_t_r_)_;_|_- Add the string pointed to by _s_t_r on the window at the current (y, x) co-ordinates. This returns ERR if it would cause the screen to scroll illegally. In this case, it will put on as much as it can. baudrate_(_)_;_|_- Returns the output baud rate of the terminal. This is a system dependent constant (defined in <<<>>> on BSD systems, which is included by <<<>>>). box_(_W_I_N_D_O_W _w_i_n_, _c_h_a_r _v_e_r_t_, _c_h_a_r _h_o_r_)_; Draws a box around the window using _v_e_r_t as the charac- ter for drawing the vertical sides, and _h_o_r for drawing SSSSccccrrrreeeeeeeennnn PPPPaaaacccckkkkaaaaggggeeee PPPPSSSS1111::::11119999----9999 the horizontal lines. If scrolling is not allowed, and the window encompasses the lower right-hand corner of the terminal, the corners are left blank to avoid a scroll. cbreak_(_)_;_|_- Set or the terminal to cbreak mode. clear_(_)_;_|_- Resets the entire window to blanks. If _w_i_n is a screen, this sets the clear flag, which will cause a clear-screen sequence to be sent on the next refresh() call. This also moves the current (y, x) co-ordinates to (0, 0). clearok_(_W_I_N_D_O_W _*_s_c_r_, _i_n_t _b_o_o_l_f_)_;_|_- Sets the clear flag for the screen _s_c_r. If _b_o_o_l_f is non-zero, this will force a clear-screen to be printed on the next refresh(), or stop it from doing so if _b_o_o_l_f is 0. This only works on screens, and, unlike clear(), does not alter the contents of the screen. If _s_c_r is _c_u_r_s_c_r, the next refresh() call will cause a clear-screen, even if the window passed to refresh() is not a screen. clrtobot_(_)_;_|_- Wipes the window clear from the current (y, x) co-ordi- nates to the bottom. This does not force a clear- screen sequence on the next refresh under any circum- stances. This has no associated "mmmmvvvv" command. clrtoeol_(_)_;_|_- Wipes the window clear from the current (y, x) co-ordi- nates to the end of the line. This has no associated "mmmmvvvv" command. crmode_(_)_;_|_- Identical to cbreak(). The misnamed macro crmode() and nocrmode() is retained for backwards compatibility with ealier versions of the library. PPPPSSSS1111::::11119999----11110000 SSSSccccrrrreeeeeeeennnn PPPPaaaacccckkkkaaaaggggeeee delch_(_)_; Delete the character at the current (y, x) co-ordi- nates. Each character after it on the line shifts to the left, and the last character becomes blank. deleteln_(_)_; Delete the current line. Every line below the current one will move up, and the bottom line will become blank. The current (y, x) co-ordinates will remain unchanged. delwin_(_W_I_N_D_O_W _*_w_i_n_)_; Deletes the window from existence. All resources are freed for future use by ccccaaaalllllllloooocccc(3). If a window has a subwin() allocated window inside of it, deleting the outer window the subwindow is not affected, even though this does invalidate it. Therefore, subwindows should be deleted before their outer windows are. echo_(_)_;_|_- Sets the terminal to echo characters. endwin_(_)_; Finish up window routines before exit. This restores the terminal to the state it was before initscr() (or gettmode() and setterm()) was called. It should always be called before exiting and before the final calls to delwin(). It does not exit. This is especially useful for resetting tty stats when trapping rubouts via ssssiiiigggg---- nnnnaaaallll(2). erase_(_)_;_|_- Erases the window to blanks without setting the clear flag. This is analagous to clear(), except that it never causes a clear-screen sequence to be generated on a refresh(). This has no associated "mmmmvvvv" command. erasechar_(_)_;_|_- Returns the erase character for the terminal, _i_._e_., the character used by the user to erase a single character SSSSccccrrrreeeeeeeennnn PPPPaaaacccckkkkaaaaggggeeee PPPPSSSS1111::::11119999----11111111 from the input. flushok_(_W_I_N_D_O_W _*_w_i_n_, _i_n_t _b_o_o_l_f_)_; Normally, refresh() fflush(_'_s); _s_t_d_o_u_t when it is fin- ished. flushok() allows you to control this. if _b_o_o_l_f is non-zero (_i_._e_., non-zero) it will do the fflush(), otherwise it will not. getch_(_)_;_|_- Gets a character from the terminal and (if necessary) echos it on the window. This returns ERR if it would cause the screen to scroll illegally. Otherwise, the character gotten is returned. If _n_o_e_c_h_o has been set, then the window is left unaltered. In order to retain control of the terminal, it is necessary to have one of _n_o_e_c_h_o, _c_b_r_e_a_k, or _r_a_w_m_o_d_e set. If you do not set one, whatever routine you call to read characters will set _c_b_r_e_a_k for you, and then reset to the original mode when finished. getstr_(_c_h_a_r _*_s_t_r_)_;_|_- Get a string through the window and put it in the loca- tion pointed to by _s_t_r, which is assumed to be large enough to handle it. It sets tty modes if necessary, and then calls getch() (or wgetch()) to get the charac- ters needed to fill in the string until a newline or EOF is encountered. The newline stripped off the string. This returns ERR if it would cause the screen to scroll illegally. gettmode_(_)_; Get the tty stats. This is normally called by initscr(). getyx_(_W_I_N_D_O_W _*_w_i_n_, _i_n_t _y_, _i_n_t _x_)_; Puts the current (y, x) co-ordinates of _w_i_n in the variables _y and _x. Since it is a macro, not a func- tion, you do not pass the address of _y and _x. idlok_(_W_I_N_D_O_W _*_w_i_n_, _i_n_t _b_o_o_l_f_)_; PPPPSSSS1111::::11119999----11112222 SSSSccccrrrreeeeeeeennnn PPPPaaaacccckkkkaaaaggggeeee Reserved for future use. This will eventually signal to refresh() that it is all right to use the insert and delete line sequences when updating the window. inch_(_)_;_|_- Returns the character at the current position on the given window. This does not make any changes to the window. initscr_(_)_; Initialize the screen routines. This must be called before any of the screen routines are used. It ini- tializes the terminal-type data and such, and without it none of the routines can operate. If standard input is not a tty, it sets the specifications to the termi- nal whose name is pointed to by _D_e_f___t_e_r_m (initially "dumb"). If the boolean _M_y___t_e_r_m is non-zero, _D_e_f___t_e_r_m is always used. If the system supports the TTTTIIIIOOOOCCCCGGGGWWWWIIIINNNNSSSSZZZZ _i_o_c_t_l_(_2_) call, it is used to get the number of lines and columns for the terminal, otherwise it is taken from the tttteeeerrrrmmmmccccaaaapppp description. insch_(_c_h_a_r _c_)_; Insert _c at the current (y, x) co-ordinates Each char- acter after it shifts to the right, and the last char- acter disappears. This returns ERR if it would cause the screen to scroll illegally. insertln_(_)_; Insert a line above the current one. Every line below the current line will be shifted down, and the bottom line will disappear. The current line will become blank, and the current (y, x) co-ordinates will remain unchanged. killchar_(_)_;_|_- Returns the line kill character for the terminal, _i_._e_., the character used by the user to erase an entire line from the input. leaveok_(_W_I_N_D_O_W _*_w_i_n_, _i_n_t _b_o_o_l_f_)_;_|_- SSSSccccrrrreeeeeeeennnn PPPPaaaacccckkkkaaaaggggeeee PPPPSSSS1111::::11119999----11113333 Sets the boolean flag for leaving the cursor after the last change. If _b_o_o_l_f is non-zero, the cursor will be left after the last update on the terminal, and the current (y, x) co-ordinates for _w_i_n will be changed accordingly. If _b_o_o_l_f is 0 the cursor will be moved to the current (y, x) co-ordinates. This flag (initially 0) retains its value until changed by the user. move_(_i_n_t _y_, _i_n_t _x_)_; Change the current (y, x) co-ordinates of the window to (_y_, _x). This returns ERR if it would cause the screen to scroll illegally. mvcur_(_i_n_t _l_a_s_t_y_, _i_n_t _l_a_s_t_x_, _i_n_t _n_e_w_y_, _i_n_t _n_e_w_x_)_; Moves the terminal's cursor from (_l_a_s_t_y_, _l_a_s_t_x) to (_n_e_w_y_, _n_e_w_x) in an approximation of optimal fashion. This routine uses the functions borrowed from _e_x ver- sion 2.6. It is possible to use this optimization without the benefit of the screen routines. With the screen routines, this should not be called by the user. move() and refresh() should be used to move the cursor position, so that the routines know what's going on. mvprintw_(_i_n_t _y_, _i_n_t _x_, _c_o_n_s_t _c_h_a_r _*_f_m_t_, _._._._)_; Equivalent to: move(y, x); printw(fmt, ...); mvscanw_(_i_n_t _y_, _i_n_t _x_, _c_o_n_s_t _c_h_a_r _*_f_m_t_, _._._._)_; Equivalent to: move(y, x); scanw(fmt, ...); mvwin_(_W_I_N_D_O_W _*_w_i_n_, _i_n_t _y_, _i_n_t _x_)_; Move the home position of the window _w_i_n from its cur- rent starting coordinates to (_y_, _x). If that would put part or all of the window off the edge of the terminal screen, mvwin() returns ERR and does not change PPPPSSSS1111::::11119999----11114444 SSSSccccrrrreeeeeeeennnn PPPPaaaacccckkkkaaaaggggeeee anything. For subwindows, mvwin() also returns ERR if you attempt to move it off its main window. If you move a main window, all subwindows are moved along with it. mvwprintw_(_W_I_N_D_O_W _*_w_i_n_, _i_n_t _y_, _i_n_t _x_, _c_o_n_s_t _c_h_a_r _*_f_m_t_, _._._._)_; Equivalent to: wmove(win, y, x); printw(fmt, ...); mvwscanw_(_W_I_N_D_O_W _*_w_i_n_, _i_n_t _y_, _i_n_t _x_, _c_o_n_s_t _c_h_a_r _*_f_m_t_, _._._._)_; Equivalent to: wmove(win, y, x); scanw(fmt, ...); newwin_(_i_n_t _l_i_n_e_s_, _i_n_t _c_o_l_s_, _i_n_t _b_e_g_i_n___y_, _i_n_t _b_e_g_i_n___x_)_; Create a new window with _l_i_n_e_s lines and _c_o_l_s columns starting at position (_b_e_g_i_n___y_, _b_e_g_i_n___x). If either _l_i_n_e_s or _c_o_l_s is 0 (zero), that dimension will be set to (_L_I_N_E_S _- _b_e_g_i_n___y) or (_C_O_L_S _- _b_e_g_i_n___x) respectively. Thus, to get a new window of dimensions _L_I_N_E_S x _C_O_L_S, use newwin(_0, _0, _0, _0). nl_(_)_;_|_- Set the terminal to nl mode, _i_._e_., start/stop the sys- tem from mapping <<<>>> to <<<>>>. If the map- ping is not done, refresh() can do more optimization, so it is recommended, but not required, to turn it off. nocbreak_(_)_;_|_- Unset the terminal from cbreak mode. nocrmode_(_)_;_|_- Identical to nocbreak(). The misnamed macro nocrmode() is retained for backwards compatibility with ealier versions of the library. SSSSccccrrrreeeeeeeennnn PPPPaaaacccckkkkaaaaggggeeee PPPPSSSS1111::::11119999----11115555 noecho_(_)_;_|_- Turn echoing of characters off. nonl_(_)_;_|_- Unset the terminal to from nl mode. See nl(). noraw_(_)_;_|_- Unset the terminal from raw mode. See raw(). overlay_(_W_I_N_D_O_W _*_w_i_n_1_, _W_I_N_D_O_W _*_w_i_n_2_)_; Overlay _w_i_n_1 on _w_i_n_2. The contents of _w_i_n_1, insofar as they fit, are placed on _w_i_n_2 at their starting (y, x) co-ordinates. This is done non-destructively, i.e., blanks on _w_i_n_1 leave the contents of the space on _w_i_n_2 untouched. Note that all non-blank characters are overwritten destructively in the overlay. overwrite_(_W_I_N_D_O_W _*_w_i_n_1_, _W_I_N_D_O_W _*_w_i_n_2_)_; Overwrite _w_i_n_1 on _w_i_n_2. The contents of _w_i_n_1, insofar as they fit, are placed on _w_i_n_2 at their starting (y, x) co-ordinates. This is done destructively, _i_._e_., blanks on _w_i_n_1 become blank on _w_i_n_2. printw_(_c_h_a_r _*_f_m_t_, _._._._)_; Performs a printf() on the window starting at the cur- rent (y, x) co-ordinates. It uses addstr() to add the string on the window. It is often advisable to use the field width options of printf() to avoid leaving things on the window from earlier calls. This returns ERR if it would cause the screen to scroll illegally. raw_(_)_;_|_- Set the terminal to raw mode. On version 7 UUUUNNNNIIIIXXXX2222 this also turns off newline mapping (see nl()). ____________________ 2 UUUUNNNNIIIIXXXX is a trademark of Unix System Laboratories. PPPPSSSS1111::::11119999----11116666 SSSSccccrrrreeeeeeeennnn PPPPaaaacccckkkkaaaaggggeeee refresh_(_)_;_|_- Synchronize the terminal screen with the desired win- dow. If the window is not a screen, only that part covered by it is updated. This returns ERR if it would cause the screen to scroll illegally. In this case, it will update whatever it can without causing the scroll. As a special case, if wrefresh() is called with the window _c_u_r_s_c_r the screen is cleared and repainted as it is currently. This is very useful for allowing the redrawing of the screen when the user has garbage dumped on his terminal. resetty_(_)_;_|_- resetty() restores them to what savetty() stored. These functions are performed automatically by initscr() and endwin(). This function should not be used by the user. savetty_(_)_;_|_- savetty() saves the current tty characteristic flags. See resetty(). This function should not be used by the user. scanw_(_c_h_a_r _*_f_m_t_, _._._._)_; Perform a scanf() through the window using _f_m_t. It does this using consecutive calls to getch() (or wgetch()). This returns ERR if it would cause the screen to scroll illegally. scroll_(_W_I_N_D_O_W _*_w_i_n_)_; Scroll the window upward one line. This is normally not used by the user. scrollok_(_W_I_N_D_O_W _*_w_i_n_, _i_n_t _b_o_o_l_f_)_;_|_- Set the scroll flag for the given window. If _b_o_o_l_f is 0, scrolling is not allowed. This is its default set- ting. standend_(_)_;_|_- SSSSccccrrrreeeeeeeennnn PPPPaaaacccckkkkaaaaggggeeee PPPPSSSS1111::::11119999----11117777 End standout mode initiated by standout(). standout_(_)_;_|_- Causes any characters added to the window to be put in standout mode on the terminal (if it has that capabil- ity). subwin_(_W_I_N_D_O_W _*_w_i_n_, _i_n_t _l_i_n_e_s_, _i_n_t _c_o_l_s_, _i_n_t _b_e_g_i_n___y_, _i_n_t _b_e_g_i_n___x_)_; Create a new window with _l_i_n_e_s lines and _c_o_l_s columns starting at position (_b_e_g_i_n___y_, _b_e_g_i_n___x) inside the win- dow _w_i_n. This means that any change made to either window in the area covered by the subwindow will be made on both windows. _b_e_g_i_n___y_, _b_e_g_i_n___x are specified relative to the overall screen, not the relative (0, 0) of _w_i_n. If either _l_i_n_e_s or _c_o_l_s is 0 (zero), that dimension will be set to (_L_I_N_E_S _- _b_e_g_i_n___y) or (_C_O_L_S _- _b_e_g_i_n___x) respectively. touchline_(_W_I_N_D_O_W _*_w_i_n_, _i_n_t _y_, _i_n_t _s_t_a_r_t_x_, _i_n_t _e_n_d_x_)_; This function performs a function similar to touchwin() on a single line. It marks the first change for the given line to be _s_t_a_r_t_x, if it is before the current first change mark, and the last change mark is set to be _e_n_d_x if it is currently less than _e_n_d_x. touchoverlap_(_W_I_N_D_O_W _*_w_i_n_1_, _W_I_N_D_O_W _*_w_i_n_2_)_; Touch the window _w_i_n_2 in the area which overlaps with _w_i_n_1. If they do not overlap, no changes are made. touchwin_(_W_I_N_D_O_W _*_w_i_n_)_; Make it appear that the every location on the window has been changed. This is usually only needed for refreshes with overlapping windows. tstp_(_) This function will save the current tty state and then put the process to sleep. When the process gets restarted, it restores the saved tty state and then calls wrefresh(_c_u_r_s_c_r); to redraw the screen. Initscr() sets the signal SIGTSTP to trap to this rou- tine. PPPPSSSS1111::::11119999----11118888 SSSSccccrrrreeeeeeeennnn PPPPaaaacccckkkkaaaaggggeeee unctrl_(_c_h_a_r _*_c_h_)_;_|_- Returns a string which is an ASCII representation of _c_h. Characters are 8 bits long. unctrllen_(_c_h_a_r _*_c_h_)_;_|_- Returns the length of the ASCII representation of _c_h. vwprintw_(_W_I_N_D_O_W _*_w_i_n_, _c_o_n_s_t _c_h_a_r _*_f_m_t_, _v_a___l_i_s_t _a_p_)_; Identical to printw() except that it takes both a win- dow specification and a pointer to a variable length argument list. vwscanw_(_W_I_N_D_O_W _*_w_i_n_, _c_o_n_s_t _c_h_a_r _*_f_m_t_, _v_a___l_i_s_t _a_p_)_; Identical to scanw() except that it takes both a window specification and a pointer to a variable length argu- ment list. waddbytes_(_W_I_N_D_O_W _*_w_i_n_, _c_h_a_r _*_s_t_r_, _i_n_t _l_e_n_)_; This function is the low level character output func- tion. _L_e_n characters of the string _s_t_r are output to the current (y, x) co-ordinates position of the window specified by _w_i_n_. _T_h_e _f_o_l_l_o_w_i_n_g _f_u_n_c_t_i_o_n_s _d_i_f_f_e_r _f_r_o_m _t_h_e _s_t_a_n_d_a_r_d _f_u_n_c_- _t_i_o_n_s _o_n_l_y _i_n _t_h_e_i_r _s_p_e_c_i_f_i_c_a_t_i_o_n _o_f _a _w_i_n_d_o_w_, _r_a_t_h_e_r _t_h_a_n _t_h_e _u_s_e _o_f _t_h_e _d_e_f_a_u_l_t _s_t_d_s_c_r_. waddch_(_W_I_N_D_O_W _*_w_i_n_, _c_h_a_r _c_h_)_; waddstr_(_W_I_N_D_O_W _*_w_i_n_, _c_h_a_r _*_s_t_r_)_; wclear_(_W_I_N_D_O_W _*_w_i_n_)_; wclrtobot_(_W_I_N_D_O_W _*_w_i_n_)_; wclrtoeol_(_W_I_N_D_O_W _*_w_i_n_)_; wdelch_(_W_I_N_D_O_W _*_w_i_n_)_; wdeleteln_(_W_I_N_D_O_W _*_w_i_n_)_; werase_(_W_I_N_D_O_W _*_w_i_n_)_; wgetch_(_W_I_N_D_O_W _*_w_i_n_)_; wgetstr_(_W_I_N_D_O_W _*_w_i_n_, _c_h_a_r _*_s_t_r_)_; winch_(_W_I_N_D_O_W _*_w_i_n_)_;_|_- winsch_(_W_I_N_D_O_W _*_w_i_n_, _c_h_a_r _c_)_; winsertln_(_W_I_N_D_O_W _*_w_i_n_)_; wmove_(_W_I_N_D_O_W _*_w_i_n_, _i_n_t _y_, _i_n_t_, _x_"_)_; SSSSccccrrrreeeeeeeennnn PPPPaaaacccckkkkaaaaggggeeee PPPPSSSS1111::::11119999----11119999 wprintw_(_W_I_N_D_O_W _*_w_i_n_, _c_h_a_r _*_f_m_t_, _._._._)_; wrefresh_(_W_I_N_D_O_W _*_w_i_n_)_; wscanw_(_W_I_N_D_O_W _*_w_i_n_, _c_h_a_r _*_f_m_t_, _._._._)_; wstandend_(_W_I_N_D_O_W _*_w_i_n_)_; wstandout_(_W_I_N_D_O_W _*_w_i_n_)_; PPPPSSSS1111::::11119999----22220000 SSSSccccrrrreeeeeeeennnn PPPPaaaacccckkkkaaaaggggeeee 1111.... EEEExxxxaaaammmmpppplllleeeessss Here we present a few examples of how to use the pack- age. They attempt to be representative, though not compre- hensive. Further examples can be found in the games section of the source tree and in various utilities that use the screen such as _s_y_s_t_a_t_(_1_). The following examples are intended to demonstrate the basic structure of a program using the package. An addi- tional, more comprehensive, program can be found in the source code in the _e_x_a_m_p_l_e_s subdirectory. 1111....1111.... SSSSiiiimmmmpppplllleeee CCCChhhhaaaarrrraaaacccctttteeeerrrr OOOOuuuuttttppppuuuutttt This program demonstrates how to set up a window and output characters to it. Also, it demonstrates how one might control the output to the window. If you run this program, you will get a demonstration of the character out- put chracteristics discussed in the above Character Output section. _#_i_n_c_l_u_d_e _#_i_n_c_l_u_d_e _#_i_n_c_l_u_d_e _#_i_n_c_l_u_d_e _#_d_e_f_i_n_e YSIZE 10 _#_d_e_f_i_n_e XSIZE 20 _i_n_t quit(); main() _{ _i_n_t i, j, c; size_t len; _c_h_a_r id[100]; FILE _*fp; _c_h_a_r _*s; initscr(); _/_* _A_l_w_a_y_s _c_a_l_l _i_n_i_t_s_c_r_(_) _f_i_r_s_t _*_/ signal(SIGINT, quit); _/_* _M_a_k_e _s_u_r_e _w_o_u _h_a_v_e _a _'_c_l_e_a_n_u_p_' _f_n _*_/ crmode(); _/_* _W_e _w_a_n_t _c_b_r_e_a_k _m_o_d_e _*_/ noecho(); _/_* _W_e _w_a_n_t _t_o _h_a_v_e _c_o_n_t_r_o_l _o_f _c_h_a_r_s _*_/ delwin(stdscr); _/_* _C_r_e_a_t_e _o_u_r _o_w_n _s_t_d_s_c_r _*_/ stdscr = newwin(YSIZE, XSIZE, 10, 35); flushok(stdscr, TRUE); _/_* _E_n_a_b_l_e _f_l_u_s_h_i_n_g _o_f _s_t_d_o_u_t _*_/ scrollok(stdscr, TRUE); _/_* _E_n_a_b_l_e _s_c_r_o_l_l_i_n_g _*_/ erase(); _/_* _I_n_i_t_i_a_l_l_y_, _c_l_e_a_r _t_h_e _s_c_r_e_e_n _*_/ standout(); move(0,0); _A_p_p_e_n_d_i_x _A _w_h_i_l_e (1) _{ c = getchar(); _s_w_i_t_c_h(c) _{ _c_a_s_e 'q': _/_* _Q_u_i_t _o_n _'_q_' _*_/ quit(); _b_r_e_a_k; _c_a_s_e 's': _/_* _G_o _i_n_t_o _s_t_a_n_d_o_u_t _m_o_d_e _o_n _'_s_' _*_/ standout(); _b_r_e_a_k; _c_a_s_e 'e': _/_* _E_x_i_t _s_t_a_n_d_o_u_t _m_o_d_e _o_n _'_e_' _*_/ standend(); _b_r_e_a_k; _c_a_s_e 'r': _/_* _F_o_r_c_e _a _r_e_f_r_e_s_h _o_n _'_r_' _*_/ wrefresh(curscr); _b_r_e_a_k; _d_e_f_a_u_l_t: _/_* _B_y _d_e_f_a_u_l_t _o_u_t_p_u_t _t_h_e _c_h_a_r_a_c_t_e_r _*_/ addch(c); refresh(); _} _} _} _i_n_t quit() _{ erase(); _/_* _T_e_r_m_i_n_a_t_e _b_y _e_r_a_s_i_n_g _t_h_e _s_c_r_e_e_n _*_/ refresh(); endwin(); _/_* _A_l_w_a_y_s _e_n_d _w_i_t_h _e_n_d_w_i_n_(_) _*_/ delwin(curscr); _/_* _R_e_t_u_r_n _s_t_o_r_a_g_e _*_/ delwin(stdscr); putchar('\n'); exit(0); _} 1111....2222.... TTTTwwwwiiiinnnnkkkklllleeee This is a moderately simple program which prints pat- terns on the screen. It switches between patterns of aster- isks, putting them on one by one in random order, and then taking them off in the same fashion. It is more efficient to write this using only the motion optimization, as is demonstrated below. _# _i_n_c_l_u_d_e _# _i_n_c_l_u_d_e _A_p_p_e_n_d_i_x _A _/_* _* _t_h_e _i_d_e_a _f_o_r _t_h_i_s _p_r_o_g_r_a_m _w_a_s _a _p_r_o_d_u_c_t _o_f _t_h_e _i_m_a_g_i_n_a_t_i_o_n _o_f _* _K_u_r_t _S_c_h_o_e_n_s_. _N_o_t _r_e_s_p_o_n_s_i_b_l_e _f_o_r _m_i_n_d_s _l_o_s_t _o_r _s_t_o_l_e_n_. _*_/ _# _d_e_f_i_n_e NCOLS 80 _# _d_e_f_i_n_e NLINES 24 _# _d_e_f_i_n_e MAXPATTERNS 4 _t_y_p_e_d_e_f _s_t_r_u_c_t _{ _i_n_t y, x; _} LOCS; LOCS Layout[NCOLS _* NLINES]; _/_* _c_u_r_r_e_n_t _b_o_a_r_d _l_a_y_o_u_t _*_/ _i_n_t Pattern, _/_* _c_u_r_r_e_n_t _p_a_t_t_e_r_n _n_u_m_b_e_r _*_/ Numstars; _/_* _n_u_m_b_e_r _o_f _s_t_a_r_s _i_n _p_a_t_t_e_r_n _*_/ _c_h_a_r _*getenv(); _i_n_t die(); main() _{ srand(getpid()); _/_* _i_n_i_t_i_a_l_i_z_e _r_a_n_d_o_m _s_e_q_u_e_n_c_e _*_/ initscr(); signal(SIGINT, die); noecho(); nonl(); leaveok(stdscr, TRUE); scrollok(stdscr, FALSE); _f_o_r (;;) _{ makeboard(); _/_* _m_a_k_e _t_h_e _b_o_a_r_d _s_e_t_u_p _*_/ puton('_*'); _/_* _p_u_t _o_n _'_*_'_s _*_/ puton(' '); _/_* _c_o_v_e_r _u_p _w_i_t_h _' _'_s _*_/ _} _} _/_* _* _O_n _p_r_o_g_r_a_m _e_x_i_t_, _m_o_v_e _t_h_e _c_u_r_s_o_r _t_o _t_h_e _l_o_w_e_r _l_e_f_t _c_o_r_n_e_r _b_y _* _d_i_r_e_c_t _a_d_d_r_e_s_s_i_n_g_, _s_i_n_c_e _c_u_r_r_e_n_t _l_o_c_a_t_i_o_n _i_s _n_o_t _g_u_a_r_a_n_t_e_e_d_. _* _W_e _l_i_e _a_n_d _s_a_y _w_e _u_s_e_d _t_o _b_e _a_t _t_h_e _u_p_p_e_r _r_i_g_h_t _c_o_r_n_e_r _t_o _g_u_a_r_a_n_t_e_e _* _a_b_s_o_l_u_t_e _a_d_d_r_e_s_s_i_n_g_. _*_/ die() _{ signal(SIGINT, SIG_IGN); mvcur(0, COLS - 1, LINES - 1, 0); endwin(); exit(0); _} _A_p_p_e_n_d_i_x _A _/_* _* _M_a_k_e _t_h_e _c_u_r_r_e_n_t _b_o_a_r_d _s_e_t_u_p_. _I_t _p_i_c_k_s _a _r_a_n_d_o_m _p_a_t_t_e_r_n _a_n_d _* _c_a_l_l_s _i_s_o_n_(_) _t_o _d_e_t_e_r_m_i_n_e _i_f _t_h_e _c_h_a_r_a_c_t_e_r _i_s _o_n _t_h_a_t _p_a_t_t_e_r_n _* _o_r _n_o_t_. _*_/ makeboard() _{ reg _i_n_t y, x; reg LOCS _*lp; Pattern = rand() % MAXPATTERNS; lp = Layout; _f_o_r (y = 0; y < NLINES; y++) _f_o_r (x = 0; x < NCOLS; x++) _i_f (ison(y, x)) _{ lp->y = y; lp->x = x; lp++; _} Numstars = lp - Layout; _} _/_* _* _R_e_t_u_r_n _T_R_U_E _i_f _(_y_, _x_) _i_s _o_n _t_h_e _c_u_r_r_e_n_t _p_a_t_t_e_r_n_. _*_/ ison(y, x) reg _i_n_t y, x; _{ _s_w_i_t_c_h (Pattern) _{ _c_a_s_e 0: _/_* _a_l_t_e_r_n_a_t_i_n_g _l_i_n_e_s _*_/ _r_e_t_u_r_n !(y & 01); _c_a_s_e 1: _/_* _b_o_x _*_/ _i_f (x >= LINES && y >= NCOLS) _r_e_t_u_r_n FALSE; _i_f (y < 3 || y >= NLINES - 3) _r_e_t_u_r_n TRUE; _r_e_t_u_r_n (x < 3 || x >= NCOLS - 3); _c_a_s_e 2: _/_* _h_o_l_y _p_a_t_t_e_r_n_! _*_/ _r_e_t_u_r_n ((x + y) & 01); _c_a_s_e 3: _/_* _b_a_r _a_c_r_o_s_s _c_e_n_t_e_r _*_/ _r_e_t_u_r_n (y >= 9 && y <= 15); _} _/_* _N_O_T_R_E_A_C_H_E_D _*_/ _} puton(ch) reg _c_h_a_r ch; _{ reg LOCS _*lp; reg _i_n_t r; reg LOCS _*end; LOCS temp; _A_p_p_e_n_d_i_x _A end = &Layout[Numstars]; _f_o_r (lp = Layout; lp < end; lp++) _{ r = rand() % Numstars; temp = _*lp; _*lp = Layout[r]; Layout[r] = temp; _} _f_o_r (lp = Layout; lp < end; lp++) _{ mvaddch(lp->y, lp->x, ch); refresh(); _} _} PPPPSSSSDDDD::::11119999----2222 SSSSccccrrrreeeeeeeennnn PPPPaaaacccckkkkaaaaggggeeee _CC_oo_nn_tt_ee_nn_tt_ss 1 Overview ............................................ 1 1.1 Terminology .................................... 1 1.2 Compiling Applications ......................... 1 1.3 Screen Updating ................................ 1 1.4 Naming Conventions ............................. 3 2 Variables ........................................... 4 3 Usage ............................................... 5 3.1 Initialization ................................. 5 3.2 Output ......................................... 5 3.3 Input .......................................... 6 3.4 Termination .................................... 6 4 Cursor Movement Optimizations ....................... 6 5 Character Output and Scrolling ...................... 7 6 Terminal State Handling ............................. 7 7 Subwindows .......................................... 8 8 The Functions ....................................... 8 AAAAppppppppeeeennnnddddiiiixxxx AAAA ............................................ 20 1 Examples ............................................ 20 1.1 Simple Character Output ........................ 20 1.2 Twinkle ........................................ 21