1 02/08/88  Introduction to CURSES Examples
  2 
  3 The following is a list of example programs for CURSES and the
  4 corresponding information segments where they can be found.  These
  5 programs are provided to demonstrate uses of CURSES and are for
  6 purposes of illustration only.
  7 
  8 
  9 PROGRAM             INFO SEGMENT
 10 
 11 editor              editor.gi.info
 12 highlight           highlight.gi.info
 13 scatter             scatter.gi.info
 14 show                show.gi.info
 15 termhl              termhl.gi.info
 16 two                 two.gi.info
 17 window              window.gi.info
 18 
 19 
 20 To view a program, type help followed by the information segment
 21 name.  For example, type
 22 
 23           help two.gi.info
 24 
 25 
 26 Show:
 27 
 28 Show pages through a file, showing one screen full each
 29 time the user presses the space bar.  By creating an input file for
 30 show made up of 24 line pages, each segment varying slightly from the
 31 previous page, nearly any exercise for CURSES can be created.  Such
 32 input files are called show scripts.
 33 
 34 In the show program, cbreak is called so that the user can press the
 35 space bar without having to hit return.  The noecho function is called
 36 to prevent the space from echoing in the middle of a refresh,
 37 messing up the screen.  The nonl function is called to enable more
 38 screen optimization.  The idlok function is called to allow insert and
 39 delete line, since many show scripts are constructed to duplicate
 40 bugs caused by that feature.  The clrtoeol and clrtobot functions
 41 clear from the cursor to the end of the line and screen, respectively.
 42 
 43 
 44 Highlight:
 45 
 46 The function addch always draws two things on a window.  In addition
 47 to the character itself, a set of attributes  is associated with
 48 the character.  These attributes cover various forms of highlighting
 49 of the character.  For example, the character can be put in reverse
 50 video, bold, or be underlined.  You can think of the attributes as the
 51 color of the ink used to draw the character.
 52 
 53 A window always has a set of current attributes  associated with it.
 54 The current attributes are associated with each character as it is
 55 written to the window.  The current attributes can be changed with a
 56 call to attrset (attrs).  (Think of this as dipping the window's pen
 57 in a particular color ink.)  The names of the attributes are
 58 A_STANDOUT, A_REVERSE, A_BOLD, A_DIM, A_INVIS, and
 59 
 60 
 61 A_UNDERLINE.  For example, to put a work in bold, the code in Figure
 62 12-2 might be used.  The word "boldface" will be shown in bold.
 63 _____________________________________________________________
 64 
 65 printw("A word in " );
 66 attrset(A_BOLD);
 67 printw("boldface");
 68 attrset(0);
 69 printw(" really stands out.\n");
 70 ...
 71 refresh();
 72 
 73 Figure 12-2 Use of attributes
 74 _____________________________________________________________
 75 
 76 
 77 Not all terminals are capable of displaying all attributes.  If a
 78 particular terminal cannot display a requested attribute, CURSES wil
 79 attempt to find a substitute attribute.  If none is possible, the
 80 attribute is ignored.
 81 
 82 One particular attribute is called standout.   This attribute is used
 83 to make text attract the attention of the user.  The particular
 84 hardware attribute used for standout varies from terminal to terminal,
 85 and is chosen to be the most visually pleasing attribute the terminal
 86 has.  Standout is typically implemented as reverse video or bold. Many
 87 programs don't really need a specific attribute, such as bold or
 88 inverse video, but instead just need to highlight some text.  For such
 89 applications, the A_STANDOUT attribute is recommended.  Two convenient
 90 functions, standout() and standend() turn on and off this attribute.
 91 
 92 
 93 Attributes can be turned on in combination.  Thus, to turn on
 94 blinking bold text, use attrset(A_BLINK|A_BOLD).  Individual
 95 attributes can be turned on and off with attron and attroff without
 96 affecting other attributes.
 97 
 98 For an example program using attributes, see the information segment
 99 highlight.gi.info.  The program takes a text file as input and allows
100 embedded escape sequences to control attributes.  In this example
101 program, \U turns on underlining, \B turns on bold, and \N restores
102 normal text.  Note the initial call to scrollok.  This allows the
103 terminal to scroll if the file is longer than one screen.  When an
104 attempt is made to draw past the bottom of the screen, CURSES will
105 automatically scroll the terminal up a line and call refresh.
106 
107 
108 Highlight comes about as close to being a filter as is possible with
109 CURSES.  It is not a true filter, because CURSES must "take over" the
110 CRT screen.  In order to determine how to update the screen, it must
111 know what is on the screen at all times.  This requires CURSES to
112 clear the screen in the first call to refresh, and to know the cursor
113 position and screen contents at all times.
114 
115 
116 Window:
117 
118 A window is a data structure representing all or part of the CRT
119 screen.  It has room for a two dimensional array of characters,
120 attributes for each character (a total of 16 bits per character: 7 for
121 text and 9 for attributes) a cursor, a set of current attributes, an
122 a number of flags.  CURSES provides a full screen window, called
123 stdscr, and a set of functions that use stdscr.  Another window is
124 provided called curscr, representing the physical screen.
125 
126 It is important to understand that a window is only a data structure.
127 Use of more than one window does not imply use of more than one
128 terminal,  nor does it involve more than one process.  A window is
129 merely an object which can be copied to all or part of the terminal
130 
131 
132 screen.  The current implementation of CURSES does not allow
133 windows which are bigger than the screen
134 
135 The programmer can create additional windows with the function newwin
136 (lines, cols, begin_row, begin_col) which will return a pointer to a
137 newly created window.  The window will be lines by cols, and the
138 upper left corner of the window will be at screen position
139 (begin_row, begin_col).  All operations that affect stdscr have
140 corresponding functions that affect an arbitrary named window.
141 Generally, these functions have names formed by putting a "w" o the
142 front of the stdscr function, and the window name is added as the
143 first parameter.  Thus waddch(mywin, c) would write the character c
144 to window mywin.  The wrefresh(win) function is used to flush the
145 contents of a window to the screen.
146 
147 
148 Windows are useful for maintaining several different screen images,
149 and alternating the user among them.  Also, it is possible to
150 subdivide the screen into several windows, refreshing each of them as
151 desired.  When windows overlap, the contents of the screen will be
152 the more recently refreshed window.
153 
154 In all cases, the non-w version of the function calls the w version
155 of the function, using stdscr as the additional argument.  Thus, a
156 call to addch(c) results in a call to waddch(stdscr, c).
157 
158 The program window is an example of the use of multiple windows.
159 
160 
161 The main display is kept in stdscr.  When the user temporarily wants
162 to put something else on the screen, a new window is created covering
163 part of the screen.  A call to wrefresh on that window causes the
164 window to be written over stdscr on the screen.  Calling refresh on
165 stdscr results in the original window being re-drawn on the screen.
166 Note the calls to touchwin before writing out an overlapping window.
167 These are necessary to defeat an optimization in CURSES.  If you have
168 trouble refreshing a new window which overlaps an old window, it may
169 be necessary to call touchwin on the new window to get it completely
170 written out.
171 
172 
173 For convenience, a set of "move" functions are also provided for most
174 of the common functions.  These result in a call to move before the
175 other function.  For example, mvaddch (row, col, c) is the same as
176 move (row, col); addch (c).  Combinations, e.g.  mvwaddch (row, col,
177 win, c) also exist.
178 
179 
180 Two:
181 
182 CURSES can produce output on more than one terminal at once.  This is
183 useful for single process programs that access a common database,
184 such as multi-player games.  Output to multiple terminals is a
185 difficult business, and CURSES does not solve all the problems for
186 the programmer.  It is the responsibility of the program to determine
187 the file name of each terminal line, and what kind of terminal is on
188 each of those lines.  The standard method, checking $TERM in the
189 environment, does not work, since each process can only examine its
190 own environment.  Another problem that must be solved is that of
191 multiple programs reading from one line.  This situation produces a
192 race condition and should be avoided.  Nonetheless, a program wishing
193 to take over another terminal cannot just shut off whatever program
194 is currently running on that line.  (Usually, security reasons
195 
196 
197 would also make this inappropriate.  However, for some applications,
198 such as an inter-terminal communication program, or a program that
199 takes over unused tty lines, it would be appropriate.) A typical
200 solution requires the user logged in on each line to run a program
201 that notifies the master program that the user is interested in
202 joining the master program, telling it the notification program's
203 process id, the name of the tty line and the type of terminal being
204 used.  Then the program goes to sleep until the master program
205 finishes.  When done, the master program wakes up the notification
206 program, and all programs exit.
207 
208 CURSES handles multiple terminals by always having a current
209 terminal.  All function calls always affect the current terminal.
210 The master program should set up each terminal, saving a reference to
211 the terminals in its own variables.  When it wishes to affect a
212 
213 
214 terminal, it should set the current terminal as desired, and then
215 call ordinary CURSES routines.
216 
217 References to terminals have type struct screen *.  A new terminal is
218 initialized by calling newterm(type, fd).  newterm returns a screen
219 reference to the terminal being set up.  type is a character string,
220 naming the kind of terminal being used.  fd is a stdio file
221 descriptor to be used for input and output to the terminal.  (If only
222 output is needed, the file can be open for output only.) This call
223 replaces the normal call to initscr, which calls newterm
224 (getenv("TERM"), stdout).
225 
226 To change the current terminal, call "set_term(sp)" where sp is the
227 screen reference to be made current.  set_term returns a reference to
228 the previous terminal.
229 
230 
231 It is important to realize that each terminal has its own set of
232 windows and options.  Each terminal must be initialized separately
233 with newterm.  Options such as cbreak and noecho must be set
234 separately for each terminal.  The functions endwin and refresh must
235 be called separately for each terminal.  See Figure 12-3 for a
236 typical scenario to output a message to each terminal.
237 _____________________________________________________________
238 
239 for (i=o; i<interm; i++) {
240           set_term(terms[i]);
241           mvaddstr(0, 0, "Important message");
242           refresh();
243 }
244 
245 Figure 12-3  Sending a message to several terminals
246 -------------------------------------------------------------
247 
248 
249 See the sample program two for a full example.  This program pages
250 through a file, showing one page to the first terminal and the next
251 page to the second terminal.  It then waits for a space to be typed
252 on either terminal, and shows the next page to the terminal typing
253 the space.  Each terminal has to be separately put into nodelay mode.
254 Since no standard multiplexor is available in current versions of the
255 UNIX system, it is necessary to either busy wait, or call sleep(1);,
256 between each check for keyboard input.  This program sleeps for a
257 second between checks.
258 
259 
260 The two program is just a simple example of two terminal CURSES.  It
261 does not handle notification, as described above, instead it requires
262 the name and type of the second terminal on the command line.  As
263 written, the command sleep 100000 must be typed on the second
264 terminal to put it to sleep while the program runs, and the first
265 user must have both read and write permission on the second terminal.
266 
267 
268 Termhl:
269 
270 Some programs need to use lower level primitives than those offered
271 by CURSES.  For such programs, the terminfo level interface is
272 offered.  This interface does not manage your CRT screen, but rather
273 gives you access to strings and capabilities which you can use
274 yourself to manipulate the terminal.
275 
276 Programmers are discouraged from using this level.  Whenever
277 possible, the higher level CURSES routines should be used.  This will
278 make your program more portable to other UNIX systems and to a wider
279 class of terminals.  CURSES takes care of all the glitches and
280 misfeatures present in physical terminals, but at the terminfo level
281 you must deal with them yourself.  Also, it cannot be guaranteed that
282 
283 
284 this part of the interface will not change or be upward compatible
285 with previous releases.
286 
287 There are two circumstances when it is proper to use terminfo.  The
288 first is when you are writing a special purpose tool that sends a
289 special purpose string to the terminal, such as programming a
290 function key, setting tab stops, sending output to a printer port, or
291 dealing with the status line.  The second situation is when writing a
292 filter.  A typical filter does one transformation on the input stream
293 without clearing the screen or addressing the cursor.  If this
294 transformation is terminal dependent and clearing the screen is
295 inappropriate, use of terminfo is indicated.
296 
297 A program writing at the terminfo level uses the framework shown in
298 Figure 12-4.
299 
300 
301 _____________________________________________________________
302 
303 #include <CURSES.h>
304 #include <term.h>
305 ...
306           setupterm(NULL, 1, NULL);
307           ...
308           putp(clear_screen);
309           ...
310           reset_shell_mode();
311           exit(0);
312 
313 Figure 12-4 Terminfo level framework
314 _____________________________________________________________
315 
316 
317 Initialization is done by calling setupterm.  Passing the values
318 NULL, 1, and NULL invoke reasonable defaults.  If setupterm can't
319 figure out what kind of terminal you are on, it will print an error
320 message and exit.  The program should call reset_shell_mode before it
321 exits.
322 
323 Global variables with names like clear_screen and cursor_address are
324 defined by the call to setupterm.  They can be output using putp, or
325 also using tputs, which allows the programmer more control.  These
326 strings should not be directly output to the terminal using printf
327 since they contain padding information.  A program that directly
328 outputs strings will fail on terminals that require padding, or that
329 use the xon/xoff flow control protocol.
330 
331 In the terminfo level, the higher level routines described previously
332 are not available.  It is up to the programmer to output whatever is
333 
334 
335 needed.  For a list of capabilities and a description of what they
336 do, see terminal_information.gi.info.
337 
338 The example program termhl shows simple use of terminfo.  It is a
339 version of highlight that uses terminfo instead of CURSES.  This
340 version can be used as a filter.  The strings to enter bold and
341 underline mode, and to turn off all attributes, are used.
342 
343 This program is more complex than it need be in order to illustrate
344 some properties of terminfo.  The routine vidattr could have been
345 used instead of directly outputting enter_bold_mode,
346 enter_underline_mode, and exit_attribute_mode.  In fact, the program
347 would be more robust if it did since there are several ways to change
348 video attribute modes.  This program was written to illustrate
349 typical use of terminfo.
350 
351 
352 The function tputs(cap, affcnt, outc) applies padding information.
353 Some capabilities contain strings like $<20>, which means to pad for
354 20 milliseconds.  tputs generates enough pad characters to delay for
355 the appropriate time.  The first parameter is the string capability
356 to be output.  The second is the number of lines affected by the
357 capability.  (Some capabilities may require padding that depends on
358 the number of lines affected.  For example, insert_line may have to
359 copy all lines below the current line, and may require time
360 proportional to the number of lines copied.  By convention affcnt is
361 1 if no lines are affected.  The value 1 is used, rather than 0, for
362 safety, since affcnt is multiplied by the amount of time per item,
363 and anything multiplied by 0 is 0.) The third parameter is a routine
364 to be called with each character.
365 
366 
367 For many simple programs, affcnt is always 1 and outc always just
368 calls putchar.  For these programs the routine putp(cap) is a
369 convenient abbreviation.  termhl could be simplified by using putp.
370 
371 Note also the special check for the underline_char capability.  Some
372 terminals, rather than having a code to start underlining and a code
373 to stop underlining, have a code to underline the current character.
374 termhl keeps track of the current mode, and if the current character
375 is supposed to be underlined, will output underline_char if
376 necessary.  Low level details such as this are precisely why the
377 CURSES level recommended over the terminfo level.  CURSES takes care
378 of terminals with different methods of underlining and other CRT
379 functions.  Programs at the terminfo level must handle such details
380 themselves.
381 
382 
383 Editor:
384 
385 For a final example, see the program editor.  This program is a very
386 simple screen editor, patterned after the vi editor.  The program
387 illustrates how to use CURSES to write a screen editor.  This editor
388 keeps the buffer in stdscr to keep the program simple - obviously a
389 real screen editor would keep a separate data structure.  Many
390 simplifications have been made here - no provision is made for files
391 of any length other than the size of the screen, for lines longer
392 than the width of the screen, or for control characters in the file.
393 
394 Several points about this program are worth making.  The routine to
395 write out the file illustrates the use of the mvinch function, which
396 returns the character in a window at a given position.  The data
397 structure used here does not have a provision for keeping track of
398 
399 
400 the number of characters in a line, or the number of lines in a file,
401 so trailing blanks are eliminated when the file is written out.
402 
403 The program uses built-in CURSES functions insch, delch, insertln,
404 and deleteln.  These functions behave much as the similar functions
405 on intelligent terminals behave, inserting and deleting a character
406 or line.
407 
408 The command interpreter accepts not only ASCII characters, but also
409 special keys.  This is important - a good program will accept both.
410 (Some editors are modeless, using non-printing characters for
411 commands.  This is largely a matter of taste - the point being made
412 here is that both arrow keys and ordinary ASCII characters should be
413 handled.) It is important to handle special keys because this makes
414 it easier for a new user to learn to use your program if he can
415 
416 
417 use the arrow keys, instead of having to memorize that "h" means
418 left, "j" means down, "k" means up, and "1" means right.  On the
419 other hand, not all terminals have arrow keys, so your program will
420 be usable on a larger class of terminals if there is an ASCII
421 character which is a synonym for each special key.  Also, experienced
422 users dislike having to move their hands from the "home row" position
423 to use special Keys, since they can work faster with alphabetic keys.
424 
425 Note the call to mvaddstr in the input routine.  addstr is roughly
426 like the C fputs function, which writes out a string of characters.
427 Like fputs, addstr does not add a trailing newline.  It is the same
428 as a series of calls to addch using the characters in the string.
429 mvaddstr is the mv version of addstr, which moves to the given
430 location in the window before writing.
431 
432 
433 The control-R command illustrates a feature most programs using
434 CURSES should add.  Often some program beyond the control of CURSES
435 has written something to the screen, or some line noise has messed up
436 the screen beyond what CURSES can keep track of.  In this case, the
437 user usually types control-L, causing the screen to be cleared and
438 redrawn.  This is done with the call to clearok(curscr), which sets a
439 flag causing the next refresh to first clear the screen.  Then
440 refresh is called to force the redraw.
441 
442 Note also the call to flash(), which flashes the screen if possible,
443 and otherwise rings the bell.  Flashing the screen is intended as a
444 bell replacement, and is particularly useful if the bell bothers
445 someone within earshot of the user.  The routine beep() can be called
446 when a real beep is desired.  (If for some reason the terminal is
447 unable to beep, but can flash, a call to beep will flash the screen.)
448 
449 
450 Another important point is that the input command is terminated by
451 control-D or '.', not escape.  It is very tempting to use escape as a
452 command, since escape is one of the few special keys which is
453 available on every keyboard.  (Return and break are the only others.)
454 However, using escape as a separate key introduces an ambiguity.
455 Most terminals use sequences of characters beginning with escape
456 ("escape sequences") to control the terminal, and have special keys
457 that send escape sequences to the computer.  If the computer sees and
458 escape coming from the terminal, it cannot tell for sure whether the
459 user pushed the escape key, or whether a special key was pressed.
460 CURSES handles the ambiguity by waiting for up to one second.  If
461 another character is received during this second, and if that
462 character might be the beginning of a special key, more input is read
463 (waiting for up to one second for each character) until either a full
464 special key is read, one second passes, or a character is
465 
466 
467 received that could not have been generated by a special key.  While
468 this strategy works most of the time, it is not foolproof.  It is
469 possible for the user to press escape, then to type another key
470 quickly, which causes CURSES to think a special key has been pressed.
471 Also, there is a one second pause until the escape can be passed to
472 the user program, resulting in slower response to the escape key.
473 Many existing programs use escape as a fundamental command, which
474 cannot be changed without infuriating a large class of users.  Such
475 programs cannot make use of special keys without dealing with this
476 ambiguity, and at best must resort to a timeout solution.  The moral
477 is clear: when designing your program, avoid the escape key.
478 
479 
480 
481 
482 
483 
484 
485