X-Git-Url: https://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=misc%2Fhackguide.html;h=417399a68365d12fb3401fe668591ca1adcdfad1;hp=9cd317b96ba3117ea092974ded658c011d949b0b;hb=refs%2Ftags%2Fv5.0;hpb=661078ddbde3ce0f3b06e95642fbb9b5fef7dca1 diff --git a/misc/hackguide.html b/misc/hackguide.html index 9cd317b9..417399a6 100644 --- a/misc/hackguide.html +++ b/misc/hackguide.html @@ -1,13 +1,13 @@ - + A Hacker's Guide to Ncurses Internals - + @@ -26,7 +26,6 @@ this one.
  • How to Design Extensions
  • Portability and Configuration
  • Documentation Conventions

    @@ -65,8 +64,8 @@ package.

    Objective of the Package

    -The objective of the ncurses package is to provide a freeware API for -character-cell terminals and terminal emulators with the following +The objective of the ncurses package is to provide a free software API for +character-cell terminals and terminal emulators with the following characteristics:

    -We use GNU autoconf(1) as a tool to deal with portability issues. +We use GNU autoconf(1) as a tool to deal with portability issues. The right way to leverage an OS-specific feature is to modify the autoconf specification files (configure.in and aclocal.m4) to set up a new feature macro, which you then use to condition your code.

    -

    If autoconf Fails

    - -The 'configure' script usually gets your system environment right -automatically. Here are some -D options you might need to compile -with if it fails:

    -

    -
    -DHAVE_UNISTD_H -
    if <unistd.h> is present -
    -DHAVE_SIGACTION -
    if the sigaction function is present -
    -DHAVE_USLEEP -
    if the usleep function is present -
    -DSVR4_ACTION -
    if (e.g., svr4) you need _POSIX_SOURCE to have sigaction -
    -DHAVE_TERMIOS_H -
    if you have <termios.h> -
    -DHAVE_TERMIO_H -
    if you have <termio.h>; otherwise it uses <sgtty.h> -
    -DBROKEN_TIOCGETWINSZ -
    on SVR4 and HPUX, the get window size ioctl is broken. -
    -

    Documentation Conventions

    There are three kinds of documentation associated with this package. Each @@ -193,7 +170,7 @@ The reason for choosing HTML is that it's (a) well-adapted for on-line browsing through viewers that are everywhere; (b) more easily readable as plain text than most other mark-ups, if you don't have a viewer; and (c) carries enough information that you can generate a nice-looking printed -version from it. Also, of course, it make exporting things like the +version from it. Also, of course, it make exporting things like the announcement document to WWW pretty trivial.

    How to Report Bugs

    @@ -201,7 +178,7 @@ announcement document to WWW pretty trivial.

    The reporting address for bugs is bug-ncurses@gnu.org. This is a majordomo list; to join, write -to ncurses-request@gnu.org with a message containing the line: +to bug-ncurses-request@gnu.org with a message containing the line:

                  subscribe <name>@<host.domain>
     
    @@ -210,7 +187,7 @@ The ncurses code is maintained by a small group of volunteers. While we try our best to fix bugs promptly, we simply don't have a lot of hours to spend on elementary hand-holding. We rely on intelligent cooperation from our users. If you think you have -found a bug in ncurses, there are some steps you can take +found a bug in ncurses, there are some steps you can take before contacting us that will help get the bug fixed quickly.

    In order to use our bug-fixing time efficiently, we put people who @@ -241,7 +218,7 @@ problem reproduces on other terminal types. Usually you'll have both a console type and xterm available; please tell us whether or not your bug reproduces on both.

    -If you have xterm available, it is also good to collect xterm reports for +If you have xterm available, it is also good to collect xterm reports for different window sizes. This is especially true if you normally use an unusual xterm window size -- a surprising number of the bugs we've seen are either triggered or masked by these.

    @@ -332,62 +309,160 @@ Most of the library is superstructure -- fairly trivial convenience interfaces to a small set of basic functions and data structures used to manipulate the virtual screen (in particular, none of this code does any I/O except through calls to more fundamental modules -described below). The files lib_addch.c, -lib_bkgnd.c, lib_box.c, lib_clear.c, -lib_clrbot.c, lib_clreol.c, lib_data.c, -lib_delch.c, lib_delwin.c, lib_erase.c, -lib_getstr.c, lib_inchstr.c, lib_insch.c, -lib_insdel.c, lib_insstr.c, lib_instr.c, -lib_isendwin.c, lib_keyname.c, lib_move.c, -lib_mvwin.c, lib_overlay.c, lib_pad.c, -lib_printw.c, lib_scanw.c, lib_screen.c, -lib_scroll.c, lib_scrreg.c, lib_set_term.c, -lib_slk.c, lib_touch.c, lib_unctrl.c, and -lib_window.c are all in this category. They are very +described below). The files +

    + +lib_addch.c +lib_bkgd.c +lib_box.c +lib_chgat.c +lib_clear.c +lib_clearok.c +lib_clrbot.c +lib_clreol.c +lib_colorset.c +lib_data.c +lib_delch.c +lib_delwin.c +lib_echo.c +lib_erase.c +lib_gen.c +lib_getstr.c +lib_hline.c +lib_immedok.c +lib_inchstr.c +lib_insch.c +lib_insdel.c +lib_insstr.c +lib_instr.c +lib_isendwin.c +lib_keyname.c +lib_leaveok.c +lib_move.c +lib_mvwin.c +lib_overlay.c +lib_pad.c +lib_printw.c +lib_redrawln.c +lib_scanw.c +lib_screen.c +lib_scroll.c +lib_scrollok.c +lib_scrreg.c +lib_set_term.c +lib_slk.c +lib_slkatr_set.c +lib_slkatrof.c +lib_slkatron.c +lib_slkatrset.c +lib_slkattr.c +lib_slkclear.c +lib_slkcolor.c +lib_slkinit.c +lib_slklab.c +lib_slkrefr.c +lib_slkset.c +lib_slktouch.c +lib_touch.c +lib_unctrl.c +lib_vline.c +lib_wattroff.c +lib_wattron.c +lib_window.c + +
    +are all in this category. They are very unlikely to need change, barring bugs or some fundamental reorganization in the underlying data structures.

    -The lib_trace.c, lib_traceatr.c, and -lib_tracechr.c file are used only for debugging support. +These files are used only for debugging support: +

    +lib_trace.c +lib_traceatr.c +lib_tracebits.c +lib_tracechr.c +lib_tracedmp.c +lib_tracemse.c +trace_buf.c +
    It is rather unlikely you will ever need to change these, unless you want to introduce a new debug trace level for some reasoon.

    There is another group of files that do direct I/O via tputs(), computations on the terminal capabilities, or queries to the OS environment, but nevertheless have only fairly low complexity. These -include: lib_acs.c, lib_beep.c, -lib_color.c, lib_endwin.c, lib_initscr.c, -lib_longname.c, lib_newterm.c, -lib_options.c, lib_termcap.c, lib_ti.c, -lib_tparm.c, lib_tputs.c, lib_vidattr.c, -and read_entry.c. These are likely to need revision only if +include: +

    +lib_acs.c +lib_beep.c +lib_color.c +lib_endwin.c +lib_initscr.c +lib_longname.c +lib_newterm.c +lib_options.c +lib_termcap.c +lib_ti.c +lib_tparm.c +lib_tputs.c +lib_vidattr.c +read_entry.c. +
    +They are likely to need revision only if ncurses is being ported to an environment without an underlying terminfo capability representation.

    -The files lib_kernel.c, lib_baudrate.c, lib_raw.c, -lib_tstp.c, and lib_twait.c have serious hooks into -the tty driver and signal facilities. If you run into porting snafus +These files +have serious hooks into +the tty driver and signal facilities: +

    +lib_kernel.c +lib_baudrate.c +lib_raw.c +lib_tstp.c +lib_twait.c +
    +If you run into porting snafus moving the package to another UNIX, the problem is likely to be in one -of these files. The file lib_print.c uses sleep(2) and also +of these files. +The file lib_print.c uses sleep(2) and also falls in this category.

    -Almost all of the real work is done in the files -hashmap.c, hardscroll.c, -lib_addch.c, lib_doupdate.c, lib_mvcur.c, -lib_getch.c, lib_mouse.c, lib_refresh.c, -and lib_setup.c. Most of the algorithmic complexity in the -library lives in these files. If there is a real bug in ncurses -itself, it's probably here. We'll tour some of these files in detail +Almost all of the real work is done in the files +

    +hardscroll.c +hashmap.c +lib_addch.c +lib_doupdate.c +lib_getch.c +lib_mouse.c +lib_mvcur.c +lib_refresh.c +lib_setup.c +lib_vidattr.c +
    +Most of the algorithmic complexity in the +library lives in these files. +If there is a real bug in ncurses itself, it's probably here. +We'll tour some of these files in detail below (see The Engine Room).

    Finally, there is a group of files that is actually most of the terminfo compiler. The reason this code lives in the ncurses library is to support fallback to /etc/termcap. These files include -alloc_entry.c, captoinfo.c, comp_captab.c, -comp_error.c, comp_hash.c, comp_parse.c, -comp_scan.c, and parse_entry.c, -read_termcap.c, and write_entry.c. We'll discuss these -in the compiler tour.

    +

    +alloc_entry.c +captoinfo.c +comp_captab.c +comp_error.c +comp_hash.c +comp_parse.c +comp_scan.c +parse_entry.c +read_termcap.c +write_entry.c +
    +We'll discuss these in the compiler tour.

    The Engine Room

    @@ -456,11 +531,11 @@ events) into a gesture (a high-level or composite event).

    Output and Screen Updating

    With the single exception of character echoes during a wgetnstr() -call (which simulates cooked-mode line editing in an ncurses window), +call (which simulates cooked-mode line editing in an ncurses window), the library normally does all its output at refresh time.

    The main job is to go from the current state of the screen (as represented -in the curscr window structure) to the desired new state (as +in the curscr window structure) to the desired new state (as represented in the newscr window structure), while doing as little I/O as possible.

    @@ -483,7 +558,7 @@ insertion, and deletion operations to make the indices match. It calls Then lib_doupdate.c goes to work. Its job is to do line-by-line transformations of curscr lines to newscr lines. Its main tool is the routine mvcur() in lib_mvcur.c. This routine -does cursor-movement optimization, attempting to get from given screen +does cursor-movement optimization, attempting to get from given screen location A to given location B in the fewest output characters posible.

    If you want to work on screen optimizations, you should use the fact @@ -538,8 +613,8 @@ and controls interpretation of the value.

    One possibly interesting aspect of the implementation is the way the compiler tables are initialized. All the tables are generated by various -awk/sed/sh scripts from a master table include/Caps; these -scripts actually write C initializers which are linked to the compiler. +awk/sed/sh scripts from a master table include/Caps; these +scripts actually write C initializers which are linked to the compiler. Furthermore, the hash table is generated in the same way, so it doesn't have to be generated at compiler startup time (another benefit of this organization is that the hash table can be in shareable text space).

    @@ -553,7 +628,7 @@ Translation.

    The background problem that makes tic tricky isn't the capability translation itself, it's the resolution of use capabilities. Older -versions would not handle forward use references for this reason +versions would not handle forward use references for this reason (that is, a using terminal always had to follow its use target in the source file). By doing this, they got away with a simple implementation tactic; compile everything as it blows by, then resolve uses from compiled @@ -564,7 +639,7 @@ compilation process has to be embeddable in the ncurses library so that it can be called by the startup code to translate termcap entries on the fly. The embedded version can't go promiscuously writing everything it translates out to disk -- for one thing, it will typically -be running with non-root permissions.

    +be running with non-root permissions.

    So our tic is designed to parse an entire terminfo file into a doubly-linked circular list of entry structures in-core, and then do @@ -614,7 +689,7 @@ format.

    The include/Caps file has a header comment describing ways you can specify source translations for nonstandard capabilities just by -altering the master table. It's possible to set up capability aliasing +altering the master table. It's possible to set up capability aliasing or tell the compiler to plain ignore a given capability without writing any C code at all.

    @@ -633,7 +708,7 @@ function passed in to dump_entry() to control which capabilities are dumped. This is necessary in order to handle both the ordinary De-compilation case and entry difference reporting.

    -The tput and clear utilities just do an entry load +The tput and clear utilities just do an entry load followed by a tputs() of a selected capability.

    Style Tips for Developers

    @@ -678,7 +753,7 @@ call any other UNIX routines such as signal(2) or the stdio library. Thus, they should not need to be modified for single-terminal ports.

    - +

    lib_addch.c lib_addstr.c lib_bkgd.c @@ -710,28 +785,28 @@ lib_tparm.c lib_tputs.c lib_unctrl.c lib_window.c -panel.c - +panel.c +

    This module is pure curses, but calls outstr():

    - +

    lib_getstr.c - +

    These modules are pure curses, except that they use tputs() and putp():

    - +

    lib_beep.c -lib_endwin.c lib_color.c +lib_endwin.c lib_options.c lib_slk.c lib_vidattr.c - +

    This modules assist in POSIX emulation on non-POSIX systems:

    @@ -743,7 +818,8 @@ This modules assist in POSIX emulation on non-POSIX systems:

    The following source files will not be needed for a single-terminal-type port.

    - +

    +alloc_entry.c captoinfo.c clear.c comp_captab.c @@ -752,24 +828,23 @@ comp_hash.c comp_main.c comp_parse.c comp_scan.c -alloc_entry.c dump_entry.c +infocmp.c parse_entry.c read_entry.c -write_entry.c -infocmp.c tput.c - +write_entry.c +

    The following modules will use open()/read()/write()/close()/lseek() on files, but no other OS calls.

    -
    lib_screen.c -
    used to read/write screen dumps -
    lib_trace.c -
    used to write trace data to the logfile +
    lib_screen.c +
    used to read/write screen dumps +
    lib_trace.c +
    used to write trace data to the logfile
    Modules that would have to be modified for a port start here:

    @@ -777,76 +852,29 @@ Modules that would have to be modified for a port start here:

    The following modules are `pure curses' but contain assumptions inappropriate for a memory-mapped port.

    -

    -lib_longname.c	-- assumes there may be multiple terminals
    -	longname()		-- return long name of terminal
    -lib_acs.c	-- assumes acs_map as a double indirection
    -	init_acs()		-- initialize acs map
    -lib_mvcur.c	-- assumes cursor moves have variable cost
    -	mvcur_init()		-- initialize
    -	mvcur()			-- do physical cursor move
    -	mvcur_wrap()		-- wrap
    -	scrolln()		-- do physical scrolling
    -lib_termcap.c	-- assumes there may be multiple terminals
    -	tgetent()		-- load entry
    -	tgetflag()		-- get boolean capability
    -	tgetnum()		-- get numeric capability
    -	tgetstr()		-- get string capability
    -lib_ti.c	-- assumes there may be multiple terminals
    -	tigetent()		-- load entry
    -	tigetflag()		-- get boolean capability
    -	tigetnum()		-- get numeric capability
    -	tigetstr()		-- get string capability
    +
    +
    lib_longname.c
    assumes there may be multiple terminals +
    lib_acs.c
    assumes acs_map as a double indirection +
    lib_mvcur.c
    assumes cursor moves have variable cost +
    lib_termcap.c
    assumes there may be multiple terminals +
    lib_ti.c
    assumes there may be multiple terminals +
    The following modules use UNIX-specific calls: -lib_doupdate.c -- input checking - doupdate() -- repaint real screen to match virtual - _nc_outch() -- put out a single character -lib_getch.c -- read() - wgetch() -- get single character - wungetch() -- push back single character -lib_initscr.c -- getenv() - initscr() -- initialize curses functions -lib_newterm.c - newterm() -- set up new terminal screen -lib_baudrate.c - baudrate() -- return the baudrate -lib_kernel.c -- various tty-manipulation and system calls - reset_prog_mode() -- reset ccurses-raw mode - reset_shell_mode() -- reset cooked mode - erasechar() -- return the erase char - killchar() -- return the kill character - flushinp() -- flush pending input - savetty() -- save tty state - resetty() -- reset tty to state at last savetty() -lib_raw.c -- various tty-manipulation calls - raw() - echo() - nl() - qiflush() - cbreak() - noraw() - noecho() - nonl() - noqiflush() - nocbreak() -lib_setup.c -- various tty-manipulation calls - use_env() - setupterm() -lib_restart.c -- various tty-manipulation calls - def_shell_mode() - def_prog_mode() - set_curterm() - del_curterm() -lib_tstp.c -- signal-manipulation calls - _nc_signal_handler() -- enable/disable window-mode signal catching -lib_twait.c -- gettimeofday(), select(). - usleep() -- microsecond sleep - _nc_timed_wait() -- timed wait for input -
    - -The package kernel could be made smaller.

    +

    +
    lib_doupdate.c
    input checking +
    lib_getch.c
    read() +
    lib_initscr.c
    getenv() +
    lib_newterm.c +
    lib_baudrate.c +
    lib_kernel.c
    various tty-manipulation and system calls +
    lib_raw.c
    various tty-manipulation calls +
    lib_setup.c
    various tty-manipulation calls +
    lib_restart.c
    various tty-manipulation calls +
    lib_tstp.c
    signal-manipulation calls +
    lib_twait.c
    gettimeofday(), select(). +

    Eric S. Raymond <esr@snark.thyrsus.com>