Import dialog-1.2-20121230.
authorPeter Avalos <pavalos@dragonflybsd.org>
Sun, 10 Feb 2013 12:24:43 +0000 (04:24 -0800)
committerPeter Avalos <pavalos@dragonflybsd.org>
Thu, 14 Feb 2013 19:30:50 +0000 (11:30 -0800)
45 files changed:
contrib/dialog/CHANGES [new file with mode: 0644]
contrib/dialog/COPYING [new file with mode: 0644]
contrib/dialog/README [new file with mode: 0644]
contrib/dialog/VERSION [new file with mode: 0644]
contrib/dialog/argv.c [new file with mode: 0644]
contrib/dialog/arrows.c [new file with mode: 0644]
contrib/dialog/buildlist.c [new file with mode: 0644]
contrib/dialog/buttons.c [new file with mode: 0644]
contrib/dialog/calendar.c [new file with mode: 0644]
contrib/dialog/checklist.c [new file with mode: 0644]
contrib/dialog/columns.c [new file with mode: 0644]
contrib/dialog/dialog.1 [new file with mode: 0644]
contrib/dialog/dialog.3 [new file with mode: 0644]
contrib/dialog/dialog.c [new file with mode: 0644]
contrib/dialog/dialog.h [new file with mode: 0644]
contrib/dialog/dlg_colors.h [new file with mode: 0644]
contrib/dialog/dlg_keys.c [new file with mode: 0644]
contrib/dialog/dlg_keys.h [new file with mode: 0644]
contrib/dialog/editbox.c [new file with mode: 0644]
contrib/dialog/formbox.c [new file with mode: 0644]
contrib/dialog/fselect.c [new file with mode: 0644]
contrib/dialog/guage.c [new file with mode: 0644]
contrib/dialog/help.c [new file with mode: 0644]
contrib/dialog/inputbox.c [new file with mode: 0644]
contrib/dialog/inputstr.c [new file with mode: 0644]
contrib/dialog/menubox.c [new file with mode: 0644]
contrib/dialog/mixedform.c [new file with mode: 0644]
contrib/dialog/mixedgauge.c [new file with mode: 0644]
contrib/dialog/mouse.c [new file with mode: 0644]
contrib/dialog/mousewget.c [new file with mode: 0644]
contrib/dialog/msgbox.c [new file with mode: 0644]
contrib/dialog/pause.c [new file with mode: 0644]
contrib/dialog/prgbox.c [new file with mode: 0644]
contrib/dialog/progressbox.c [new file with mode: 0644]
contrib/dialog/rangebox.c [new file with mode: 0644]
contrib/dialog/rc.c [new file with mode: 0644]
contrib/dialog/tailbox.c [new file with mode: 0644]
contrib/dialog/textbox.c [new file with mode: 0644]
contrib/dialog/timebox.c [new file with mode: 0644]
contrib/dialog/trace.c [new file with mode: 0644]
contrib/dialog/treeview.c [new file with mode: 0644]
contrib/dialog/ui_getc.c [new file with mode: 0644]
contrib/dialog/util.c [new file with mode: 0644]
contrib/dialog/version.c [new file with mode: 0644]
contrib/dialog/yesno.c [new file with mode: 0644]

diff --git a/contrib/dialog/CHANGES b/contrib/dialog/CHANGES
new file mode 100644 (file)
index 0000000..1d4b619
--- /dev/null
@@ -0,0 +1,1884 @@
+-- $Id: CHANGES,v 1.451 2012/12/30 15:43:24 tom Exp $
+-- Thomas E. Dickey <dickey@invisible-island.net>
+
+This version of dialog was originally from a Debian snapshot.  I've done this
+to it:
+
+2012/12/30 - release 1.2
+       + improve some older changelog entries to help with HTML'izing content.
+       + various fixes/improvments for scrollbar appearance.
+       + add mappings for some equivalent options provided by whiptail;
+         add configure option --disable-whiptail to allow suppressing these.
+       + add configure option --disable-Xdialog2 to allow suppressing the
+         newer features, i.e., for cdialog 1.2
+       + add --no-items option, for consistency.
+       + add --no-tags option, like Xdialog.
+       + add buildlist, rangebox and treeview dialogs, like Xdialog.
+       + remove obsolete workaround for ncurses 4.2 scrolling in checklist
+         and menubox.
+       + improve dialog_helpfile() by preventing it from showing extra buttons
+         (suggested by xDog Walker).
+       + correct logic in formbox's scroll_next() function (report by xDog
+         Walker).
+       + fix a case with inputbox widget where preset input text is not shown
+         until moving the cursor within the text (report by xDog Walker).
+       + handle SIGCHLD in dialog_prgbox() to eliminate defunct processes
+         (report by xDog Walker).
+       + improve the way "hotkeys" are assigned to widget buttons by checking
+         if a given key has already been used in the row of buttons (Debian
+         #684933).
+       + amend fix for --trace parsing from 2012/07/03, which sometimes
+         skipped a parameter (report by xDog Walker).
+       + drop copismall and install files from samples, which were essentially
+         nonfunctional.
+       + correct secondary border colors in samples/slackware.rc and
+         samples/whiptail.rc
+       + update gl.po, add ia.po from
+               http://translationproject.org/latest/dialog/
+       + fix various issues reported by coverity scan.
+       + miscellaneous configure script fixes/updates:
+         + require autoconf 2.52+patches
+         + support --datarootdir option
+         + check for clang compiler
+         + check for tinfo library when looking for ncurses
+         + add 3rd parameter to AC_DEFINE for autoheader
+         + remove unused macros from aclocal.m4
+       + update config.guess, config.sub
+
+2012/07/06
+       + modify samples/setup-tempfile to work with Tru64's shell.
+       + modify inputmenu sample scripts to make them more portable:
+         + use "id" rather than "$GROUPS", use sed to work with Solaris.
+         + use sed to split-up the rename results to work with HPUX.
+       + fix regression in msgbox (ArchLinux #30574)
+
+2012/07/03
+       + modify prgbox widget to work with --extra-button, etc.
+       + add case values to several widgets to allow for mouse-clicks with
+       "--extra-button" and "--help-button" additions.
+       + correct timebox widget's exit code for "--extra-button" when handing
+         the "enter" key.
+       + modify msgbox widget to honor "--extra-button".
+       + corrected processing of "--trace" option, which did not update the
+         index into command-line to point past its value.
+       + add a check in dialog program for valid characters used in option,
+         e.g., to generate an error if a script attempts to add option value
+         using "=" rather than with whitespace.
+       + add new command-line option --default-button and library function
+         dlg_default_button() to retrieve the value set by the option
+         to provide a way to set the default button directly rather than
+         by combining --nook, etc. (patch by Zoltan Kelemen).
+       + amend include of unctrl.h to apply only to the case where curses.h
+         is included, to avoid conflict of ncurses' unctrl.h with a system
+         implementation (report by Martin Roedlach)
+       + add limit-check to dlg_toupper() in non-wide curses mode to work
+         when non-character values such as arrow-key codes are passed to
+         it (patch by Zoltan Kelemen).
+       + override timeout value, e.g., as set via --timeout command-line
+         option in pause widget because that interferes with pause's behavior
+         (report by Jan Spitalnik).
+       + modify samples/inputmenu* to allow ":" in renamed text (report by
+         Andreas Stoewing).
+       + modify double-quoting to make it more consistent, i.e., checklist
+         output is quoted only when needed.  This fixes the case where
+         single-quotes were used whether or not needed, but also modifies
+         older checklist behavior for double-quoting which always added those
+         (Debian #663664).
+       + correct exit-code used in inputmenu for "rename" button (Debian
+         #673041, forwarded from Ubuntu #333909, patch by Lebedev Vadim).
+       + update el.po and hr.po from
+               http://translationproject.org/latest/dialog/
+       + use checkbashisms to clean up sample scripts.
+
+2012/02/15
+       + modify menubox.c to use the same improvement as in checklist.c
+       + improve auto width computation for checklist widget by using
+         dlg_calc_list_width as in the non-auto case (Edho Arief).
+       + eliminate some bashisms in the sample scripts (Pedro Giffuni).
+       + makefile fixes from FreeBSD ports (Li-Wen Hsu):
+         + make --with-package option of configure script work.
+         + get LIBTOOL_VERSION from configure script, needed by
+           ${LIBTOOL_VERSION} in LIBTOOL_CREATE (LIB_CREATE in configure and
+           aclocal.m4)
+       + update cs.po and sr.po from
+               http://translationproject.org/latest/dialog/
+       + updated configure script macros, improving CF_XOPEN_SOURCE among
+         other fixes.
+
+2011/10/20
+       + fix --analyze warnings for clang versions 2.8, 2.9.
+       + add configure check for lint program.
+       + add check in dlg_getc() in case its window is freed as a side effect
+         of removing callbacks.
+       + fix logic in freeing subwindows (report by xDog Walker).
+       + fix a regression in logic distinguishing between inputmenu and menu
+         widgets (report by xDog Walker).
+       + minor fixes to library manpage.
+
+2011/10/18
+       + modify header-sh.in to work around limit on sed script length on
+         HPUX.
+       + add a special case of parameter parsing for "--trace" to the
+         initialization done before calling init_dialog(), to allow users to
+         capture the initial state of the parameter list before any options
+         are processed and removed.  This is only done if "--trace" is the
+         first option, otherwise it is handled in the common options as before
+         (report by xDog Walker).
+       + modify samples/testdata-8bit, discarding $1 from the parameter list
+         if it was used, so that the source'ing scripts can consistently use
+         "$@" to insert parameters before the widget, e.g., as an alternative
+         to using $DIALOGOPTS (report by xDog Walker).
+       + modify treatment of function pointers in menubox.c, make
+         dlg_renamed_menutext() and dlg_dummy_menutext() visible to library
+         users (request by xDog Walker).
+       + add dlg_count_real_columns(), use to modify centering for "--hline"
+         text to account for "\Z"s (report by xDog Walker).
+       + improve check in dlg_draw_arrows2() for conflict between the window
+         title and up-arrow marker to take into account that the given window
+         may not be the top-level window of the widget.
+       + change width of page up/down mouse areas in fselect panes to use the
+         full width of the panes rather than only the portion from the left
+         margin to the up/down arrow.
+       + add/use dlg_draw_box2() and dlg_draw_bottom_box2() to use the
+         secondary borders.
+       + modify rc-file read/write to accept/generate color values that refer
+         to previously-processed items in the color table.  This reduces the
+         number of distinct colors that must be specified to set up a color
+         scheme.
+       + add color table entries for secondary borders, i.e., the ones that
+         are normally drawn with the dialog's text-colors (Debian #641168).
+       + modify fselect.c to scan the current directory if the input field
+         happens to be empty (Debian #640905).
+       + repeated the discussion of environment variables that can override
+         the exit-status values in the manpage's return-codes section
+         (Debian #642105).
+       + add an example to the manpage showing how to override the form
+         widget's keys used for field/button traversal (Debian #642108).
+       + modify call to dlg_register_window() in formbox.c so that the editing
+         bindings are attached to the form sub-window rather than the
+         top-level dialog window.  Also change the name by which the editing
+         bindings are bound for editbox.c, fselect.c and inputbox.c, so that
+         the editing and navigation bindings can be different.
+       + correct logic in dlg_lookup_key() so that it matches the widget name
+         before using a binding from .dialogrc, allowing the inner/outer
+         windows of form and other editing widgets to have different bindings.
+       + modify dlg_register_window() to call dlg_dump_window_keys() after
+         its updates, via the --trace output, to supplement the manpage
+         description of key bindings (Debian #642108).
+       + add DLGK_FORM_PREV and DLGK_FORM_NEXT key-bindings to form.c, to
+         allow binding a single key to traverse both form-fields and buttons
+         (Debian #642108).
+       + modify dlg_parse_rc() to check for error return from
+         dlg_parse_bindkey().
+       + add function dlg_dump_window_keys(), to help with debugging widgets.
+       + add CR, LF, TAB, FF and ESC to table of curses names to help make
+         key bindings more readable.
+       + update table of dialog key-names so that helpfile and trace are
+         dumped properly.
+       + correct dlg_dump_keys(), which was showing only the first item in
+         the matched binding table.
+       + save/restore window current position in dlg_update_mixedgauge().
+       + pass return-code from pause_for_ok() from dlg_progressbox() when
+         pauseopt is set, rather than only DLG_OK.
+       + call setlocale() in init_dialog() rather than relying on on-demand
+         use within inputstr.c, since there are paths in textbox widget which
+         do not exercise the latter (report by xDog Walker).
+       + fix some places where checks for "\Z" were done without also checking
+         dialog_vars.colors (report by Moray Henderson).
+       + correct logic for DIALOGOPTS parsing so that the parse happens only
+         once unless memory leak checking is enabled (report by xDog Walker).
+       + remove an incorrect free() call in dlg_free_gauge() (report by xDog
+         Walker).
+       + modify dlg_trace_win() to log wide-characters (report by xDog Walker).
+       + make traces shorter by skipping repeated ERR's, but showing the
+         number skipped (report by xDog Walker).
+       + improve description in manpage to distinguish program box and
+         progress box from tailboxes (adapted from email by xDog Walker).
+       + modify dlg_trace_win() so that it looks for the topmost window in a
+         dialog.  Because subwindows share space with the top window, tracing
+         the latter shows the whole widget (report by xDog Walker).
+       + expand tracing so that each window is traced before soliciting input,
+         making the ^T feature to print a window on demand partly redundant
+         (suggested by xDog Walker).
+       + cosmetic change in dialog.h to avoid "*/*" strings from comments next
+         to "*" (report by xDog Walker).
+       + ensure result from dlg_align_columns() has trailing null on each
+         string.  Analysis was hindered by libc6's continuance of libc5's
+         early-1990s misfeature of clearing the result from malloc, noting
+         that libc6's documentation incorrectly claims that it does not do
+         this (report by xDog Walker).
+
+2011/07/07
+       + modify util.c to work better with old versions of ncurses:
+         + suppress use of wchgat() before fix in 20060715 which is needed
+           for simple shadow manipulation used here in 2011/06/30 (report
+           by xDog Walker).
+         + add a null-pointer check in dlg_print_scrolled()
+       + fix a regression in dlg_getc() introduced by changes to intercept
+         F1 for help-popup (report by xDog Walker).
+
+2011/06/30
+       + correct license statement for prgbox.c (Debian #632198).
+       + correct layout when "--colors" is used, by discounting characters in
+         the escape sequences from the column counts (report by xDog Walker).
+       + modify dlg_checklist() so that only one item in the list can
+         initially be selected (report by xDog Walker).
+       + add/use macro dlg_enter_buttoncode() to improve implementation of
+         "--nook" option (report by xDog Walker).
+       + add option "--no-nl-expand" to suppress the conversion of "\n"
+         strings into newlines (request by xDog Walker).
+       + modify LIB_CREATE symbol in makefile.in to include the library
+         dependencies such as ncurses.  This is needed when dynamically
+         loading the library (report/analysis by xDog Walker).
+       + modify dlg_exit_label() to suppress the Cancel button, for
+         consistency.
+       + modify dlg_exit_label() to honor the --nook option, except when there
+         is no other button, e.g., the help-button.
+       + modify dlg_exit_buttoncode() so that it returns the proper code for
+         help-button (report by xDog Walker).
+       + correct loop limit when processing "--column-separator" (report by
+         xDog Walker).
+       + modify handling of "--version" and "--help" to ensure that they are
+         processed, and exit before widgets.  Separate "--print-version"
+         from "--version", allowing its output to be interspersed with
+         widget output (report by xDog Walker).
+       + correct a few places where "--version" or "--help" options went
+         always to stdout rather than allowing redirection with the "--stderr"
+         option (report by xDog Walker).
+       + improve repainting after erasing a widget and its shadow.
+       + add "--hline" and "--hfile" options for compatibility with FreeBSD
+         dialog (request by Devin Teske).
+       + add dialog version message when opening a trace file (request by
+         xDog Walker).
+       + show filename of rc-file in traces.
+       + add piped-in data for gauge widget to traces.
+       + add entrypoints to gauge widget, for allocating, updating and freeing
+         the widget (adapted from patch by Stephen Hurd).
+       + fix a reference to freed memory in the gauge widget.
+       + fix --no-mouse option by actually closing the mouse (report by
+         xDog Walker).
+       + add sk.po from
+               http://translationproject.org/latest/dialog/
+       + limit Solaris xpg4 portability fix for redefinition of ERR to cover
+         the specific value found in <sys/regset.h>, in case an application
+         includes dialog.h after curses.h (FreeBSD #156601, report by Jaakko
+         Heinonen, Stephen Hurd).
+       + updated configure macros:
+         + CF_CURSES_CPPFLAGS,
+         + CF_CURSES_LIBS, make checks for special libraries on hpux10 and
+           sunos4 optional
+         + CF_CURSES_FUNCS, workaround for bug in gcc 4.2.1 (FreeBSD 8.1)
+           which caused part of test program to be omitted, i.e., when it saw
+           two return-statements in a row it omitted the _first_ one.  Also
+           add expression to pointer check to help FreeBSD's linker decide it
+           should be validated.  Just an assignment was not enough.  Also, add
+           check for unctrl.h
+         + CF_CURSES_HEADER, change order for curses.h / ncurses.h pairs to
+           put ncurses.h first, which will tend to provide the same #define's
+           as in CF_NCURSES_HEADER (report by Dennis Preiser).
+         + CF_CURSES_TERM_H, modify to avoid spurious check for
+           <curses.hterm.h> if there is no ncurses version.  Look for
+           ncurses's term.h anyway, to work around breakage by packagers who
+           separate ncurses' header files.
+         + CF_DISABLE_RPATH_HACK, fix garbled message
+         + CF_LD_RPATH_OPT, add mirbsd
+         + CF_MAKEFLAGS, filter out GNU make's entering/leaving messages. 
+           This only appeared when using the macro in a dpkg script, though it
+           should have in other cases.
+         + CF_RPATH_HACK, add a check for libraries not found, e.g., from
+           suppressed functionality of gcc in linking from /usr/local/lib, and
+           add a -L option to help work around this.
+         + CF_XOPEN_SOURCE, workaround for cygwin to get ncurses' configure
+           script to define _XOPEN_SOURCE_EXTENDED (cygwin's features.h
+           doesn't do anything, so it needs a crutch).
+       + update config.guess, config.sub
+
+2011/03/02
+       + add --prgbox and --programbox (adapted from patch by David Boyd).
+       + add sl.po from
+               http://translationproject.org/latest/dialog/
+       + fix timeouts from 2011/01/18, which were being interpreted as
+         milliseconds rather than seconds (report by Luis Moreira).
+
+2011/01/18
+       + fix inconsistency in return-codes for textbox when help-button is
+         used by making dlg_exit_buttoncode() a wrapper for
+         dlg_ok_buttoncode().
+       + modify pause widget to use dlg_ok_buttoncode(), so help-button works.
+       + correct two infobox sample scripts, which did not pass extra
+         command-line parameters due to quoting problems.
+       + add a limit-check to the timebox widget (patch by Garrett Cooper).
+       + modify --trace option to also trace the command-line parameters.
+       + account for combining characters when wrapping text (Debian #570634).
+       + correct handling of SIGWINCH in gauge widget (Debian #305705).
+       + add gauge_color, to make guage's progress-bar distinct from
+         title_color (request by Dominic Derdau).
+       + update fi.po from
+               http://translationproject.org/latest/dialog/
+         as well as resync line-numbers in the other po-files.
+       + modify configure script and dialog program to build with NetBSD's
+         wide-character curses functions, including workarounds for its
+         incorrect WACS_xxx definitions.  Some of the UTF-8 examples work.
+       + add back-tab for traversal of tailboxbg widgets, for symmetry with
+         tab-traversal.
+       + reduce flicker in tailboxbg by checking if the input file size has
+         changed.
+       + modify internals of callbacks to avoid blocking reads of their
+         associated files by keyboard input.
+       + add command-line option --no-mouse, to suppress use of mouse.
+       + add configure option --enable-header-subdir to allow the header files
+         to be installed into a subdirectory named for the package.
+       + modify dlg_restore_vars() to retain the updated values of
+         input_result and input_length, eliminating the need for a caller to
+         provide their own user buffer (prompted by report by Thiago Bimbatti
+         Felicio).
+       + add a null-pointer check in show_result() for
+         dialog_vars.input_result, and ensure it is set to null after freeing
+         (prompted by report by Thiago Bimbatti Felicio).
+       + change order of -I options in CPPFLAGS (report by Michel Feldheim)
+       + modify pause-widget so that it no longer exits when an unrecognized
+         key is pressed (patch by Creidieki M Crouch).
+       + add --with-package option to configure script to allow renaming
+         of the dialog program and library, to support the package scripts.
+       + add Debian and RPM package scripts for test-builds.
+       + several improvements to configure script:
+         + quote params of ifelse()
+         + change obsolete ${name-value} to standard ${name:-value}
+         + use new macros CF_ADD_LIB/CF_ADD_LIBS to enforce consistency.
+         + AM_GNU_GETTEXT, drop $MKINSTALLDIRS, use "mkdir -p" consistently.
+         + CF_ADD_SUBDIR_PATH, workaround - if $prefix was not mkdir'd yet, no
+           directories were added.
+         + CF_BUNDLED_INTL, add --with-textdomain option, to use with lynx-dev
+           package
+         + CF_FIND_LINKAGE, simplify save/restore of $LIBS
+         + CF_GCC_WARNINGS, fix for Mac OS X (compiler makes conftest.dSYM
+           directory)
+         + CF_HEADER_PATH, don't search for variations of everything in the
+           current include-path
+         + CF_WITH_CURSES_DIR, move the calls to CF_ADD_INCDIR and
+           CF_ADD_LIBDIR for the curses-directory here, from
+           CF_NCURSES_CPPFLAGS and CF_NCURSES_LDFLAGS, so it will work even
+           with the default checking, e.g., no --with-ncurses, etc.
+       + update config.guess, config.sub
+
+2010/04/28
+       + several improvements to configure script:
+         + modify CF_CURSES_TERM_H to handle cases such as cygwin where
+           packager has installed curses.h and term.h in different
+           directories, e.g., to wedge in a termcap library.
+         + modify CF_XOPEN_SOURCE, adding special case for OpenSolaris
+         + modify CF_MAKE_TAGS to add check for exctags and exetags, prefer to
+           ctags and etags to work around pkgsrc (NetBSD) renaming.
+         + correct CF_FIND_LINKAGE, setting cache variable for library_file in
+           the special case where no directory search is made.
+         + improve CF_GCC_VERSION, suppress stderr for c89 alias of gcc.
+         + improve CF_GCC_WARNINGS, moving -W and -Wall into the list to
+           check, since c89 alias for gcc complains about these options.
+         + modify CF_HEADER_PATH, to not search for variations of everything
+           in the current include-path
+         + use "mkdir -p", remove mkdirs.sh
+         + use CF_CURSES_HEADER to fill in possible subdirectory used for
+           ncurses header filename.
+         + modify CF_XOPEN_CURSES to work around current ncurse header loss of
+           predefinition of _XOPEN_SOURCE_EXTENDED
+         + add "--disable-rpath-hack" option, along with scripting to add
+           rpath option to libraries found in unusual places.
+       + modify pause widget to autosize like gauge, and to omit the area for
+         buttons when none are displayed.
+       + fix an infinite loop in dlg_button_layout() if there are no buttons
+         to display (Debian #579390).
+       + add makefile rules for generating html, etc., documentation from
+         nroff.
+       > patches by Samuel Martín Moro
+       + reset errors in tailbox before reading new character.
+       + modify dlg_draw_scrollbar(), omitting hiding percentages in boxes
+         when no arrows or scrollbar are needed.
+       + correct value of row for scrollbars in formbox.
+       + update es.po from
+               http://translationproject.org/latest/dialog/
+
+2010/01/19
+       + split up binding tables in inputbox and similar widgets to avoid
+         conflict between cursor-key use for input-string versus navigation
+         (report by slakmagik).
+       + if strftime() is available, support --time-format option for timebox
+         widget.
+       + if strftime() is available, support --date-format option for calendar
+         widget (request by Walter Harms).
+       + build-fixes for linking to intl library in /usr/local
+       + add --scrollbar option, use in most widgets to show a scrollbar on
+         the right margin of the data.  That is cosmetic, does not respond to
+         the mouse.
+       + reuse functions from msgbox to allow prompt for yesno box to be
+         scrolled in a too-small window.
+       + correct mapping of button-codes with --nook option (report by Lebedev
+         Vadim).
+       + cleanup sample scripts using new utility scripts setup-* and report-*,
+         and allow command-line parameters to be added, for ad hoc testing.
+       + correct change to tailbox widget from 2009/02/22 using
+         dlg_button_layout(), which broke that widget.
+       + document some of the portability caveats.
+       + modify gauge widget to service callbacks (prompted by patch and
+         comments by Frank Sorenson).
+       + modify editbox to allow its input buffer to be larger than MAX_LEN
+         unless bounded by the --max-input option, and add limit-checks for
+         the buffer (report by slakmagik).
+       + improve manpage description of --checklist (report by Isaac Good).
+       + several improvements to configure script macros:  CF_ADD_CFLAGS
+         CF_CURSES_FUNCS CF_DISABLE_ECHO CF_GCC_ATTRIBUTES CF_MATH_LIB
+         CF_POSIX_C_SOURCE CF_REMOVE_DEFINE CF_WITH_LIBTOOL CF_XOPEN_SOURCE
+       + add is.po, lv.po, sw.po from
+               http://translationproject.org/latest/dialog/
+       + update de.po, id.po, pl.po, pt_BR.po, vi.po from
+               http://translationproject.org/latest/dialog/
+
+2009/02/22
+       + do not display top-arrows for scrolling if they would overwrite the
+         title (report by slakmagik)
+       + consistently use dlg_button_layout() when autosizing widgets (report
+         by slakmagik).
+       + add "-" and "+" bindings to timebox widget.
+       + add "-" and "+" bindings to calendar widget (OpenSolaris #6739031).
+       + review/fix other widgets to ensure that they exit on error, e.g.,
+         editbox.c
+       + modify check in dlg_getc() to treat closure of either stdin or stdout
+         as an error, rather than both.  This is more stringent than the check
+         added in 2007/07/04.
+       + modify dlg_result_key() to map curses ERR to dialog's error exit
+         (adapted from patch by Domagoj Pensa).
+       + updated several configure script macros:
+         + consistently append, rather then prepend, to $CFLAGS
+         + add cases for AIX 6, mint, and dragonfly to CF_XOPEN_SOURCE
+         + use $PATH_SEPARATOR rather than $PATHSEP
+         + improve CF_FIND_LINKAGE, use in checks for more libraries, e.g.,
+           libutf8 and libiconv.
+       + update da.po, ru.po from
+               http://translationproject.org/latest/dialog/
+       + update config.guess, config.sub
+
+2008/08/19
+       + amend changes to quoting; by default, the checklist widget quotes its
+         output except when --separate-output is used (Debian #495600).
+       + add eo.po from
+               http://translationproject.org/latest/dialog/
+
+2008/07/27
+       + add pointer-check when closing piped input (cf: 2007/03/25)
+       + use here-documents rather than echo, when passing backslashes in
+         strings, to accommodate the Debian shell "dash" (Debian #489563).
+       + recode several ".po" files to UTF-8 for consistency.
+       + change --separator to be an alias for --output-separator, for
+         compatibility with Xdialog.
+       + add --output-separator option to allow scripts to change the output
+         separator from a newline (for --separate-output) or a space.  This
+         applies to other widgets such as forms and editboxes which normally
+         use a newline.
+       + add --column-separator option, to tell where column-aligned data for
+         radio/checkboxes or menus should be split into columns (request by
+         Ben Dibbens).
+       + add id.po, ku.po, lt.po, nb.po and update ca.po, fr.po, gl.po, ja.po,
+         th.po from
+               http://translationproject.org/latest/dialog/
+       + add "--quoted" option, to quote values returned by formbox, etc.
+       + change names of EX/ES macros in dialog.1 to work around name-
+         pollution caused by changes in Debian #470729.
+
+2008/03/16
+       + modify dlg_mouse_wgetch() to loop only on errors that it detects,
+         rather than on errors forwarded from dlg_getc(), in case those are
+         due to a disconnected terminal (report by Anatoli Sakhnik).
+       + allow "default" color in dialogrc file (request by Dashing).
+       + fix an indexing error in formbox (Debian #469190, report by Dmitry
+         Gomerman, patch by Vladimir Mezentsev).
+       + add bindings for CTL/N, CTL/P to checklist, fselect and menubox
+         widgets (prompted by discussion with John Gatewood Ham).
+       + add be@latin.po, th.po and update zh_TW.po from
+               http://translationproject.org/latest/dialog/
+       > patches by Peter Astrand:
+         + modify dlg_auto_sizefile() to ensure the computed height and width
+           do not extend beyond the screen size.
+         + use unctrl() to make inputstr.c work with Solaris curses.
+       > patches by Yura Kalinichenko:
+         + extend pause widget to use ok/cancel buttons (the former giving the
+           same result as a timeout), rather than an exit-button.
+         + fix initialization parameter of inputbox for multibyte characters.
+
+2007/10/28
+       + improve layout of checklist.c, menubox.c, ensuring that the list fits
+         within the available space (report by Gordon Schumacher).
+       + undo removal of redundant chunk from checklist.c in 2007/02/27,
+         since some scripts depend on this (Debian #443077).
+       + update nl.po from
+               http://translationproject.org/latest/dialog/
+
+2007/09/30
+       + correct cursor position in editbox after deleting past left margin
+         (report by Joe McDonagh).
+       + add "--no-ok" option (patch by Klaus Knopper).
+       + modify "--file" option to allow it to read from sources other than
+         a regular file (patch by Pieter van Beek).
+       + improved hi.po (Hindi) (from Klaus Knopper).
+       + fix masking of attributes in dlg_draw_shadow() which lost
+         line-drawing bit (report by David Everly).
+       + fix editbox widget to handle zero-length files (report by Joe
+         McDonagh).
+       + update "po" files eu.po ga.po it.po ms.po sv.po vi.po wa.po zh_CN.po
+         from
+               http://translationproject.org/latest/dialog/
+
+2007/07/04
+       + revise the resizable shadows so textbox's search dialog has text
+         visible in the shadow again.
+       + improve the prefixing of autoconf-related symbols in the installed
+         header files, taking into account symbols which are not mentioned in
+         dlg_config.h
+       + add a check when ERR returned from wgetch() to ensure that the
+         input/output streams are still valid.  If that happens, force
+         ESC to be returned, quitting dialog (report by Reiner Huober).
+       + add extern "C" declarations to dlg_keys.h so the corresponding
+         function declarations are exported to C++ as C symbols.
+       + update config.guess, config.sub
+
+2007/06/04
+       + fix a memory leak in editbox.c
+       + revise change from 2007/02/27 which moved the logic for trimming
+         option text out of the loop because that moved it before
+         initialization of the "--trim" option.  Put it back in the loop, but
+         limit the tokens which are trimmed to cover only those for the
+         current widget.  Also ensure that all tokens for a widget are
+         trimmed, rather than only the first, which is usually text (report by
+         Lai Zit Seng).
+       + add _FILE_OFFSET_BITS definition in CF_LARGEFILE configure macro.
+
+2007/05/28
+       + revise changes needed to make textbox's searchbox handle ncurses
+         resizing events, e.g., by handling the ERR in that code rather than
+         in dlg_getc() (Debian #423732).
+
+2007/05/14
+       + supply a repaint_text() call in tailbox.c which was bypassed because
+         dlg_getc() now retries on ERR (Debian #423732, cf: 2007/02/27).
+       + modify dlg_getc() to fix regression in 2007/02/27 for use of
+         timeouts, broken by fixes to allow resizing of textbox (patch by
+         Arnaud Fontaine, Debian #418905).
+       + modify dlg_getc() to fix regression in use of TAB for traversal of
+         tailboxbg widgets due to changes for user-definable key bindings
+         (Debian #418917, cf:  2005/12/07).
+
+2007/04/09
+       + add case in dlg_getc() to handle tab for traversing between widgets
+         as in the samples/tailboxbg1 script.  Normally the key binding
+         overrides, except for the special case where multiple widgets are
+         available.
+       + add configure --with-libtool-opts, which passes its value to the
+         library creation and linkage passes, e.g.,
+               --with-libtool-opts=-static
+         to force the result to be static libraries (prompted by a related
+         request by Santiago Vila).
+       > several fixes based on Coverity scan:
+       + fix memory leak in timebox, calendar widgets if the widget cannot
+         be created.
+       + fix memory leak in dlg_key.c if a user binding's storage cannot
+         be allocated.
+       + fix improperly delinked entry in dlg_del_window().
+
+2007/03/25
+       + improve mkdirs.sh to ignore error from mkdir if the target directory
+         happens to already exist (suggested by Harald van Dijk).
+       + amend documentation for --gauge to reflect longstanding quirk which
+         allows it to read percentage from the first line after an "XXX"
+         (Debian #415596).
+       + fix makefile dependency so "configure && make install-lib" works.
+       + fix resizing of msgbox; the message was not repainted (Debian
+         #415022, patch by Brian Rolfe).
+       + fix typo in makefile LIB_OBJECT symbol from 2007/02/27 changes.
+       + improve CF_MBSTATE_T by including stdio.h, needed on Tru64 to make
+         the test-compile work.
+       + change makefile to install dialog.3 as part of install-lib rather
+         than install-man (report by Thomas Klausner).
+       + use $(INSTALL_SCRIPT) for installing dialog-config (report by
+         Santiago Vila).
+
+2007/02/27 - release 1.1
+       + mark as "dialog 1.1"
+       + add dialog-config script, which provides applications with compile-
+         and link-information for using the dialog library.
+       + move calls to dlg_trim_string() out of loop in dialog.c, so each
+         string is trimmed once (report by Ivanov Makcim).
+       + modify textbox.c to allow resizing while the search box is presented.
+         This relies on bug-fix in ncurses 5.6 20070224.
+       + use dgettext() rather than gettext() to allow libdialog to use the
+         messages installed for dialog (patch by Vajna Miklos).
+       + modify inputbox to position the cursor initially at the end of any
+         initial-text (request by Klaus Knopper).
+       + add configure --with-valgrind for testing.
+       + add --trace option, for debugging.
+       + add --ascii-lines and --no-lines options to control the way the
+         line-drawing characters are rendered (request by Klaus Knopper).
+       + add --keep-tite option, to override suppression of smcup/rmcup
+         (termcap ti/te) strings which would switch to xterm's alternate
+         screen (Debian #380665).
+       + modify fselect/dselect to use space-character as a completion
+         operator like tab in shells (patch by Yoram Bar Haim).
+       + remove a redundant chunk from checklist.c which reported status a
+         second time if the help-button was pressed but no item-help option
+         was in effect (Andre C Barros).
+       + fix return-status from "dialog --pause" (Debian #409254).
+       + add --mixedform and --mixedgauge dialogs based on patch from
+         Kiran Cherupally.
+       + add some notes on compatibility to the manpage.
+       + add editbox dialog (compatible with Xdialog, Debian #368478).
+       + add dselect dialog (compatible with Xdialog).
+       + remove an incorrect initialization of .text_flen from 2005/12/07
+         changes, which made all fields in a form editable (Debian #404045).
+       + report error and exit if a filename given for the --file option
+         cannot be opened (report by "Dog Walker").
+       + make --program-prefix, etc., work in configure script, e.g., to make
+         program install as "cdialog".  This does not alter the library name.
+       + add install-bin, install-man (and uninstall) rules to makefile.
+       + updates for configure script macros (originally vile, lynx, xterm):
+         AM_PATH_PROG_WITH_TEST, AM_WITH_NLS, CF_CURSES_CPPFLAGS,
+         CF_CURSES_LIBS, CF_INCLUDE_DIRS, CF_LARGEFILE, CF_MAKEFLAGS,
+         CF_PATH_SYNTAX, CF_SUBDIR_PATH, CF_SUBST, CF_WITH_DBMALLOC,
+         CF_WITH_DMALLOC, CF_WITH_LIBTOOL and CF_XOPEN_SOURCE.
+       + update config.guess, config.sub
+       > adapted fixes from SuSE package (Werner Fink):
+         + add some limit-checks in dlg_draw_shadow().
+         + make shadows resizable, using new dlg_move_window() in msgbox.c
+           and yesno.c
+         + add dialog_state.input, use this in end_dialog() to decide whether
+           to close pipe inputs and call _exit(), or simply call exit().
+         + modify dlg_ctl_size() to check if the reason for failure is because
+           shadows were used; retry in that case without shadows.
+         + add signal catcher for SIGSEGV.
+
+2006/02/21
+       + fix logic in split-out dlg_menu() to separate inputmenu and menu
+         handling (report by Auke Kok).
+
+2006/01/26
+       + fix fselect.c to compile properly with Intel compiler and largefile
+         option.
+       + improve configure script checks for curses headers to work around
+         breakage in some packages, e.g., cygwin.
+       + amend correction to menubox, fixes normal menus (Debian #349969).
+
+2006/01/19
+       + completed dialog.3 manpage
+       + modify configure script option --with-gauge to cover all flavors of
+         the gauge (gauge, pause, progressbox).
+       + add progressbox widget, a hybrid of gauge and tailbox (Reznic Valery).
+       + fix a comparison in checklist.c to avoid unneeded arrows when the
+         list happens to fit in the window (patch by Peter Postma).
+       + correct wrapping computation in print_line() from 2005/11/07 changes
+         (report by Barry Kauler).
+       + update sv.po (comments only).
+               http://www.iro.umontreal.ca/translation/maint/dialog/
+       + correct logic that passes the callback for menubox to do inputmenu
+         operations from 2005/12/7 changes (report by Reznic Valery).
+
+2006/01/01
+       + add a null-pointer check in dlg_register_buttons(), needed for the
+         tailboxbg (Debian #345524).
+       + fix a few memory leaks reported by valgrind.
+
+2005/12/19
+       + correct return-values of new functions dlg_default_listitem() and
+         dlg_default_formitem() (Debian #344002).
+       + add Swedish translation (Debian #343303, by Daniel Nylander)
+       + begin function-summaries in dialog.3
+       + update config.guess, config.sub
+
+2005/12/07
+       + change license to LGPL.
+       + change naming convention in dlg_colors.h to make it easier to read,
+         and incidentally remove the last chunk of code preventing relicense.
+       + add --passwordform (request by Reznic Valery).
+       + modify pause.c, msgbox.c to work with --help-button.
+       + modify formbox.c, inputbox.c, textbox.c, yesno.c to work with extra
+         button (adapted from Reznic Valery patch).
+       + modify dlg_exit_label(), dlg_yes_labels() and dlg_ok_label() to allow
+         help-button (prompted by Reznic Valery patch).
+       + add zh_CN.po file from
+               http://www.iro.umontreal.ca/translation/maint/dialog/
+       + provide alternate interfaces for dialog_checklist(), dialog_menu()
+         and dialog_form():  dlg_checklist(), dlg_menu() and dlg_form()
+         (discussion with Michael Gebetsroither).
+       + add/use dlg_result_key() to allow binding function keys to the
+         buttons.
+       + implement user-definable key bindings in the rc-file.
+       + modify inline cases for KEY_xxx values to use binding tables in new
+         module dlg_keys.c
+       + add several DIALOG_STATE items to the rc file:  aspect,
+         separate_widget, tab_len and visit_links
+       + add a tab-adjustment to dlg_print_text() to improve solution from
+         2005/10/30, e.g., in the samples/form* scripts.
+       + fix an off-by-one which made mouse-selection not work for menu items
+         past the first page (GenToo #112024, patch by Harald van Dijk).
+
+2005/11/07
+       + extend dlg_add_result() to allow caller to pass a null pointer
+         for dialog_vars.input_result (Debian #336986).
+       + correct length used for text portion of radio/checkboxes (report by
+         Valentin Stoykov).
+       + modify msgbox, textbox and center_label() to work properly for
+         LANG=bg_BG.utf8 examples by Valentin Stoykov.
+       + modify use of freopen() to work with opaque FILE type on DragonFly
+         (report by Jeremy C Reed).
+       + modify print_line() to compute columns, use that for the call to
+         dlg_print_line().  Fix a few places where strlen() was used instead
+         of dlg_count_columns() (reports by Valentin Stoykov).
+
+2005/10/30
+       + reviewed changes since beginning development in 1999, decided that
+         there are no appreciable portions of original code remaining.
+         Marked sources to correspond.
+       + improve cache performance for inputstr.c using tsearch() rather than
+         a linked-list search (Debian #294853).
+       + remove a special case for darwin in CF_XOPEN_SOURCE configure macro.
+       + add ms.po file from
+               http://www.iro.umontreal.ca/translation/maint/dialog/
+       + remove an assignment that caused the cursor to appear initially on a
+         form field rather than button (Debian #333506).
+       + modify buttons.c to count columns rather than bytes, fixing case
+         where buttons were laid out incorrectly (report by Valentin Stoykov).
+       + change dlg_print_text() to count columns rather than bytes, fixing
+         case where fewer columns were displayed in menu than expected
+         (report by Valentin Stoykov).
+
+2005/10/05
+       + improve fix for dlg_does_output(), eliminating redundant leading
+         separator.
+       + fill background color for item-help text (report by Peter Postma).
+       + correct interaction between --separate-output and --output-separator
+         broken in 2005/09/11 fix for Debian #326918 (Debian #331440).
+       + update config.guess, config.sub
+
+2005/09/11
+       + undo doubled adjustment for left/right margins when wrapping text
+         for msgbox, gauge and pause (report by Xyba).
+       + correct position of scrolled text in formbox broken by 2004/12/19
+         changes (report by Konrad Jelen).
+       + call dlg_does_output() from dlg_add_result(), ensuring that
+         separators are used when combining widgets such as formbox (report by
+         John Suykerbuyk).
+       + fix marker in textbox.c to make it disappear at the top of the file
+         (report by Patrick J. Volkerding).
+       + fix marker shown in arrows.c for checklists, etc., which was "(+)"
+         where it should have been "(-)" (report/patch by Patrick J.
+         Volkerding).
+       + fix --input-fd (changes in glibc since 2003 made dialog hang on exit
+         due to the way dialog updated stdin).
+       + restore default value (a tab) for --separator or --separate-widget
+         lost in 2003/11/26 changes (Debian #326918).
+       + make several widgets handle SIGWINCH (calendar, checklist, formbox,
+         fselect, inputbox, menubox, pause, tailbox, textbox, timebox).  Only
+         msgbox and yesno had been done before.  Note that some still have
+         fixed geometry requirements, so they cannot be shrunk below a given
+         threshold.  Also, these changes do not address traversal, e.g., for
+         tailboxbg.
+       + make gauge widget handle SIGWINCH with ncurses (Debian #305705).
+       + add configure option to control whether largefile support is
+         compiled-in (Debian #298882).
+       + update eu.po (Debian #312622, patch by Piarres Egana).
+       + add/update po files from
+               http://www.iro.umontreal.ca/translation/maint/dialog/
+         fi.po, rw.po, sr.po, tr.po, zh_TW.po
+       + fixes for configure script:
+         + improve script for determining gcc version
+         + improve checks for Intel compiler and related warning options
+         + improve checks for defining _XOPEN_SOURCE (or alternatives) and
+           _POSIX_C_SOURCE
+       + update config.guess, config.sub
+
+2005/03/06
+       + add/update po files from
+               http://www.iro.umontreal.ca/translation/maint/dialog/
+         ga.po, it.po
+       + revert last change for da.po; it was from an older version (report by
+         Morten Brix Pedersen).
+
+2005/02/06
+       + modify makefile.in so --disable-echo applies to libtool builds.
+       + corrected malloc size used for editable fields in formbox widget to
+         match the function which updates the corresponding buffer.
+       + modify formbox widget's use of flen to allow negative values to be
+         used to limit the length of the displayed field.
+       + improve description in manpage of output from formbox widget
+         (Debian #292418).
+       + modify formbox widget to allow fields with flen==0 to display
+         (Debian #292417).
+       + improved configure macros CF_POSIX_C_SOURCE and CF_XOPEN_SOURCE, to
+         avoid redefinition warnings on cygwin.
+       + fix a typo in inputmenu-stdout found via "sh -n" (report by Steve
+         Grubb).
+       + add/update po files from
+               http://www.iro.umontreal.ca/translation/maint/dialog/
+         ca.po, da.po, hu.po, nl.po, rm.po, ro.po, vi.po
+
+2005/01/16
+       + add --args option to help with debugging scripts.
+       + adapted some new po files from Debian package for whiptail:  ar.po,
+         bg.po, gl.po, hi.po, hr.po, mg.po, mk.po, ro.po, sq.po and zh_TW.po
+       + update da.po (Morten Brix Pedersen).
+       + add configure check for Intel 8.0 compiler, to set appropriate
+         warning options.
+       + update config.guess, config.sub
+
+2004/12/22
+       + correct a typo in 2004/12/19 changes which caused width of multibyte
+         characters to be incorrectly computed in some locales.
+       + modify --version and --help options to write consistently to the
+         standard output (report by Santiago Vila).
+       + modify tailboxbg by resetting tty modes at the point where it forks a
+         process to update the screen, rather than waiting until that process
+         exits.  This improves user feedback by making it apparent that dialog
+         is no longer processing input after that point (Redhat #142538).
+       + minor updates to some .po files using Babel Fish, comparing with lynx.
+       + update es.po (Santiago Vila).
+       + work around bug in NetBSD 1.6 curses which seems to be confused by
+         reusing color pairs with different video attributes.  The problem
+         does not appear in NetBSD 2.0 curses (but its headers do not provide
+         version info, so color-caching is not available for that
+         configuration).
+       + modify pause and gauge widgets to ensure that reverse-video progress
+         bar is visible when the background is reversed, e.g., using the
+         default non-color attributes.
+       + use chtype rather than attr_t, to build with old Solaris curses,
+         used in save/restore operation from 2004/09/20.
+
+2004/12/19
+       + add pause-widget (patch by Yura Kalinichenko).
+       + modify exit-code returned on selecting the "Help"-button when the
+         --item-help option is given.  Previously this returned the same code
+         as "OK", since it combines output for "OK" with the help status.  It
+         now returns the help-code, but this can be overridden by setting the
+         environment variable $DIALOG_ITEM_HELP (reports by Erika Pacholleck
+         and Sebastian Muesch).
+       + modify formbox widget so input-length is not limited to field-length
+         (report by David Liebermann).
+       + localize the label on the search box for textbox widget (report by
+         Erika Pacholleck).
+       + correct usage message detail for fselect, which listed an extra
+         parameter (Debian #284008).
+       + add include for <sys/select.h> in ui_getc.c to build with QNX 4.25
+         using Watcom 10.6 (patch by Len Meakin).
+       + modify behavior when no locale (or POSIX locale) is set to allow
+         legacy interpretation of Latin-1 character set (Debian #284795).
+
+2004/11/18
+       + correct computation of column width for menubox/checkbox tags, for
+         multicolumn characters, e.g., the menubox-utf8 example.
+       + correct calls to wbkgdset(), which set the background attribute but
+         not the corresponding character (ncurses uses blank if none is given).
+       + improve configure script check for _XOPEN_SOURCE and _POSIX_C_SOURCE.
+       + improved limit-computation in show_message() to allow for scrolling
+         very long messages.
+       + adjust scrolling logic in msgbox to account for the one-line offset
+         used by the logic which wraps text in a box, thus avoiding leaving
+         an extra blank line (report by Maxim Sobolev).
+
+2004/09/20
+       + add samples/whiptail.rc
+       + add samples/dialog.py (noting that a later version of this exists
+         as pythondialog, but this is relatively self-contained).  Modified
+         the script to accept the $DIALOG environment variable like the other
+         sample scripts, to specify the path of the program to use.
+       + modify the install rule for header-files so the autoconf names in
+         dlg_config.h (and corresponding usage in dialog.h, etc), are altered
+         from "HAVE_xxx" to "DLG_HAVE_xxx", etc.
+       + add a check for getenv("HOME") in rc.c
+       + add a call to end_dialog() in signal_handler for tailboxbg (from
+         patch by Werner Fink).
+       + correct initialization in checklist and radiobox for --default-item,
+         scrolling as needed.
+       + modify --visit-items option so that it puts the cursor initially on
+         the list (in menubox, checklist and radiobox), accepts abbreviations
+         for the buttons when the cursor is on the button-row, and otherwise
+         (when --visit-items is given) abbreviations apply only to the list
+         (report by Erika Pacholleck).
+       + modify a few widgets (inputbox, textbox, yesno) to beep on unexpected
+         input.
+       + modify some msgbox widget to accept abbreviations of its button
+         label, for consistency with other widgets (request by Erika
+         Pacholleck).
+       + corrected logic of dlg_char_to_button(), making it check only the
+         first uppercase letter in each button label rather than all uppercase
+         letters (report by Erika Pacholleck, cf: 2003/09/10).
+       + improved description of --clear and --keep-window options (adapted
+         from Erika Pacholleck).
+       + move discussion of --beep and --beep-signal options to Obsolete
+         Options section of manpage, remove these from the help-message
+         (report by Erika Pacholleck).
+       + bracket extern's in dialog.h with C++ extern "C" declaration, in case
+         the library is used from a C++ application.
+       + modify inputmenu examples to allow ESC to cancel the script.
+       + modify inputmenu widget to cancel edit on a TAB or ESC.
+       + modify inputmenu widget to use the same color scheme for the editable
+         text as the inputbox widget.
+       + modify samples/killall to work around differences in "cut" versions.
+       + use the color-caching from the \Z logic when loading the ".rc" file,
+         thereby reducing the number of color pairs required, and making it
+         less likely that deriving color pairs for drawing arrows on a given
+         background will run out of colors.
+       + save/restore window attributes in dlg_draw_arrows() and similar
+         functions, to allow widgets to draw arrows using the widget's
+         background rather than a common/fixed value (request by Erika
+         Pacholleck).
+       + modify textbox widget so the down-arrow will be hidden when at the
+         end of the file.  (Modifying the up-arrow to be hidden is harder -
+         will do this when implementing scrollbars).
+       + correct off-by-one in fselect.c which left down-arrows showing at
+         the bottom of directory- and file-lists (report by Erika Pacholleck).
+       + improve display of percentages by omitting blanks where lines should
+         be shown.
+       + modify logic for \Z escapes to make those that set video attributes
+         not clear the colors (report by Erika Pacholleck).
+       + modify logic for \Z escapes to allow foreground and background
+         colors to be the same, provided that bold attribute is set.
+         Also improved the logic for choosing a background color when the
+         foreground and background are the same (report by Erika Pacholleck).
+       + updated configure script macro CF_XOPEN_SOURCE, ensuring that the
+         _POSIX_C_SOURCE value is defined with a specific value (bug report
+         originally for lynx).
+       + fix configure script so that po/makefile is generated properly when
+         the configure --srcdir --enable-nls options are used.
+       + modify makefile.in to allow build/install from another directory,
+         i.e., using configure --srcdir (patch by Mike Castle).
+       + updated da.po (Debian #262587, Morten Brix Pedersen).
+       + modify some sample scripts to avoid using grave quotes nested within
+         double quotes with multiple file redirection, which does not work
+         with Solaris /bin/sh (report/analysis by Eric Haller).
+       + check for end of string immediately after a \Z escape to avoid
+         displaying the null terminator as a ^@ (report by Erika Pacholleck).
+       > patches by Erika Pacholleck:
+       + modify calendar.c, fselect.c and timebox.c to use color scheme like
+         other lists, using menubox colors rather than dialog colors.
+       + correct charset for po/de.po, translate messages for "Help" and
+         "Rename".
+       + omit parentheses around percentage in textbox.c
+       + correct a few mismatched attributes, e.g., searchbox_attr in textbox.c,
+         percentage in msgbox.c,
+
+
+2004/07/31
+       + add test scripts to cover zero-width column case.
+       + remove limit checks from checklist.c and menubox.c (cf: 2004/07/28),
+         since some scripts use zero-width columns (Debian #262411 and report
+         by Kyle Sallee).
+
+2004/07/29
+       + modify msgbox.c to only reserve space for percentage shown as part
+         of scrollable text for the msgbox widget.  This makes infobox look
+         as it did before 2004/06/06 changes (report by Vinesh Christopher)
+
+2004/07/28
+       + remove redundant calls to wtimeout() from widgets since wtimeout()
+         is properly called from ui_getc() where it is controlled by the
+         --timeout option (bug report by juanjo).
+       + add limit checks in checklist.c and menubox.c for very narrow screens
+         (prompted by Steve Grubb patch).
+       + initialize step in dlg_draw_buttons() in case it is used to draw
+         a vertical list of buttons (prompted by Steve Grubb patch).
+       > fixes by Steve Grubb:
+       + correct logic in checklist.c (cf: 2003/11/26 changes) which turned
+         quoting on unnecessarily for radiobox, breaking some old scripts.
+       + increase size of array in dlg_ok_labels() to avoid overrun if extra
+         and help buttons are used (cf: 2002/06/12 changes).
+       + initialize fkey variable in menubox.c and textbox.c (cf: 2003/07/12).
+
+2004/07/21 - release 1.0
+       + minor updates for configure script, i.e., CF_XOPEN_SOURCE,
+         CF_NCURSES_LIBS macros.
+       + update config.guess, config.sub
+       + add nl.po (Jacques Weewer).
+
+2004/06/06
+       + add --visit-items option, which allows the user to tab to the item
+         list in the checklist/radiobox and menubox widgets (request by
+         Ari Moisio).
+       + use wide-character line-drawing for up/down arrows when configured
+         for wide-characters, gives better results with uxterm.
+       + limit the number of times a --file option can be used, to prevent
+         runaway recursion if a --file option is embedded within a file which
+         is included.
+       + improve discussion of wrapping in the manpage (Debian #251937).
+       + modify msgbox to allow it to scroll vertically like textbox (Debian
+         #233276).  This only works with ncurses.
+       + implement $DIALOGVARS environment variable to apply common options to
+         dialog_vars when it is reset before processing other common options.
+       + add --single-quoted option to control whether output is double-quoted
+         with '"' or single-quoted with single-quotes.
+       + revert the default quoting behavior of checklists to use
+         double-quotes (report by Mark K Post regarding Slackware scripts).
+       + add eu.po (Basque) (Piarres Beobide Egaa).
+       + add ca.po (Catalan) (Jordi Mallach).
+
+2004/04/21
+       + add a call to flushinp() to init_dialog(), to discard any typeahead
+         before dialog is invoked (Debian #244746).
+       + correct dlg_match_char() function, which was broken during rewrite
+         to support wide-characters (Debian #244777).
+       + improved ru.po, uses UTF-8 charset (Leonid Kanter, Redhat #119200).
+       + correct position of shadow drawn for dialogs, which appeared to work
+         for most versions of curses (other than NetBSD) but would have been
+         visible for certain color schemes (discussion with Julian Coleman).
+       + correct loop-exit in longest_word() (Tomas Heredia, forwarded by
+         Santiago Vila).
+       + add cy.po (Welsh) (Dafydd Harries).
+
+2004/03/16
+       + modify quoting of results to use single-quote rather than double
+         quote, and ensure that results containing a quote or backslash
+         character are escaped (report by Florent Rougon)
+       + remove an incorrect comparison from checklist which made cursor
+         stick on the last line, from 2004/03/01 changes.
+
+2004/03/14
+       + add a dependency to install library if "--with-libtool" is used.
+       + add manpage for the library.
+       + add "--file"
+       + modify formbox.c to support "--help-status" like menubox.
+       + modify checklist.c to add item name to the "HELP" string when
+         "--help-button" is used and no --item-help option is given (Debian
+         #236841, report/patch by Jorg Sommer).
+       + rename colors.h to dlg_colors.h, install that when the library is
+         installed.
+       + add copyright notice to usage ("--help") message.
+       + correct a missing bounds check for mouse-clicks in menubox (prompted
+         by Debian #233044).
+       + updated several configure-script macros:  AM_GNU_GETTEXT,
+         AM_WITH_NLS, CF_OUR_MESSAGES, CF_PROG_EXT, CF_WITH_DBMALLOC,
+         CF_WITH_DMALLOC, CF_WITH_LIBTOOL, CF_XOPEN_SOURCE.
+
+2004/03/01
+       + improve layout of calendar widget to allow for very long button
+         labels (report by Santiago Vila).
+       + correct logic for $DIALOG_TTY, broken in 2003/11/30.  The environment
+         variable must evaluate to a nonzero integer (report by Florent
+         Rougon).
+       + document interaction between "--default-no" and "--no-cancel" options
+         in manpage (Debian #223488).
+       + change configure script to use autoconf 2.52+patch, to work around
+         issues with Estonian locale (report by Seemant Kulleen).
+       + add uk.po (Ukrainian) (Debian #232441).
+       + make --default-item apply to checklist widget (Debian #225255).
+       + correct a missing check for --item-help when --help-status was given
+         for checklist (Debian #232921).
+       + correct a missing bounds check for mouse-clicks in checklist (Debian
+         #233044).
+       + update config.guess, config.sub
+
+2003/12/07
+       + correct infinite loop in yesno widget when "--defaultno" option is
+         combined with "--no-cancel" (Debian #223077).
+
+2003/11/30
+       + suppress double-quotes added for "--help-status" option if the
+         string does not contain any special characters.
+
+2003/11/26
+       + add samples/sourcemage.rc, for comparison with slackware.rc
+       + add "--insecure" option (request by Sean Mathews (DrWho@f34r.com)).
+       + make "--defaultno" option apply to widgets which use OK/Cancel
+         buttons as well (Debian #209030).
+       + improve documentation of exit-codes for each widget in the manpage
+         (Debian #217926).
+       + add option "--keep-window" to suppress repainting after completing
+         each widget (request by Ingo van Lil).
+       + add options "--yes-label" and "--no-label" to allow override of the
+         "Yes" and "No" strings (request by Christoph Zwerschke).
+       + add option "--help-status" to allow script to restore a checklist
+         or radiolist after processing an item-help string (Debian #209031).
+       + modify width-calculation for non-formatted text to ensure it is
+         wide enough for the longest word in the text (patch by Andrew Gaul).
+       + modify dlg_index_columns() to count a newline as a single cell rather
+         than 2 for the normal curses case.  This fixes an off-by-one for
+         the text-justification, shown in screen 2 of msgbox1 sample script.
+       + fix dlg_char_to_button(); 2003/09/10 changes made it incorrectly
+         ignore case of the labels.
+       + change calendar's use of arrow keys so they are (as before 2002/06/22)
+         interpreted within the day-grid as movement within that grid (request
+         by David Anders).
+       + correct missing initialization of last_getc variable in dlg_getc()
+         (report/analysis by Victor Wodecki).
+       + modify main program to make
+               dialog --no-shadow --print-maxsize
+         work.  Normally dialog prints the screen size after subtracting the
+         area reserved for shadows, but some applications may need the actual
+         screen size (Debian #213424).
+       + several related changes (Debian #213425):
+         + separate the examples using "--stdout" and "--output-fd" from the
+           normal usage examples.
+         + add "--input-fd" option, provide a sample of its use.
+         + modify init_dialog() to use initscr() unless a "--stdout" option
+           was used.  Some scripts relied on the coincidence that redirecting
+           standard output from dialog would "work".  Before this change
+           init_dialog() assumed that redirected standard output was
+           synonymous with "--stdout" option (not the intended behavior).
+         + modify command-line parsing to look for "--stdout" and "--stderr"
+           options first, allowing only one.
+         + add a check for an environment variable $DIALOG_TTY which provides
+           the older behavior, i.e., try to open the terminal directly if
+           stdout is redirected.
+       + interface changes, to make libdialog simpler to use:
+         + rename all of the internal functions to begin with "dlg_", but
+           provide compatibility with older names if the application defines
+           __DIALOG_OLD_NAMES__.
+         + add dialog_version() function, and corresponding DIALOG_VERSION and
+           DIALOG_PATCHDATE definitions to dlg_config.h
+         + eliminate remaining global variables such as screen_initialized in
+           favor of dialog_state and dialog_vars.
+         + move some data such as dialog_vars.output to dialog_state, since
+           they are normally not reset between widgets.
+         + change interfaces of dialog_yesno() and dialog_checklist() to use
+           dialog_state.defaultno and dialog_vars.separate_output, making it
+           simpler and more consistent.
+       + improve configure script and related definitions:
+         + add "--with-libtool" option to provide shared library support by
+           libtool.
+         + rename generated "config.h" to "dlg_config.h", so it can be
+           installed without naming conflict.  Added "dlg_config.h" to
+           install-lib rule.
+         + modify configure script and makefile to use EXEEXT and OBJEXT.
+         + add "--enable-widec" option to control whether wide-curses features
+           are compiled-in, rather than check for the existence of those in
+           the curses library.  This allows building with HPUX curses, which
+           has abandoned legacy features while not quite supporting X/Open
+           curses.
+         + add configure check for getbegx(), etc., which are not provided on
+           all platforms.
+       + update config.guess, config.sub
+
+2003/10/02
+       + update hu.po (Arpad Biro).
+       + revert part of the 2003/08/18 change to "--stdout" option.  Using
+         stderr for screen output does not work well on several platforms
+         since stdout's settings are affected (report by Kent Robotti).
+
+2003/09/24
+       + modify tailbox to allow it to display files with arbitrarily long
+         lines.
+       + fix an infinite loop in tailbox, broken when making interface changes
+         to dlg_getc() (report by Ingo van Lil).
+       + amend fix for "--and-widget" to not treat "---" as an option (report
+         by Kent Robotti).
+       + updated es.po (Santiago Vila).
+
+2003/09/10
+       + correct "RENAMED" result from inputmenu widget, which did not reset
+         the result buffer, and did not account for scroll-offset (Debian
+         #209336).
+       + modify button, menu and checklist logic that matches a character to
+         the beginning of a text field to support wide-characters (completes
+         Debian #195674).
+       + modify configure script to not use "head -1".
+
+2003/08/30
+       + modify searchbox popup in textbox widget so one can simply press
+         return on an empty input to cancel the popup.
+       + modify error reporting to avoid clearing screen if a problem is
+         found in the ".rc" file.
+       + add color/attribute combinations for form widget (based on patch by
+         Reznic Valery).
+       + combine rc-file colors, attribute- and color-tables to obtain a
+         single table for color values, which requires less work to add new
+         entries.
+       + modify fselect widget to make back-tab work again, since it was
+         broken by the rewrite of dlg_edit_string().
+       + modify howmany_tags() so it will quit searching when it finds any
+         option, not only "--and-widget" (Debian #206636).
+       + correct call to dlg_print_text() in print_line(), which did not
+         account for hidden characters (report/patch by David Poole).
+       + modify print_button() to display properly if locale defines ok/cancel
+         or yes/no buttons that contain multibyte characters.
+
+2003/08/20
+       + correct an indexing error when deleting from the end of a line using
+         KEY_DC; it happened to work on Linux because malloc() clears memory
+         like calloc().
+       + add '\r' to case statement where '\n' is translated to KEY_ENTER to
+         work around defect in NetBSD curses.
+       + modify configure check for getparyx(), etc., which are implemented
+         by NetBSD curses as functions rather than macros.
+       + correct configure check for term.h, which may be <ncursesw/term.h>
+         if ncursesw development headers are installed, but not ncurses
+         development headers.  Or they may not coincide (Debian #206287).
+
+2003/08/18
+       + modify checklist.c and menubox.c to display tags properly if they
+         contain wide-characters.
+       + better solution for initializing curses when "--stdout" option is
+         used, e.g., use stderr for the output if it is a tty.  Also correct
+         the error handling, so dialog exits with an error if it cannot
+         find a way to do output (Debian #205509).
+       + modify sample scripts to use consistent definition of $DIALOG
+         (Debian #205508).
+       + add UTF-8 examples inputbox6-utf8, inputbox6-utf8 (from Tomohiro
+         Kubota, Debian #195674).
+       + modify print_line() to work with wide-characters, e.g., so it handles
+         wrapping for double-width characters.
+       + cache results from multibyte character indices, speeds up cursor
+         movement.
+       + modify form widget to support scrolling and mouse-selection.
+       + add form widget (based on patch by Reznic Valery).
+       + correct mouse-handling for inputmenu widget.
+       + corrections to menu.c: location of clearing operation, and height of
+         rows in code for older ncurses versions (patch by Reznic Valery).
+       + improve logic that compensates for xterm's alternate-screen by
+         cancelling the rmcup/smcup strings after the rmcup has been issued.
+         That ensures that dialog will not clear the screen on exit (report
+         by Javier Kohen).
+       + modify initialization between widgets to retain the values for the
+         --aspect, --separate-widget and --tab-len options.
+       + add --separator as an alias for --separate-widget (compatible with
+         Xdialog).
+       + correct handling of Xdialog's --icon and --wmclass options, whose
+         parameter was not ignored.
+       + correct logic for --separate-widget so its string is written before
+         each output, rather than only for --and-widget option (report by
+         Javier Kohen).
+       + improve limit-check in center_label() for buttons.c (report by Tor
+         Vidar Havstad).
+       + correct layout of --menu widget, which reduced display width due to
+         logic for --inputmenu being applied whether or not that configuration
+         was used (reports by Javier Kohen, Dimitar Zhekov and MAL
+         <mal@komcept.com>).  Fixes Debian #201215.
+       + modify gauge widget to support --begin option (Hans-Joachim Baader).
+       + updated pl.po (Jaroslaw Swierczynski).
+       + hide cursor while painting gauge.
+       + add auto-sizing logic to gauge widget (reports by Javier Kohen and
+         Robert Schubert).
+
+2003/07/20
+       + rewrote inputstr.c, allowing it to enter and display wide-characters.
+         Some nonprinting characters such as control/B can be edited as well.
+       + modify timebox to allow user to type numbers into the fields.
+       + change interfaces of dlg_getc(), mouse_wgetch(), etc., to add
+         parameter that returns whether the result is really a function-key.
+         This is needed to work with wide-character curses.
+       + correct computation of week-number in calendar widget (report by
+         Heiner Lamann).
+       + updated configure script macros:
+         + suppress -Winline with gcc 3.3, since it is broken.
+         + fix caching bug in CF_UTF8_LIB
+         + improved script for CF_BUNDLED_INTL.
+       + update config.guess, config.sub
+
+2003/03/08
+       + add null-pointer checks to some malloc calls which were overlooked.
+       + correct logic in dlg_add_result(), which did not copy content of
+         non-allocated buffer to the first allocation (report by Daniel
+         Dupont).
+
+2003/03/02
+       + correct an uninitialized value in dlg_add_result() (Debian #182683).
+
+2003/01/30
+       + corrected print_line(), which subtracted the margin twice from the
+         right-limit, making a string wrap unnecessarily (Debian #168823).
+       + correct initial limit-check for arrows in checklist.c, which used
+         the wrong variable, showing the bottom arrow when it should not
+         (Debian #168823).
+       + modify driver to always call show_result(), to simplify updates.
+       + fix several memory leaks, important if dialog is run with a large
+         number of widgets (report by albert.veli@telia.com forwarded by
+         Santiago Vila).
+       + check if the screen output is actually to the terminal before trying
+         to suppress xterm's alternate screen mode (see 2000/01/18) (report by
+         David Oliveira).
+       + use dialog_vars.input_result consistently to return the text which is
+         printed after a widget completes.  In many cases, dialog now
+         allocates enough space to hold the text, rather than use a fixed
+         buffer.  The checklist widget was writing directly to the output to
+         avoid limits of the fixed buffer.
+       + modify dialog.c to also write dialog_vars.input_result if the
+         Help-button was pressed (request by Amon Ott).
+       + add hu.po (Arpad Biro).
+       + update fr.po, pt.po, pt_BR.po to add strings for "Help" button (patch
+         by Frederic L W Meunier).
+       + fix off-by-one error in menu.c, checklist.c (reported by
+         Tomasz Wasiak 2002/09/15 and others:
+         Andrew Gaul 2002/11/12,
+         Tobias C Rittweiler 2002/11/19,
+         Arpad Biro 2003/01/21).
+       + updated configure script, improving checks for ncurses in various
+         locations, updated NLS script to match lynx.  Added --with-curses-dir
+         option.
+       > Tobias C Rittweiler:
+       + make ifdef in mousewget.c consistent with usage in dialog.h
+       + use beep() rather than flash() in dlg_edit_string(), for consistency
+         with the other functions.
+       + change order of buttons so extra button falls between Ok/Cancel.
+       + fix so "dialog --print-maxsize" exits from curses.
+       + add --inputmenu option.
+
+2002/08/14
+       + modify checklist.c and menubox.c to treat the extra button like the
+         "Ok" button by making dialog print the chosen items (request by
+         Tobias C Rittweiler).
+       + add examples checklist6 and menubox6 to illustrate the --colors
+         option.
+       + implement -colors option, which allows one to highlight words in the
+         titles and most text areas with color or video attributes (adapted
+         from patch by Tobias C Rittweiler).
+       + add examples inputbox4, inputbox5 to illustrate how to use the
+         --output-fd option, and how to use dialog without any temporary
+         file at all.
+       + add --output-fd option (Debian #153984).
+       + documented vi-style keys for calendar, textbox widgets in manpage.
+
+2002/06/22
+       + improve mouse handling, e.g., for up/down scrolling in calendar,
+         checklist, etc.
+       + add --extra-button and --extra-label options (adapted from patch
+         by Tobias C Rittweiler).
+       + correct displayed cursor position in inputbox when returning to the
+         input area after traversing the buttons with tabs, etc.
+       + add left/right arrows for traversal in calendar and timebox dialogs.
+       + implement two new functions dlg_next_ok_buttonindex() and
+         dlg_prev_ok_buttonindex(), using these to hide details about the
+         traversal over buttons in several widgets.
+       + modify checklist.c and menubox.c to verify if both --help-button and
+         --item-help are specified before assuming that selecting the help
+         button should cause the "HELP {item-help}" message to be printed
+         (reported by Marcel Ritter).
+       + modify init_dialog() to work around HP's broken tty driver (report by
+         John Mudd).  Specifically, the problem is that when opening /dev/tty
+         directly (to support the --stdout option), the terminal does not
+         change to raw mode.  The workaround opens /dev/tty only as needed;
+         the --stdout option does not work on HPUX but otherwise dialog works.
+       + updated el.po (patch by kromJx <kromJx@crosswinds.net>).
+
+2002/05/19 - release 0.9b
+       + add --no-collapse option to allow one to retain tabs and repeated
+         blanks in a message box (request by Roberto Simoni).
+       + use DLG_EXIT_ESC constant rather than -1's in several places.  This
+         has the effect of changing some exit-with-error cases to denote that
+         the exit was because ESC was pressed (patch by Diego Alvarez,
+         forward by Santiago Vila).
+       + bump package version to 0.9b (with patch-date, as usual).
+       + add --exit-label option (request by Roberto Simoni).
+       + updated de.po to correct translation for "Cancel" (from Michael
+         Piefel, Debian #146402).
+       + use definitions from autoconf macro AC_HEADER_TIME to ensure that
+         time() is properly prototyped.
+       + update pl.po, adding translation for "Help" (patch by Jaroslaw
+         Swierczynski <swiergot@hacking.pl>).
+       + update COPYING file, to reflect address change of FSF (reported by
+         Santiago Vila).
+       + update some configuration script macros:  CF_CHECK_CACHE,
+         CF_CURSES_CPPFLAGS, CF_HEADER_PATH and CF_MAKEFLAGS.
+       + correct misuse of "$with_XXX" variables in the configure script,
+         which prevented configuration against curses library as opposed to
+         ncurses.
+       + update config.guess, config.sub
+
+2002/03/09 (a)
+       + modify geometry of samples/fselect scripts to allow them to run in
+         a 24x80 screen (report/patch by Santiago Vila).
+       + correct exit-code for menubox.c when Cancel is pressed.  This was
+         unintentionally altered when adding --help-button (reported by
+         Patrick J Volkerding)
+
+2002/03/09
+       + add --timeout option, which forces the program to exit with an error
+         if no user response is given within the specified number of seconds
+         (request by <andrew@argoncorp.com>).
+       + modify calendar widget to allow day/month/year values to default to
+         the current date (request by <Ron.Perrella@bellsouth.com>).
+       + modify display of buttons in checklist.c and menubox.c to handle the
+         case where the button label is empty (Debian #134388).
+       + extended logic for ok/cancel/help to make this work with checklist
+         widget.
+       + revert pt_BT.po, apply changes to pt.po (report by Frederic L W
+         Meunier).
+       > several changes from Stanislav Ievlev:
+       + add options --help-button and --help-label to make menubox display a
+         third button which can be used to return an exit code causing the
+         calling script to show extended help information.
+       + use home/end keys in input string-editing, e.g., inputbox.
+       + add option --max-input to limit length of string returned by inputbox
+         and other widgets which allow the user to edit a string.
+
+2001/12/02
+       + add --ok-label and --cancel-label options (request by Kyle Sallee).
+       + correct usage message for --fselect option (reported by Patrick J
+         Volkerding).
+       + add samples/debian.rc, for comparison with slackware.rc
+       + corrected samples/slackware.rc, which was just the compiled-in
+         default values (patch by Patrick J Volkerding).
+       + modify search rule for rc-file to add a global rc file /etc/dialogrc
+         (patch by Patrick J Volkerding).
+       + updated pt_BR.po with modified entries for fselect.c (Frederic L W
+         Meunier).
+       + add pl.po (Swiergot <swiergot@l02.ids.czest.pl>).
+
+2001/11/11
+       + modify command-line parsing to allow a "--" argument to act as an
+         escape, so the next argument is not recognized as an option if it
+         begins with "--".  This is apparently one of popt's undocumented
+         features, upon which some Debian scripts depend (Debian #116642).
+       + add da.po (Morten Brix Pedersen <morten@wtf.dk>).
+       + add an install-strip rule to makefile, changing the normal install
+         rule to not strip the installed executable (based on discussion with
+         Santiago Vila).
+       + initialize my_output variable if user cannot open /dev/tty, e.g., if
+         su'd to another user (patch by Richard Braakman (<dark@ssh.com>), Debian
+         #117177).
+       + add configure option --with-ncursesw, to allow configure/build with
+         wide-character version of ncurses.
+
+2001/10/14
+       + add option --ignore, to make dialog be ignore options that it does
+         not recognize.
+       + add option --trim, to trim literal newlines and repeated spaces from
+         text that will be displayed.  Add samples/msgbox2, which is the
+         same as msgbox1, but using --trim (cf: change for Debian #102942).
+       + minor correction to attributes for buttons.c to use active_attr on
+         the right-side of a button.
+       + add a sample dialog rc-file slackware.rc based on diffs in hdasetup
+         package at
+               http://ftp1.sourceforge.net/pub/mirrors/slackware/slackware/source/a/hdsetup/
+         (discussion with Frederic L W Meunier).
+       + modify dialog.pl to avoid using a statically-named tempfile, allowing
+         multiple processes to use this script (patch by James Ranson
+         (<euclid80@yahoo.com>), Debian #110609).
+       + correct fprintf() call in j_menu() function, i.e., "--menu" option,
+         which did not guard against expanding '%' embedded in the parameters
+         (Stavros Chatzistefanidis <sxatz@yahoo.com>).
+       + add et.po (Ivar Smolin <okul@trenet.ee>).
+       + update fr.po (Frederic L W Meunier).
+       + modify to allow scripts to alter the exit codes, mainly to
+         distinguish ESC and ERROR exits.  This is done by setting a shell
+         variable such as DIALOG_ESC to a new value (request by Petr Vandrovec
+         (<vandrove@vc.cvut.cz>), Debian #99264)
+
+2001/08/27
+       + use VPATH in makefile to support build with configure --srcdir, if
+         the make program supports that.  Note that samples/install/makefile
+         is not generated, due to awkward limitation of autoconf script
+         (reported by Frederic L W Meunier <0@pervalidus.net>).
+       + add po/pt_BR.po (Frederic L W Meunier <0@pervalidus.net>).
+       + correct sense of --enable/--disable shown in configure --help (report
+         by Frederic L W Meunier <0@pervalidus.net>).
+       + correct logic for --clear option, broken in 2000/07/02 (fixes Debian
+         #110254).
+
+2001/08/11
+       + porting fixes to work on AIX: flush output to work around bug in
+         curses library, use ./killall in scripts to avoid conflict with
+         AIX program by that name.
+       + modify dlg_trim_string() to retain literal newlines if the string
+         does not contain "\\n" strings, and to retain leading blanks on the
+         resulting lines, for compatibility with older scripts (Debian
+         #102942).
+       + add charset specification to cs.po
+       + change dates in CHANGES to consistent format, add el.po for Greek
+         (patch by kromJx <kromJx@crosswinds.net>).
+       + eliminate static globals (bss, data) from modules rc, tailbox,
+         textbox using better parameter-passing convention, and const.
+       + cleanup temporary files in a few of the sample scripts.
+       + rewrote tailboxbg using select() rather than fork(), thereby
+         eliminating lock-files.  Only one process should be trying to display
+         on the screen at any given time.
+       + add error check to ensure that numeric parameters are really numbers.
+       + correct off-by-one in error messages reporting too-few or too-many
+         tokens for a given option (reported by George Mirchev).
+       + fix typo in manpage, "textboxbg" where "tailboxbg" was meant
+         (reported by George Mirchev <la@mail.techno-link.com>).
+       + use DLG_EXIT_xxx symbols consistently for all exit codes.
+       + updated es.po (patch by Santiago Vila).
+       + updates for some configure script macros from lynx:  CF_MAKEFLAGS,
+         CF_NCURSES_VERSION, CF_PROG_EXT.
+       + fixes to compile if <term.h> is included, e.g., when building with
+         AIX curses (report by Suzi Dowson <Suzi.Dowson@capgemini.co.uk>).
+
+2001/05/27
+       + updated dialog.pot
+       + modify fselect.c to work with autosize, i.e., given height and width
+         zero (report by Martin Povolny).
+       + add a null-pointer check in justify_text(), needed by fselect.c
+       + add several more options which dialog can safely ignore, from
+         Xdialog 2.0.2
+       + refinements for configure macros checking for $CPPFLAGS, from lynx.
+       + update config.guess, config.sub to match autoconf 2.50
+       > Martin Povolny <martin@solnet.cz>:
+       + add cs.po
+       + use nl_langinfo() to customize names for day-of-week, and month
+
+2001/05/11
+       > Vincent Stemen <dialog@AdvancedResearch.org>:
+          Fixed dialog.c to not pass menu items through dlg_trim_string().
+          Stripping extra spaces out of the menu items broke some of my
+          scripts by altering the string that it compared to know which menu
+          item was selected.  There should be no need to do justification on
+          the menu items, which are always one line, anyway.
+
+2001/04/29
+       > Vincent Stemen <dialog@AdvancedResearch.org>:
+       + rewrote the text justification code to be able to have preformatted
+         text in the prompts with extra spaces like the older versions of
+         dialog.  If there are "\n" strings in the text, then extra spaces are
+         preserved.  Lines are always wrapped on word boundaries.
+        + fixed --cr-wrap to break lines on '\n' (newline) characters and not
+          add an extra line at the top and bottom of the text.  It now works
+          as the manual says it should.
+       + it is no longer necessary to use "\n\" at the end of lines to escape
+         the '\n' character.  "\n" now works.  However, the old way, "\n\"
+         still works.
+        + the fixes involved the following changes:
+          - rewrote dlg_trim_string() to recognize preformatted text (know
+            when not to strip extra spaces) and to pay attention to --cr-wrap.
+          - rewrote justify_text() which now calls a new function in util.c,
+            print_line(), to print each line and end it on a word boundary.
+         - modified real_auto_size() to call a new function
+           auto_size_preformated() to calculate the box size for preformatted
+           text.
+          - removed skip_blanks() and skip_text() since they are not used by
+            the new justify_text().
+          - modified dialog.c to not call dlg_trim_string() on title strings
+            so that titles retain their spaces.
+        + modified the following demo files in the sample directory:
+          - inputbox
+             changed all "\n\" strings to "\n" to demonstrate the extra
+             backslash is no longer needed.
+          - inputbox1
+              removed all the "\n\" strings from the end of the lines to
+              properly demonstrate --cr-wrap.
+          - msgbox1
+             this sample was using "--aspect 9 --cr-wrap".  Rewrote it to
+             properly demonstrate --aspect.  9 is already dialog's default
+             aspect ratio.  It now creates several dialogs in sequence,
+             demonstrating aspect ratios of 9, 12 and 6 and properly
+             demonstrates --cr-wrap.
+        + made the following changes to the manual (dialog.1).
+          - rewrote the description of --aspect to be more understandable.
+          - rewrote the description of --cr-wrap to be more correct and more
+            detailed.  It did say, "Otherwise, the text for each dialog will
+            display on a single line.", which is not correct.  It wraps the
+            text to fit in the box.
+       > T.Dickey:
+       + use logic from menubox dialog in checklist to handle autosizing when
+         list height is given as zero (fixes problem reported by Eric Veltman
+         <eveltman@baan.nl>).
+       + modify checklist and menubox dialogs to check for too-wide data, and
+         truncate one or both of the name and text fields to fit (also
+         reported by Eric Veltman).
+       + corrected a few items from Vincent's patch:
+         - use C89-style comments rather than C++
+         - restore logic in justify_text() which checks for win==0, needed to
+           work with standard curses implementations other than ncurses.
+           The first call on justify_text() passes a null pointer as a flag
+           to indicate that checking should be done, but no screen updates.
+         - avoid modifying the buffer in decode_percent(), otherwise a message
+           containing a space or newline would be truncated at the whitespace.
+         - modify dlg_button_x_step() and dlg_button_layout() slightly to
+           work with altered print_autowrap(), etc.
+       + fixes to build/work with SunOS 4.x 5lib curses
+
+2001/04/15
+       + fix a memory leak in mouse_region().
+       + simplify handling of optional parameters with new functions
+         optional_str() and optional_num().
+       + add calendar and timebox dialogs (compatible with Xdialog).
+       + correct typo in fallback definition for getparyx, and remove void
+         cast for mouse_open and mouse_close which prevented build with
+         Sun's Solaris compiler.
+       + rename --enable-lxdialog configure option to --enable-Xdialog
+       + modify CF_NCURSES_CPPFLAGS macro to match more variations of ncurses
+         header files.
+       + update config.guess, config.sub
+       + modify some configure script macros to avoid problems with buggy
+         autoconf 2.49c which breaks changequote().
+
+2001/01/15
+       + small fix to revised real_auto_size() and justify_text() to avoid
+         adding origin to box-width, which broke samples/wheel.
+       + apply 1999/12/25 tempfile change to wheel and copismall samples.
+       + add sample script for tailboxbg.
+       + revised lock-file management to better ensure that locks are actually
+         created by the tailbox subprocess(es).
+       + correct hardcoded signal 15 in tailbox to SIGHUP to match
+         documentation.  Signal 15 is usually SIGTERM, which cannot be caught.
+       + correct off-by-one comparison of return-value for arg_rest() which
+         made
+               dialog --gauge test 10 50
+         dump core because it expected a 4th parameter (fixes Debian #80641).
+       + resync config.sub, config.guess from
+         http://subversions.gnu.org/cgi-bin/cvsweb/config/ (which finally have
+         cases for OS/2 EMX), minor tweaks to related configure script macros.
+
+2000/12/17
+       + restore treatment of predefined height/width in real_auto_size()
+         which was lost in 2000/12/12 rewrite (report by Raphael Halimi
+         <raphaelh@easynet.fr>).
+       + updates for configure script macros AM_PATH_PROG_WITH_TEST,
+         CF_CURSES_LIBS, CF_LIB_PREFIX, CF_PROG_EXT for $PATHSEP and $CFLAGS
+         fixes.
+
+2000/12/13
+       + correct change for create_lock(), which resulted in an infinite loop
+         (patch by Chris Butler, <chrisb@debian.org>).
+
+2000/12/12
+       + rewrote print_autowrap() and real_auto_size() to share common code
+         justify_text(), which now does text flow even when the string
+         contains newlines (fixes Debian #77199).
+       + improve create_lock() function using open() with O_EXCL rather than
+         fopen() (patch by Matt Kraai (<kraai@debian.org>), Debian #78951).
+       + correct description of --fselect in man page (patch by Tomas Pospisek
+         (<tpo@spin.ch>), Debian #77200).
+       + add --no-cancel as alias for --nocancel for compatibility with
+         Xdialog (report by Luis E Limon <luisl@abriasoft.com>).
+
+2000/10/27
+       + some lint fixes using lclint (mostly void-casts, but some
+         sign-extension fixes e.g., for ctype.h macros, and loop in
+         dlg_char_to_button()).
+       + modified to build/run on OS/2 EMX with ncurses.
+       + minor changes to po/*.po (trim trailing blanks, provide explicit
+         translation for "OK"), to work with Solaris gettext.
+       + modified to allow this to build with archaic version (1.8.6)
+         of ncurses on FreeBSD 3.1 (does not run).
+       + update config.guess, config.sub from subversions.gnu.org
+
+2000/10/17
+       + use new function sub_window() to check success/failure of calls to
+         subwin(), printing an error message if it fails (fixes Debian #74903).
+       + use combination of isatty/ttyname to look for workable tty device
+         on systems which have no /dev/tty, e.g., BeOS.
+
+2000/10/08
+       + change exiterr() to use stdarg.h, make some messages easier to
+         understand.
+       + add dialog_clear()
+       + make samples/install/setup build.
+       + implemented mouse support for buttons, e.g., in yesno dialog using
+         ncurses (the gpm support no longer works, but is useful for reference)
+       + add a configure check for chtype.
+       + updates for configure script macros (CF_BUNDLED_INTL, CF_CURSES_LIBS,
+         CF_GCC_ATTRIBUTES, CF_GCC_WARNINGS, CF_INCLUDE_DIRS), and scripts
+         config.guess, config.sub
+       + cleanup of item-help change, integrate with checklist and radiobox.
+       + add ja.po, from Hirofumi Takeda <takepin@turbolinux.co.jp>.
+       > patch by Marco Mariani <marcom@sferacarta.com>
+       + add --item-help option, which makes menubox data interpreted as
+         3 columns rather than 2.  The third column is displayed on the
+         last line of the screen as a help/status message for the currently
+         selected item.
+       + add it.po, pt.po
+       + change TAG_KEY_HL to FALSE, making unselected items in checklist
+         easier to read on Linux console.
+
+2000/07/30
+       + change real_auto_size() to allow it to be used for dialogs that have
+         no prompt, e.g., fselect.  Also, rather than requiring both height
+         and width to be given as -1 for maximizing the dialog, allow either
+         alone.
+       + increase minimum height needed for autosized yesno dialog.
+       + add --version as an alias for --print-version.
+       + fix for build on Solaris without NLS (cannot redefine 'gettext()').
+       + add fselect dialog (compatible with Xdialog).
+       + add --enable-lxdialog configure option.
+       + use new configure macro CF_ARG_MSG_ENABLE to show progress with
+         enable/disable switches.
+
+2000/07/02
+       + implement --stdout and --stderr options as in Xdialog.
+       + move logic that translates "\\n" into '\n' into main program to
+         simplify logic that formats text.
+       + make ifdef's for rc-file not specific to ncurses.
+       + correct logic making percent parameter of gauge optional.
+
+2000/06/29
+       + add alternate test-script for gauge, adapted from Xdialog.
+       + modify gauge to make optional a percentage which was read at the
+         beginning of the XXX-delimited message text, since clones of dialog
+         are written to assume this is text.  If the line is not a simple
+         integer, dialog will treat it as text.
+       + make the percent parameter of gauge optional, as in Xdialog.
+       + undo one use of CharOf() in guage.c, an error.
+       + fix configure macro AM_WITH_NLS to refrain from attempting to make a
+         symbolic link into/libintl.h if we are not using the bundled intl
+         directory from gettext (reported by Julian Coleman
+         <J.D.Coleman@newcastle.ac.uk>).
+       + add ru.po, from Michael Sobolev <mss@transas.com>
+       + updates for config.guess, config.sub from tin.
+       + updates for configure script macros:  CF_MATH_LIB (improperly nested
+         brackets/parenthesis) and CF_XOPEN_CURSES (make include of
+         <*curses.h> depend on configure tests).
+
+2000/04/25
+       + repaint screen when a control/L is pressed.
+       + apply CharOf() macro to avoid sign-extension on calls to waddch(),
+         fixes a problem with accented characters (reported by Santiago Vila).
+       + add es.po, from Santiago Vila <sanvila@unex.es>
+
+2000/04/23
+       + modified to use gettext (configure option --enable-nls).  This uses
+         gettext 0.10.35, which must be previously installed.  (It can also
+         use an included intl library, but I consider that to be a waste of
+         disk space).
+       + remove code in checklist/radiobox, menubox that try to use
+         abbreviations for the OK/Cancel buttons since those conflict with the
+         check for abbreviations in list entries, which are more useful.
+       + moved padding of button labels out of string literals, into the
+         logic of dlg_draw_buttons().
+       + resync/update with configure macros CF_CURSES_LIBS, CF_FIND_LIBRARY,
+         CF_HEADER_PATH, CF_LIBRARY_PATH and CF_NCURSES_LIBS, as well as
+         mkdirs.sh and config.guess.
+
+2000/02/22
+       + add --default-item option, for menubox to set the default selection
+         (fixes Debian #49796).
+       + add sample scripts for --nocancel and --fb options with inputbox.
+       + modify inputbox* sample scripts to show application errors, if any.
+       + add --nocancel option, and ignore --noitem, --fb, --fullbutton, to
+         make this compatible with whiptail scripts.  (whiptail does not
+         handle many dialog scripts however).
+       + modify checklist/radiobox to handle home, end, nextpage, prevpage
+         keys, as well as make the abbreviation search work for the whole
+         list, not only the current page.
+       + treat KEY_LL the same as KEY_END in checklist and textbox.
+       + add logic for KEY_BTAB.
+       + use new function dlg_draw_buttons() to better manage the layout of
+         yes/no/ok/cancel buttons.
+       + another pass of cleanup of dialog.c, makes it use a single table for
+         lookup of option names and help-message.  Eliminated numerous
+         adjustments to 'offset' variable.
+       + on initialization, check if standard input is from a terminal.  If
+         not, open /dev/tty (fixes Debian #57771)
+
+2000/02/05
+       + implement inline editing in textbox.c search dialog.
+       + revise inputbox.c, allowing inline editing with arrow-keys.  removed
+         redundant logic in that module.
+       + correct a typo that prevented rc-file configuration from building.
+       + correct ifdef's to compile/run if the curses implementation does not
+         support color.
+
+2000/01/23
+       + improve test-case for gauge.
+       + change gauge.c to show progress in reverse-video, add a check for
+         end-of-file in the loop for reading new messages.
+       + use curses whline() function to simplify print_arrows() logic in
+         checklist.c and menubox.c
+       + use curses beep() function rather than hardcoded strings.
+       + correct several compiler warnings for gcc -pedantic (mismatch of
+         const, signed/unsigned).
+       + modify exiterr() to avoid possible expansion of '%'.
+       + change CF_MATH_LIB configure macro to allow specifying a particular
+         test-function.  For dialog, this should be sqrt().  The macro was
+         originally written for ncurses, which needs sin().  However, that is
+         a builtin function on the m68k port (reported by Roman Hodek
+         <Roman.Hodek@informatik.uni-erlangen.de>, this fixes Debian #55553).
+
+2000/01/18
+       + update manpage (Debian #25648).
+       + modify configure test for math library to avoid using a constant
+         parameter to the test function, lest gcc optimize the call away
+         (fixes Debian #55553).
+       + restructure help-message so actual problem is indicated.  The original
+         help-message is shown if no parameters are given, or if the --help
+         option is specified alone.
+       + suppress xterm's alternate screen mode by sending an exit_ca_mode
+         after initscr if the terminal looks like xterm, e.g., has key_mouse
+         defined, and has private-mode escapes in both enter_ca_mode and
+         exit_ca_mode (fixes Debian #55181).
+       + change yellow lettering on white to blue on white, since it offers
+         better contrast (fixes Debian #51196).
+       + use napms() rather than sleep().
+       + some cleanup/simplification of main program.  Indent'd dialog.c and
+         util.c
+       + eliminate several places where repeated options are treated as
+         an error, since they are really executed once anyway.
+
+2000/01/15
+       + remove pre-autoconf Makefile
+       + remove sleep's from a few of the sample scripts, which left users
+         thinking that dialog was slow to complete an action.
+       + rewrote infobox sample script, using dialog's --sleep option and
+         a loop in the script.
+       + change 'ch' variable in tailbox.c to an integer, because it is
+         compared against EOF (fixes Debian #53157).
+       + corrected mandir variable in makefile.in (reported by Santiago Vila).
+       + small changes to sample scripts, from Debian: rename "guage" script
+         to "gauge", change path to copy of GPL used in textbox.
+       + add uninstall rule to makefile.in, fixed some dependencies so
+         "make install" works without first doing "make all".
+
+1999/12/25
+       + use more portable scheme for tempfile generation in samples.
+       + add a configure script, prefer to not use the original Makefile
+         because it works only with GNU make.
+       + correct prototype of 'main()', which misused const.
+       + modify guage.c to use fgets() rather than gets().
+       + merge changes from Debian package maintainer
+         Santiago Vila <sanvila@ctv.es>:
+
+         1999/10/07
+               + add a password dialog box (Debian #45964, patch by Joey Hess).
+               + implement "--defaultno" option to specify if the default for
+                 the yes/no box is "No" (Debian #46076, patch by Joey Hess).
+         1999/03/10
+               + modify input.c to clear the input field to the right of the
+                 given string, to help with screen-refresh
+         1998/12/08
+               + check for list_height less than one in checklist.c (Debian
+                 #22239).
+         1998/10/21
+               + use function wscrl() in preference to scroll() in checklist.c
+                 and menubox.c (unclear: in ncurses, scroll() is a macro that
+                 uses wscrl()).
+               + remove the "-I/usr/include/ncurses" option from Makefile
+                 since Debian does not install ncurses' header files into
+                 that directory.
+         1998/09/12
+               + simplify menubox.c using new functions print_arrows() and
+                 print_items().  add logic to handle KEY_NPAGE and KEY_PPAGE
+                 (Debian #26326).
+               + modifications to provide sample scripts (Debian #26211):
+                 + change sample scripts to use Debian tempfile utility rather
+                   than putting files into /tmp.
+                 + change sample scripts to use 'dialog' from user's path
+                   rather than in the parent directory as in the build
+                   directory.
+               + use the system copy of GPL rather than that in the build
+                 directory as an example for the textbox script.
+
+1999/11/27
+       + fix some gcc warnings about ambiguous use of "else"
+
+1999/05/01
+       + cleaned up some of the redundant code with new functions:
+               box_x_ordinate
+               box_y_ordinate
+               draw_title
+               draw_bottom_box
+               new_window
+
+       + modified msgbox.c and yesno.c to work with the KEY_RESIZE sigwinch
+         handling in ncurses 4.2
+
+       + corrected spelling of "gauge"
+
+The relevant portions of the Debian change log for the original version
+(dialog-0.9a-12) are abstracted here, omitting details of their packaging:
+
+1998/05/24
+
+       + Replaced guage.c by the one in dialog 0.6z, which is known to work.
+         Fixes Debian #18284: unstable dialog.
+
+1997/12/16
+
+       + dialog.c:  dialog_input_result printed with "%s" format.  This was
+         Debian #9913, fixed by Bill Mitchell, but the change was lost.
+       + Pristine source, .depend is not removed in clean target.  Instead, it
+         is made zero length (otherwise it would not work *without* fakeroot).
+       + Added '^U' support in input box (Debian #9915, patch by Joey Hess).
+       + Wrote patch to fix core-dumping problem (Debian #13170).  Sven Rudolph
+         <sr1@inf.tu-dresden.de>:
+
+-- vile:fk=8bit
diff --git a/contrib/dialog/COPYING b/contrib/dialog/COPYING
new file mode 100644 (file)
index 0000000..8add30a
--- /dev/null
@@ -0,0 +1,504 @@
+                 GNU LESSER GENERAL PUBLIC LICENSE
+                      Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+                 GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+\f
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                           NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/contrib/dialog/README b/contrib/dialog/README
new file mode 100644 (file)
index 0000000..b2c9b85
--- /dev/null
@@ -0,0 +1,61 @@
+-(1999-12-25)-------------------------------------------------------------------
+This version of dialog, formerly known as cdialog is based on the Debian
+package for dialog 0.9a (see CHANGES for recent modifications)
+- T.Dickey <dickey@invisible-island.net>
+
+-(1996-01-15)-------------------------------------------------------------------
+I have uploaded cdialog-0.9a.tar.gz to sunsite. It should be moved
+to pub/Linux/utils/shell, I think.
+
+Starting point for cdialog v.0.9a was dialog-0.6c. Many new features
+like as Resolution-independence, Auto-sizing, Maximizing, more widget
+on the same screen (multi-widget), etc. were added. New widget are 
+tailbox and tailbox-in-background. Here are the options:
+
+   Usage: dialog <Common options> <Box options>
+          { --and-widget <Common options> <Box options> }
+
+   Common options: <Global options>
+       [--backtitle <backtitle>] [--sleep <secs>] [--beep] [--beep-after]
+       [--clear] [--begin <y> <x>] [--aspect <ratio>] [--print-size]
+       [--print-maxsize] [--size-err] [--separate-output] [--cr-wrap]
+       [--tab-len <n>] [--tab-correct] [--print-version] [--no-kill]
+       [--title <title>]
+
+   Global options: [--shadow] [--no-shadow] [--separate-widget "<str>"]
+
+At the moment, mouse support with libgpm can't be added because it
+does't implement the wtimeout() function of ncurses. Wtimeout() is
+needed to have more widgets (es.tailbox) cooperating on the same
+screen... I don't know if with newer versions of libgpm it's possible.
+
+I have no more time to write docs for this new version...Is there
+anyone, that looking at the code, can do it??? Ouch! :-)
+Don't flame me!
+
+For the future, if any volunteer want, the way to evolve cdialog is to
+1) make a daemon for a better support of multi-tasking or implementing
+   multithreading.
+2) add an option that could permit to read commands (--options) from a
+   file, like as in a normal programming language, but maintaining 
+   compatiblity with older version of dialog.
+
+I no longer could maintain cdialog...
+Executable and library name of cdialog are the same of dialog, for
+compatiblity.
+
+I think that only one directive should be follow: don't use a resource
+like stdin, stdout when you'll write new options for cdialog; these 
+resources have to be shared from all widgets on the command line.
+Guage uses stdin :-/ so that can't be mixed for example with an inputbox,
+but it was made before of multi-widget. However this is not a big problem!
+
+THERE ARE NO *KNOWN* BUGS. If anyone has much time and can find the way
+to add wtimeout() support to libgpm, also mouse could be supported.
+
+Please use ncurses-1.9.4 or newer.
+
+|  __   |  demarco_p@abramo.it:~$ make Linux | more > UserFriendly;
+| /__)  |  /~~  _   _ _   _   /~\  _     /  .  _          |
+|/  ako | (___ (_) | ) ) (-' (__/ | )   /__ | | ) (_| ><  .  coordinator.
+
diff --git a/contrib/dialog/VERSION b/contrib/dialog/VERSION
new file mode 100644 (file)
index 0000000..c3a82bb
--- /dev/null
@@ -0,0 +1 @@
+11:0:0 1.2     20121230
diff --git a/contrib/dialog/argv.c b/contrib/dialog/argv.c
new file mode 100644 (file)
index 0000000..7416054
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * $Id: argv.c,v 1.2 2012/11/30 20:28:23 tom Exp $
+ *
+ *  argv - Reusable functions for argv-parsing.
+ *
+ *  Copyright 2011,2012        Thomas E. Dickey
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License, version 2.1
+ *  as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to
+ *     Free Software Foundation, Inc.
+ *     51 Franklin St., Fifth Floor
+ *     Boston, MA 02110, USA.
+ */
+
+#include <dialog.h>
+#include <string.h>
+
+/*
+ * Convert a string to an argv[], returning a char** index (which must be
+ * freed by the caller).  The string is modified (replacing gaps between
+ * tokens with nulls).
+ */
+char **
+dlg_string_to_argv(char *blob)
+{
+    size_t n;
+    int pass;
+    size_t length = strlen(blob);
+    char **result = 0;
+
+    for (pass = 0; pass < 2; ++pass) {
+       bool inparm = FALSE;
+       bool quoted = FALSE;
+       char *param = blob;
+       size_t count = 0;
+
+       for (n = 0; n < length; ++n) {
+           if (quoted && blob[n] == '"') {
+               quoted = FALSE;
+           } else if (blob[n] == '"') {
+               quoted = TRUE;
+               if (!inparm) {
+                   if (pass)
+                       result[count] = param;
+                   ++count;
+                   inparm = TRUE;
+               }
+           } else if (blob[n] == '\\') {
+               if (quoted && !isspace(UCH(blob[n + 1]))) {
+                   if (pass) {
+                       *param++ = blob[n];
+                       *param++ = blob[n + 1];
+                   }
+               }
+               ++n;
+           } else if (!quoted && isspace(UCH(blob[n]))) {
+               inparm = FALSE;
+               if (pass) {
+                   *param++ = '\0';
+               }
+           } else {
+               if (!inparm) {
+                   if (pass)
+                       result[count] = param;
+                   ++count;
+                   inparm = TRUE;
+               }
+               if (pass) {
+                   *param++ = blob[n];
+               }
+           }
+       }
+
+       if (!pass) {
+           if (count) {
+               result = dlg_calloc(char *, count + 1);
+               assert_ptr(result, "string_to_argv");
+           } else {
+               break;          /* no tokens found */
+           }
+       } else {
+           *param = '\0';
+       }
+    }
+    return result;
+}
+
+/*
+ * Count the entries in an argv list.
+ */
+int
+dlg_count_argv(char **argv)
+{
+    int result = 0;
+
+    if (argv != 0) {
+       while (argv[result] != 0)
+           ++result;
+    }
+    return result;
+}
+
+int
+dlg_eat_argv(int *argcp, char ***argvp, int start, int count)
+{
+    int k;
+
+    *argcp -= count;
+    for (k = start; k <= *argcp; k++)
+       (*argvp)[k] = (*argvp)[k + count];
+    (*argvp)[*argcp] = 0;
+    return TRUE;
+}
diff --git a/contrib/dialog/arrows.c b/contrib/dialog/arrows.c
new file mode 100644 (file)
index 0000000..22d29a1
--- /dev/null
@@ -0,0 +1,274 @@
+/*
+ *  $Id: arrows.c,v 1.49 2012/12/30 22:33:28 tom Exp $
+ *
+ *  arrows.c -- draw arrows to indicate end-of-range for lists
+ *
+ *  Copyright 2000-2011,2012   Thomas E. Dickey
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License, version 2.1
+ *  as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to
+ *     Free Software Foundation, Inc.
+ *     51 Franklin St., Fifth Floor
+ *     Boston, MA 02110, USA.
+ */
+
+#include <dialog.h>
+
+#ifdef USE_WIDE_CURSES
+#if defined(CURSES_WACS_ARRAY) && !defined(CURSES_WACS_SYMBOLS)
+/* workaround for NetBSD 5.1 curses */
+#undef WACS_DARROW
+#undef WACS_UARROW
+#define WACS_DARROW &(CURSES_WACS_ARRAY['.'])
+#define WACS_UARROW &(CURSES_WACS_ARRAY['-'])
+#endif
+#define add_acs(win, code) wadd_wch(win, W ## code)
+#else
+#define add_acs(win, code) waddch(win, dlg_boxchar(code))
+#endif
+
+/* size of decorations */
+#define ON_LEFT 4
+#define ON_RIGHT 3
+
+#ifdef HAVE_COLOR
+static chtype
+merge_colors(chtype foreground, chtype background)
+{
+    chtype result = foreground;
+    if ((foreground & A_COLOR) != (background & A_COLOR)) {
+       short fg_f, bg_f;
+       short fg_b, bg_b;
+       short fg_pair = (short) PAIR_NUMBER(foreground);
+       short bg_pair = (short) PAIR_NUMBER(background);
+
+       if (pair_content(fg_pair, &fg_f, &bg_f) != ERR
+           && pair_content(bg_pair, &fg_b, &bg_b) != ERR) {
+           result &= ~A_COLOR;
+           result |= dlg_color_pair(fg_f, bg_b);
+       }
+    }
+    return result;
+}
+#else
+#define merge_colors(f,b) (f)
+#endif
+
+/*
+ * If we have help-line text, e.g., from "--hline", draw it between the other
+ * decorations at the bottom of the dialog window.
+ */
+void
+dlg_draw_helpline(WINDOW *win, bool decorations)
+{
+    int cur_x, cur_y;
+    int bottom;
+
+    if (dialog_vars.help_line != 0
+       && (bottom = getmaxy(win) - 1) > 0) {
+       chtype attr = A_NORMAL;
+       const int *cols = dlg_index_columns(dialog_vars.help_line);
+       int other = decorations ? (ON_LEFT + ON_RIGHT) : 0;
+       int avail = (getmaxx(win) - other - 2);
+       int limit = dlg_count_real_columns(dialog_vars.help_line) + 2;
+
+       if (limit < avail) {
+           getyx(win, cur_y, cur_x);
+           other = decorations ? ON_LEFT : 0;
+           (void) wmove(win, bottom, other + (avail - limit) / 2);
+           waddch(win, '[');
+           dlg_print_text(win, dialog_vars.help_line, cols[limit], &attr);
+           waddch(win, ']');
+           wmove(win, cur_y, cur_x);
+       }
+    }
+}
+
+void
+dlg_draw_arrows2(WINDOW *win,
+                int top_arrow,
+                int bottom_arrow,
+                int x,
+                int top,
+                int bottom,
+                chtype attr,
+                chtype borderattr)
+{
+    chtype save = dlg_get_attrs(win);
+    int cur_x, cur_y;
+    int limit_x = getmaxx(win);
+    bool draw_top = TRUE;
+    bool is_toplevel = (wgetparent(win) == stdscr);
+
+    getyx(win, cur_y, cur_x);
+
+    /*
+     * If we're drawing a centered title, do not overwrite with the arrows.
+     */
+    if (dialog_vars.title && is_toplevel && (top - getbegy(win)) < MARGIN) {
+       int have = (limit_x - dlg_count_columns(dialog_vars.title)) / 2;
+       int need = x + 5;
+       if (need > have)
+           draw_top = FALSE;
+    }
+
+    if (draw_top) {
+       (void) wmove(win, top, x);
+       if (top_arrow) {
+           (void) wattrset(win, merge_colors(uarrow_attr, attr));
+           (void) add_acs(win, ACS_UARROW);
+           (void) waddstr(win, "(-)");
+       } else {
+           (void) wattrset(win, attr);
+           (void) whline(win, dlg_boxchar(ACS_HLINE), ON_LEFT);
+       }
+    }
+    mouse_mkbutton(top, x - 1, 6, KEY_PPAGE);
+
+    (void) wmove(win, bottom, x);
+    if (bottom_arrow) {
+       (void) wattrset(win, merge_colors(darrow_attr, borderattr));
+       (void) add_acs(win, ACS_DARROW);
+       (void) waddstr(win, "(+)");
+    } else {
+       (void) wattrset(win, borderattr);
+       (void) whline(win, dlg_boxchar(ACS_HLINE), ON_LEFT);
+    }
+    mouse_mkbutton(bottom, x - 1, 6, KEY_NPAGE);
+
+    (void) wmove(win, cur_y, cur_x);
+    wrefresh(win);
+
+    (void) wattrset(win, save);
+}
+
+void
+dlg_draw_scrollbar(WINDOW *win,
+                  long first_data,
+                  long this_data,
+                  long next_data,
+                  long total_data,
+                  int left,
+                  int right,
+                  int top,
+                  int bottom,
+                  chtype attr,
+                  chtype borderattr)
+{
+    char buffer[80];
+    int percent;
+    int len;
+    int oldy, oldx;
+
+    chtype save = dlg_get_attrs(win);
+    int top_arrow = (first_data != 0);
+    int bottom_arrow = (next_data < total_data);
+
+    getyx(win, oldy, oldx);
+
+    dlg_draw_helpline(win, TRUE);
+    if (bottom_arrow || top_arrow || dialog_state.use_scrollbar) {
+       percent = (!total_data
+                  ? 100
+                  : (int) ((next_data * 100)
+                           / total_data));
+
+       if (percent < 0)
+           percent = 0;
+       else if (percent > 100)
+           percent = 100;
+
+       (void) wattrset(win, position_indicator_attr);
+       (void) sprintf(buffer, "%d%%", percent);
+       (void) wmove(win, bottom, right - 7);
+       (void) waddstr(win, buffer);
+       if ((len = dlg_count_columns(buffer)) < 4) {
+           (void) wattrset(win, border_attr);
+           whline(win, dlg_boxchar(ACS_HLINE), 4 - len);
+       }
+    }
+#define BARSIZE(num) (int) (0.5 + (double) ((all_high * (int) (num)) / (double) total_data))
+#define ORDSIZE(num) (int) ((double) ((all_high * (int) (num)) / (double) all_diff))
+
+    if (dialog_state.use_scrollbar) {
+       int all_high = (bottom - top - 1);
+
+       this_data = MAX(0, this_data);
+
+       if (total_data > 0 && all_high > 0) {
+           int all_diff = (int) (total_data + 1);
+           int bar_diff = (int) (next_data + 1 - this_data);
+           int bar_high;
+           int bar_y;
+
+           bar_high = ORDSIZE(bar_diff);
+           if (bar_high <= 0)
+               bar_high = 1;
+
+           if (bar_high < all_high) {
+               int bar_last = BARSIZE(next_data);
+
+               wmove(win, top + 1, right);
+
+               (void) wattrset(win, save);
+               wvline(win, ACS_VLINE | A_REVERSE, all_high);
+
+               bar_y = ORDSIZE(this_data);
+               if (bar_y >= bar_last && bar_y > 0)
+                   bar_y = bar_last - 1;
+               if (bar_last - bar_y > bar_high && bar_high > 1)
+                   ++bar_y;
+               bar_last = MIN(bar_last, all_high);
+
+               wmove(win, top + 1 + bar_y, right);
+
+               (void) wattrset(win, position_indicator_attr);
+               wattron(win, A_REVERSE);
+#if defined(WACS_BLOCK) && defined(NCURSES_VERSION)
+               wvline_set(win, WACS_BLOCK, bar_last - bar_y);
+#else
+               wvline(win, ACS_BLOCK, bar_last - bar_y);
+#endif
+           }
+       }
+    }
+    dlg_draw_arrows2(win,
+                    top_arrow,
+                    bottom_arrow,
+                    left + ARROWS_COL,
+                    top,
+                    bottom,
+                    attr,
+                    borderattr);
+
+    (void) wattrset(win, save);
+    wmove(win, oldy, oldx);
+}
+
+void
+dlg_draw_arrows(WINDOW *win,
+               int top_arrow,
+               int bottom_arrow,
+               int x,
+               int top,
+               int bottom)
+{
+    dlg_draw_helpline(win, TRUE);
+    dlg_draw_arrows2(win,
+                    top_arrow,
+                    bottom_arrow,
+                    x,
+                    top,
+                    bottom,
+                    menubox_border2_attr,
+                    menubox_border_attr);
+}
diff --git a/contrib/dialog/buildlist.c b/contrib/dialog/buildlist.c
new file mode 100644 (file)
index 0000000..362b75f
--- /dev/null
@@ -0,0 +1,1110 @@
+/*
+ *  $Id: buildlist.c,v 1.56 2012/12/31 00:38:57 tom Exp $
+ *
+ *  buildlist.c -- implements the buildlist dialog
+ *
+ *  Copyright 2012     Thomas E. Dickey
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License, version 2.1
+ *  as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to
+ *     Free Software Foundation, Inc.
+ *     51 Franklin St., Fifth Floor
+ *     Boston, MA 02110, USA.
+ */
+
+#include <dialog.h>
+#include <dlg_keys.h>
+
+/*
+ * Visually like menubox, but two columns.
+ */
+
+#define sLEFT         (-2)
+#define sRIGHT        (-1)
+
+#define KEY_TOGGLE    ' '
+#define KEY_LEFTCOL   '^'
+#define KEY_RIGHTCOL  '$'
+
+#define MIN_HIGH  (1 + (5 * MARGIN))
+
+typedef struct {
+    WINDOW *win;
+    int box_y;
+    int box_x;
+    int top_index;
+    int cur_index;
+} MY_DATA;
+
+typedef struct {
+    DIALOG_LISTITEM *items;
+    int base_y;                        /* base for mouse coordinates */
+    int base_x;
+    int use_height;            /* actual size of column box */
+    int use_width;
+    int item_no;
+    int check_x;
+    int item_x;
+    MY_DATA list[2];
+} ALL_DATA;
+
+/*
+ * Print list item.  The 'selected' parameter is true if 'choice' is the
+ * current item.  That one is colored differently from the other items.
+ */
+static void
+print_item(ALL_DATA * data,
+          WINDOW *win,
+          DIALOG_LISTITEM * item,
+          int choice,
+          int selected)
+{
+    chtype save = dlg_get_attrs(win);
+    int i;
+    bool both = (!dialog_vars.no_tags && !dialog_vars.no_items);
+    bool first = TRUE;
+    int climit = (data->item_x - data->check_x - 1);
+    const char *show = (dialog_vars.no_items
+                       ? item->name
+                       : item->text);
+
+    /* Clear 'residue' of last item */
+    (void) wattrset(win, menubox_attr);
+    (void) wmove(win, choice, 0);
+    for (i = 0; i < getmaxx(win); i++)
+       (void) waddch(win, ' ');
+
+    (void) wmove(win, choice, data->check_x);
+    (void) wattrset(win, menubox_attr);
+
+    if (both) {
+       dlg_print_listitem(win, item->name, climit, first, selected);
+       (void) waddch(win, ' ');
+       first = FALSE;
+    }
+
+    (void) wmove(win, choice, data->item_x);
+    climit = (getmaxx(win) - data->item_x + 1);
+    dlg_print_listitem(win, show, climit, first, selected);
+
+    if (selected) {
+       dlg_item_help(item->help);
+    }
+    (void) wattrset(win, save);
+}
+
+/*
+ * Prints either the left (unselected) or right (selected) list.
+ */
+static void
+print_1_list(ALL_DATA * data,
+            int choice,
+            int selected)
+{
+    MY_DATA *moi = data->list + selected;
+    WINDOW *win = moi->win;
+    int i, j;
+    int last = 0;
+    int max_rows = getmaxy(win);
+
+    for (i = j = 0; j < max_rows; i++) {
+       int ii = i + moi->top_index;
+       if (ii >= data->item_no) {
+           break;
+       } else if (!(selected ^ (data->items[ii].state != 0))) {
+           print_item(data,
+                      win,
+                      &data->items[ii],
+                      j, ii == choice);
+           last = ++j;
+       }
+    }
+    if (wmove(win, last, 0) != ERR)
+       wclrtobot(win);
+    (void) wnoutrefresh(win);
+}
+
+/*
+ * Return the previous item from the list, staying in the same column.  If no
+ * further movement is possible, return the same choice as given.
+ */
+static int
+prev_item(ALL_DATA * data, int choice, int selected)
+{
+    int result = choice;
+    int n;
+
+    for (n = choice - 1; n >= 0; --n) {
+       if ((data->items[n].state != 0) == selected) {
+           result = n;
+           break;
+       }
+    }
+    return result;
+}
+
+/*
+ * Return true if the given choice is on the first page in the current column.
+ */
+static bool
+stop_prev(ALL_DATA * data, int choice, int selected)
+{
+    return (prev_item(data, choice, selected) == choice);
+}
+
+static bool
+check_hotkey(DIALOG_LISTITEM * items, int choice, int selected)
+{
+    bool result = FALSE;
+
+    if ((items[choice].state != 0) == selected) {
+       if (dlg_match_char(dlg_last_getc(),
+                          (dialog_vars.no_tags
+                           ? items[choice].text
+                           : items[choice].name))) {
+           result = TRUE;
+       }
+    }
+    return result;
+}
+
+/*
+ * Return the next item from the list, staying in the same column.  If no
+ * further movement is possible, return the same choice as given.
+ */
+static int
+next_item(ALL_DATA * data, int choice, int selected)
+{
+    int result = choice;
+    int n;
+
+    for (n = choice + 1; n < data->item_no; ++n) {
+       if ((data->items[n].state != 0) == selected) {
+           result = n;
+           break;
+       }
+    }
+    dlg_trace_msg("next_item(%d) ->%d\n", choice, result);
+    return result;
+}
+
+/*
+ * Translate a choice from items[] to a row-number in an unbounded column,
+ * starting at zero.
+ */
+static int
+index2row(ALL_DATA * data, int choice, int selected)
+{
+    int result = -1;
+    int n;
+    for (n = 0; n < data->item_no; ++n) {
+       if ((data->items[n].state != 0) == selected) {
+           ++result;
+       }
+       if (n == choice)
+           break;
+    }
+    return result;
+}
+
+/*
+ * Return the first choice from items[] for the given column.
+ */
+static int
+first_item(ALL_DATA * data, int selected)
+{
+    int result = -1;
+    int n;
+
+    for (n = 0; n < data->item_no; ++n) {
+       if ((data->items[n].state != 0) == selected) {
+           result = n;
+           break;
+       }
+    }
+    return result;
+}
+
+/*
+ * Return the last choice from items[] for the given column.
+ */
+static int
+last_item(ALL_DATA * data, int selected)
+{
+    int result = -1;
+    int n;
+
+    for (n = data->item_no - 1; n >= 0; --n) {
+       if ((data->items[n].state != 0) == selected) {
+           result = n;
+           break;
+       }
+    }
+    return result;
+}
+
+/*
+ * Convert a row-number back to an item number, i.e., index into items[].
+ */
+static int
+row2index(ALL_DATA * data, int row, int selected)
+{
+    int result = -1;
+    int n;
+    for (n = 0; n < data->item_no; ++n) {
+       if ((data->items[n].state != 0) == selected) {
+           if (row-- <= 0) {
+               result = n;
+               break;
+           }
+       }
+    }
+    return result;
+}
+
+static int
+skip_rows(ALL_DATA * data, int row, int skip, int selected)
+{
+    int choice = row2index(data, row, selected);
+    int result = row;
+    int n;
+    if (skip > 0) {
+       for (n = choice + 1; n < data->item_no; ++n) {
+           if ((data->items[n].state != 0) == selected) {
+               ++result;
+               if (--skip <= 0)
+                   break;
+           }
+       }
+    } else if (skip < 0) {
+       for (n = choice - 1; n >= 0; --n) {
+           if ((data->items[n].state != 0) == selected) {
+               --result;
+               if (++skip >= 0)
+                   break;
+           }
+       }
+    }
+    return result;
+}
+
+/*
+ * Find the closest item in the given column starting with the given choice.
+ */
+static int
+closest_item(ALL_DATA * data, int choice, int selected)
+{
+    int prev = choice;
+    int next = choice;
+    int result = choice;
+    int n;
+
+    for (n = choice; n >= 0; --n) {
+       if ((data->items[n].state != 0) == selected) {
+           prev = n;
+           break;
+       }
+    }
+    for (n = choice; n < data->item_no; ++n) {
+       if ((data->items[n].state != 0) == selected) {
+           next = n;
+           break;
+       }
+    }
+    if (prev != choice) {
+       result = prev;
+       if (next != choice) {
+           if ((choice - prev) > (next - choice)) {
+               result = next;
+           }
+       }
+    } else if (next != choice) {
+       result = next;
+    }
+    return result;
+}
+
+static void
+print_both(ALL_DATA * data,
+          int choice)
+{
+    int selected;
+    int cur_y, cur_x;
+    WINDOW *dialog = wgetparent(data->list[0].win);
+
+    getyx(dialog, cur_y, cur_x);
+    for (selected = 0; selected < 2; ++selected) {
+       MY_DATA *moi = data->list + selected;
+       WINDOW *win = moi->win;
+       int thumb_top = index2row(data, moi->top_index, selected);
+       int thumb_max = index2row(data, -1, selected);
+       int thumb_end = thumb_top + getmaxy(win);
+
+       print_1_list(data, choice, selected);
+
+       dlg_mouse_setcode(selected * KEY_MAX);
+       dlg_draw_scrollbar(dialog,
+                          (long) (moi->top_index),
+                          (long) (thumb_top),
+                          (long) MIN(thumb_end, thumb_max),
+                          (long) thumb_max,
+                          moi->box_x + data->check_x,
+                          moi->box_x + getmaxx(win),
+                          moi->box_y,
+                          moi->box_y + getmaxy(win) + 1,
+                          menubox_border2_attr,
+                          menubox_border_attr);
+    }
+    (void) wmove(dialog, cur_y, cur_x);
+    dlg_mouse_setcode(0);
+}
+
+static void
+set_top_item(ALL_DATA * data, int value, int selected)
+{
+    if (value != data->list[selected].top_index) {
+       dlg_trace_msg("set top of %s column to %d\n",
+                     selected ? "right" : "left",
+                     value);
+       data->list[selected].top_index = value;
+    }
+}
+
+/*
+ * Adjust the top-index as needed to ensure that it and the given item are
+ * visible.
+ */
+static void
+fix_top_item(ALL_DATA * data, int cur_item, int selected)
+{
+    int top_item = data->list[selected].top_index;
+    int cur_row = index2row(data, cur_item, selected);
+    int top_row = index2row(data, top_item, selected);
+
+    if (cur_row < top_row) {
+       top_item = cur_item;
+    } else if ((cur_row - top_row) > data->use_height) {
+       top_item = row2index(data, cur_row + 1 - data->use_height, selected);
+    }
+    if (cur_row < data->use_height) {
+       top_item = row2index(data, 0, selected);
+    }
+    dlg_trace_msg("fix_top_item(cur_item %d, selected %d) ->top_item %d\n",
+                 cur_item, selected, top_item);
+    set_top_item(data, top_item, selected);
+}
+
+/*
+ * This is an alternate interface to 'buildlist' which allows the application
+ * to read the list item states back directly without putting them in the
+ * output buffer.
+ */
+int
+dlg_buildlist(const char *title,
+             const char *cprompt,
+             int height,
+             int width,
+             int list_height,
+             int item_no,
+             DIALOG_LISTITEM * items,
+             const char *states,
+             int order_mode,
+             int *current_item)
+{
+    /* *INDENT-OFF* */
+    static DLG_KEYS_BINDING binding[] = {
+       HELPKEY_BINDINGS,
+       ENTERKEY_BINDINGS,
+       DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ),
+       DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ),
+       DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ),
+       DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_LEFT ),
+       DLG_KEYS_DATA( DLGK_ITEM_FIRST, KEY_HOME ),
+       DLG_KEYS_DATA( DLGK_ITEM_LAST,  KEY_END ),
+       DLG_KEYS_DATA( DLGK_ITEM_LAST,  KEY_LL ),
+       DLG_KEYS_DATA( DLGK_ITEM_NEXT,  '+' ),
+       DLG_KEYS_DATA( DLGK_ITEM_NEXT,  KEY_DOWN ),
+       DLG_KEYS_DATA( DLGK_ITEM_NEXT,  CHR_NEXT ),
+       DLG_KEYS_DATA( DLGK_ITEM_PREV,  '-' ),
+       DLG_KEYS_DATA( DLGK_ITEM_PREV,  KEY_UP ),
+       DLG_KEYS_DATA( DLGK_ITEM_PREV,  CHR_PREVIOUS ),
+       DLG_KEYS_DATA( DLGK_PAGE_NEXT,  KEY_NPAGE ),
+       DLG_KEYS_DATA( DLGK_PAGE_NEXT,  DLGK_MOUSE(KEY_NPAGE) ),
+       DLG_KEYS_DATA( DLGK_PAGE_NEXT,  DLGK_MOUSE(KEY_NPAGE+KEY_MAX) ),
+       DLG_KEYS_DATA( DLGK_PAGE_PREV,  KEY_PPAGE ),
+       DLG_KEYS_DATA( DLGK_PAGE_PREV,  DLGK_MOUSE(KEY_PPAGE) ),
+       DLG_KEYS_DATA( DLGK_PAGE_PREV,  DLGK_MOUSE(KEY_PPAGE+KEY_MAX) ),
+       DLG_KEYS_DATA( DLGK_GRID_LEFT,  KEY_LEFTCOL ),
+       DLG_KEYS_DATA( DLGK_GRID_RIGHT, KEY_RIGHTCOL ),
+       END_KEYS_BINDING
+    };
+    /* *INDENT-ON* */
+
+#ifdef KEY_RESIZE
+    int old_height = height;
+    int old_width = width;
+#endif
+    ALL_DATA all;
+    MY_DATA *data = all.list;
+    int i, j, k, key2, found, x, y, cur_x, cur_y;
+    int key = 0, fkey;
+    bool save_visit = dialog_state.visit_items;
+    int button;
+    int cur_item;
+    int was_mouse;
+    int name_width, text_width, full_width, list_width;
+    int result = DLG_EXIT_UNKNOWN;
+    int num_states;
+    bool first = TRUE;
+    WINDOW *dialog;
+    char *prompt = dlg_strclone(cprompt);
+    const char **buttons = dlg_ok_labels();
+    const char *widget_name = "buildlist";
+
+    (void) order_mode;
+
+    /*
+     * Unlike other uses of --visit-items, we have two windows to visit.
+     */
+    if (dialog_state.visit_cols)
+       dialog_state.visit_cols = 2;
+
+    memset(&all, 0, sizeof(all));
+    all.items = items;
+    all.item_no = item_no;
+
+    if (dialog_vars.default_item != 0) {
+       cur_item = dlg_default_listitem(items);
+    } else {
+       if ((cur_item = first_item(&all, 0)) < 0)
+           cur_item = first_item(&all, 1);
+    }
+    button = (dialog_state.visit_items
+             ? (items[cur_item].state ? sRIGHT : sLEFT)
+             : dlg_default_button());
+
+    dlg_does_output();
+    dlg_tab_correct_str(prompt);
+
+#ifdef KEY_RESIZE
+  retry:
+#endif
+
+    all.use_height = list_height;
+    all.use_width = (2 * (dlg_calc_list_width(item_no, items)
+                         + 4
+                         + 2 * MARGIN)
+                    + 1);
+    all.use_width = MAX(26, all.use_width);
+    if (all.use_height == 0) {
+       /* calculate height without items (4) */
+       dlg_auto_size(title, prompt, &height, &width, MIN_HIGH, all.use_width);
+       dlg_calc_listh(&height, &all.use_height, item_no);
+    } else {
+       dlg_auto_size(title, prompt,
+                     &height, &width,
+                     MIN_HIGH + all.use_height, all.use_width);
+    }
+    dlg_button_layout(buttons, &width);
+    dlg_print_size(height, width);
+    dlg_ctl_size(height, width);
+
+    /* we need at least two states */
+    if (states == 0 || strlen(states) < 2)
+       states = " *";
+    num_states = (int) strlen(states);
+
+    x = dlg_box_x_ordinate(width);
+    y = dlg_box_y_ordinate(height);
+
+    dialog = dlg_new_window(height, width, y, x);
+    dlg_register_window(dialog, widget_name, binding);
+    dlg_register_buttons(dialog, widget_name, buttons);
+
+    dlg_mouse_setbase(all.base_x = x, all.base_y = y);
+
+    dlg_draw_box2(dialog, 0, 0, height, width, dialog_attr, border_attr, border2_attr);
+    dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr);
+    dlg_draw_title(dialog, title);
+
+    (void) wattrset(dialog, dialog_attr);
+    dlg_print_autowrap(dialog, prompt, height, width);
+
+    list_width = (width - 6 * MARGIN - 2) / 2;
+    getyx(dialog, cur_y, cur_x);
+    data[0].box_y = cur_y + 1;
+    data[0].box_x = MARGIN + 1;
+    data[1].box_y = cur_y + 1;
+    data[1].box_x = data[0].box_x + 1 + 2 * MARGIN + list_width;
+
+    /*
+     * After displaying the prompt, we know how much space we really have.
+     * Limit the list to avoid overwriting the ok-button.
+     */
+    if (all.use_height + MIN_HIGH > height - cur_y)
+       all.use_height = height - MIN_HIGH - cur_y;
+    if (all.use_height <= 0)
+       all.use_height = 1;
+
+    for (k = 0; k < 2; ++k) {
+       /* create new window for the list */
+       data[k].win = dlg_sub_window(dialog, all.use_height, list_width,
+                                    y + data[k].box_y + 1,
+                                    x + data[k].box_x + 1);
+
+       /* draw a box around the list items */
+       dlg_draw_box(dialog, data[k].box_y, data[k].box_x,
+                    all.use_height + 2 * MARGIN,
+                    list_width + 2 * MARGIN,
+                    menubox_border_attr, menubox_border2_attr);
+    }
+
+    text_width = 0;
+    name_width = 0;
+    /* Find length of longest item to center buildlist */
+    for (i = 0; i < item_no; i++) {
+       text_width = MAX(text_width, dlg_count_columns(items[i].text));
+       name_width = MAX(name_width, dlg_count_columns(items[i].name));
+    }
+
+    /* If the name+text is wider than the list is allowed, then truncate
+     * one or both of them.  If the name is no wider than 1/4 of the list,
+     * leave it intact.
+     */
+    all.use_width = (list_width - 6 * MARGIN);
+    if (dialog_vars.no_tags && !dialog_vars.no_items) {
+       full_width = MIN(all.use_width, text_width);
+    } else if (dialog_vars.no_items) {
+       full_width = MIN(all.use_width, name_width);
+    } else {
+       if (text_width >= 0
+           && name_width >= 0
+           && all.use_width > 0
+           && text_width + name_width > all.use_width) {
+           int need = (int) (0.25 * all.use_width);
+           if (name_width > need) {
+               int want = (int) (all.use_width * ((double) name_width) /
+                                 (text_width + name_width));
+               name_width = (want > need) ? want : need;
+           }
+           text_width = all.use_width - name_width;
+       }
+       full_width = text_width + name_width;
+    }
+
+    all.check_x = (all.use_width - full_width) / 2;
+    all.item_x = ((dialog_vars.no_tags
+                  ? 0
+                  : (dialog_vars.no_items
+                     ? 0
+                     : (name_width + 2)))
+                 + all.check_x);
+
+    /* ensure we are scrolled to show the current choice */
+    j = MIN(all.use_height, item_no);
+    for (i = 0; i < 2; ++i) {
+       int top_item = 0;
+       if ((items[cur_item].state != 0) == i) {
+           top_item = cur_item - j + 1;
+           if (top_item < 0)
+               top_item = 0;
+           set_top_item(&all, top_item, i);
+       } else {
+           set_top_item(&all, 0, i);
+       }
+    }
+
+    /* register the new window, along with its borders */
+    for (i = 0; i < 2; ++i) {
+       dlg_mouse_mkbigregion(data[i].box_y + 1,
+                             data[i].box_x,
+                             all.use_height,
+                             list_width + 2,
+                             2 * KEY_MAX + (i * (1 + all.use_height)),
+                             1, 1, 1 /* by lines */ );
+    }
+
+    dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width);
+
+    while (result == DLG_EXIT_UNKNOWN) {
+       int which = (items[cur_item].state != 0);
+       MY_DATA *moi = data + which;
+       int at_top = index2row(&all, moi->top_index, which);
+       int at_end = index2row(&all, -1, which);
+       int at_bot = skip_rows(&all, at_top, all.use_height, which);
+
+       dlg_trace_msg("\t** state %d:%d top %d (%d:%d:%d) %d\n",
+                     cur_item, item_no - 1,
+                     moi->top_index,
+                     at_top, at_bot, at_end,
+                     which);
+
+       if (first) {
+           print_both(&all, cur_item);
+           dlg_trace_win(dialog);
+           first = FALSE;
+       }
+
+       if (button < 0) {       /* --visit-items */
+           int cur_row = index2row(&all, cur_item, which);
+           cur_y = (data[which].box_y
+                    + cur_row
+                    + 1);
+           if (at_top > 0)
+               cur_y -= at_top;
+           cur_x = (data[which].box_x
+                    + all.check_x + 1);
+           dlg_trace_msg("\t...visit row %d (%d,%d)\n", cur_row, cur_y, cur_x);
+           wmove(dialog, cur_y, cur_x);
+       }
+
+       key = dlg_mouse_wgetch(dialog, &fkey);
+       if (dlg_result_key(key, fkey, &result))
+           break;
+
+       was_mouse = (fkey && is_DLGK_MOUSE(key));
+       if (was_mouse)
+           key -= M_EVENT;
+
+       if (!was_mouse) {
+           ;
+       } else if (key >= 2 * KEY_MAX) {
+           i = (key - 2 * KEY_MAX) % (1 + all.use_height);
+           j = (key - 2 * KEY_MAX) / (1 + all.use_height);
+           k = row2index(&all, i + at_top, j);
+           dlg_trace_msg("MOUSE column %d, row %d ->item %d\n", j, i, k);
+           if (k >= 0 && j < 2) {
+               if (j != which) {
+                   /*
+                    * Mouse click was in the other column.
+                    */
+                   moi = data + j;
+                   fix_top_item(&all, k, j);
+               }
+               which = j;
+               at_top = index2row(&all, moi->top_index, which);
+               at_bot = skip_rows(&all, at_top, all.use_height, which);
+               cur_item = k;
+               print_both(&all, cur_item);
+               key = KEY_TOGGLE;       /* force the selected item to toggle */
+           } else {
+               beep();
+               continue;
+           }
+           fkey = FALSE;
+       } else if (key >= KEY_MIN) {
+           if (key > KEY_MAX) {
+               if (which == 0) {
+                   key = KEY_RIGHTCOL;         /* switch to right-column */
+                   fkey = FALSE;
+               } else {
+                   key -= KEY_MAX;
+               }
+           } else {
+               if (which == 1) {
+                   key = KEY_LEFTCOL;  /* switch to left-column */
+                   fkey = FALSE;
+               }
+           }
+           key = dlg_lookup_key(dialog, key, &fkey);
+       }
+
+       /*
+        * A space toggles the item status.  Normally we put the cursor on
+        * the next available item in the same column.  But if there are no
+        * more items in the column, move the cursor to the other column.
+        */
+       if (key == KEY_TOGGLE) {
+           int new_choice;
+           int new_state = items[cur_item].state + 1;
+
+           if ((new_choice = next_item(&all, cur_item, which)) == cur_item) {
+               new_choice = prev_item(&all, cur_item, which);
+           }
+           dlg_trace_msg("cur_item %d, new_choice:%d\n", cur_item, new_choice);
+           if (new_state >= num_states)
+               new_state = 0;
+
+           items[cur_item].state = new_state;
+           if (cur_item == moi->top_index) {
+               set_top_item(&all, new_choice, which);
+           }
+
+           if (new_choice >= 0) {
+               fix_top_item(&all, cur_item, !which);
+               cur_item = new_choice;
+           }
+           print_both(&all, cur_item);
+           dlg_trace_win(dialog);
+           continue;           /* wait for another key press */
+       }
+
+       /*
+        * Check if key pressed matches first character of any item tag in
+        * list.  If there is more than one match, we will cycle through
+        * each one as the same key is pressed repeatedly.
+        */
+       found = FALSE;
+       if (!fkey) {
+           if (button < 0 || !dialog_state.visit_items) {
+               for (j = cur_item + 1; j < item_no; j++) {
+                   if (check_hotkey(items, j, which)) {
+                       found = TRUE;
+                       i = j;
+                       break;
+                   }
+               }
+               if (!found) {
+                   for (j = 0; j <= cur_item; j++) {
+                       if (check_hotkey(items, j, which)) {
+                           found = TRUE;
+                           i = j;
+                           break;
+                       }
+                   }
+               }
+               if (found)
+                   dlg_flush_getc();
+           } else if ((j = dlg_char_to_button(key, buttons)) >= 0) {
+               button = j;
+               ungetch('\n');
+               continue;
+           }
+       }
+
+       /*
+        * A single digit (1-9) positions the selection to that line in the
+        * current screen.
+        */
+       if (!found
+           && (key <= '9')
+           && (key > '0')
+           && (key - '1' < at_bot)) {
+           found = TRUE;
+           i = key - '1';
+       }
+
+       if (!found && fkey) {
+           switch (key) {
+           case DLGK_FIELD_PREV:
+               if ((button == sRIGHT) && dialog_state.visit_items) {
+                   key = DLGK_GRID_LEFT;
+                   button = sLEFT;
+               } else {
+                   button = dlg_prev_button(buttons, button);
+                   dlg_draw_buttons(dialog, height - 2, 0, buttons, button,
+                                    FALSE, width);
+                   if (button == sRIGHT) {
+                       key = DLGK_GRID_RIGHT;
+                   } else {
+                       continue;
+                   }
+               }
+               break;
+           case DLGK_FIELD_NEXT:
+               if ((button == sLEFT) && dialog_state.visit_items) {
+                   key = DLGK_GRID_RIGHT;
+                   button = sRIGHT;
+               } else {
+                   button = dlg_next_button(buttons, button);
+                   dlg_draw_buttons(dialog, height - 2, 0, buttons, button,
+                                    FALSE, width);
+                   if (button == sLEFT) {
+                       key = DLGK_GRID_LEFT;
+                   } else {
+                       continue;
+                   }
+               }
+               break;
+           }
+       }
+
+       if (!found && fkey) {
+           i = cur_item;
+           found = TRUE;
+           switch (key) {
+           case DLGK_GRID_LEFT:
+               i = closest_item(&all, cur_item, 0);
+               fix_top_item(&all, i, 0);
+               break;
+           case DLGK_GRID_RIGHT:
+               i = closest_item(&all, cur_item, 1);
+               fix_top_item(&all, i, 1);
+               break;
+           case DLGK_PAGE_PREV:
+               if (cur_item > moi->top_index) {
+                   i = moi->top_index;
+               } else if (moi->top_index != 0) {
+                   int temp = at_top;
+                   if ((temp -= all.use_height) < 0)
+                       temp = 0;
+                   i = row2index(&all, temp, which);
+               }
+               break;
+           case DLGK_PAGE_NEXT:
+               if ((at_end - at_bot) < all.use_height) {
+                   i = next_item(&all,
+                                 row2index(&all, at_end, which),
+                                 which);
+               } else {
+                   i = next_item(&all,
+                                 row2index(&all, at_bot, which),
+                                 which);
+                   at_top = at_bot;
+                   set_top_item(&all,
+                                next_item(&all,
+                                          row2index(&all, at_top, which),
+                                          which),
+                                which);
+                   at_bot = skip_rows(&all, at_top, all.use_height, which);
+                   at_bot = MIN(at_bot, at_end);
+               }
+               break;
+           case DLGK_ITEM_FIRST:
+               i = first_item(&all, which);
+               break;
+           case DLGK_ITEM_LAST:
+               i = last_item(&all, which);
+               break;
+           case DLGK_ITEM_PREV:
+               i = prev_item(&all, cur_item, which);
+               if (stop_prev(&all, cur_item, which))
+                   continue;
+               break;
+           case DLGK_ITEM_NEXT:
+               i = next_item(&all, cur_item, which);
+               break;
+           default:
+               found = FALSE;
+               break;
+           }
+       }
+
+       if (found) {
+           if (i != cur_item) {
+               int now_at = index2row(&all, i, which);
+               int oops = item_no;
+               int old_item;
+
+               dlg_trace_msg("<--CHOICE %d\n", i);
+               dlg_trace_msg("<--topITM %d\n", moi->top_index);
+               dlg_trace_msg("<--now_at %d\n", now_at);
+               dlg_trace_msg("<--at_top %d\n", at_top);
+               dlg_trace_msg("<--at_bot %d\n", at_bot);
+
+               if (now_at >= at_bot) {
+                   while (now_at >= at_bot) {
+                       if ((at_bot - at_top) >= all.use_height) {
+                           set_top_item(&all,
+                                        next_item(&all, moi->top_index, which),
+                                        which);
+                       }
+                       at_top = index2row(&all, moi->top_index, which);
+                       at_bot = skip_rows(&all, at_top, all.use_height, which);
+
+                       dlg_trace_msg("...at_bot %d (now %d vs %d)\n",
+                                     at_bot, now_at, at_end);
+                       dlg_trace_msg("...topITM %d\n", moi->top_index);
+                       dlg_trace_msg("...at_top %d (diff %d)\n", at_top,
+                                     at_bot - at_top);
+
+                       if (at_bot >= at_end) {
+                           /*
+                            * If we bumped into the end, move the top-item
+                            * down by one line so that we can display the
+                            * last item in the list.
+                            */
+                           if ((at_bot - at_top) > all.use_height) {
+                               set_top_item(&all,
+                                            next_item(&all, moi->top_index, which),
+                                            which);
+                           } else if (at_top > 0 &&
+                                      (at_bot - at_top) >= all.use_height) {
+                               set_top_item(&all,
+                                            next_item(&all, moi->top_index, which),
+                                            which);
+                           }
+                           break;
+                       }
+                       if (--oops < 0) {
+                           dlg_trace_msg("OOPS-forward\n");
+                           break;
+                       }
+                   }
+               } else if (now_at < at_top) {
+                   while (now_at < at_top) {
+                       old_item = moi->top_index;
+                       set_top_item(&all,
+                                    prev_item(&all, moi->top_index, which),
+                                    which);
+                       at_top = index2row(&all, moi->top_index, which);
+
+                       dlg_trace_msg("...at_top %d (now %d)\n", at_top, now_at);
+                       dlg_trace_msg("...topITM %d\n", moi->top_index);
+
+                       if (moi->top_index >= old_item)
+                           break;
+                       if (at_top <= now_at)
+                           break;
+                       if (--oops < 0) {
+                           dlg_trace_msg("OOPS-backward\n");
+                           break;
+                       }
+                   }
+               }
+               dlg_trace_msg("-->now_at %d\n", now_at);
+               cur_item = i;
+               print_both(&all, cur_item);
+           }
+           dlg_trace_win(dialog);
+           continue;           /* wait for another key press */
+       }
+
+       if (fkey) {
+           switch (key) {
+           case DLGK_ENTER:
+               result = dlg_enter_buttoncode(button);
+               break;
+#ifdef KEY_RESIZE
+           case KEY_RESIZE:
+               /* reset data */
+               height = old_height;
+               width = old_width;
+               /* repaint */
+               dlg_clear();
+               dlg_del_window(dialog);
+               refresh();
+               dlg_mouse_free_regions();
+               goto retry;
+#endif
+           default:
+               if (was_mouse) {
+                   if ((key2 = dlg_ok_buttoncode(key)) >= 0) {
+                       result = key2;
+                       break;
+                   }
+                   beep();
+               }
+           }
+       } else {
+           beep();
+       }
+    }
+
+    dialog_state.visit_cols = save_visit;
+    dlg_del_window(dialog);
+    dlg_mouse_free_regions();
+    free(prompt);
+    *current_item = cur_item;
+    return result;
+}
+
+/*
+ * Display a dialog box with a list of options that can be turned on or off
+ */
+int
+dialog_buildlist(const char *title,
+                const char *cprompt,
+                int height,
+                int width,
+                int list_height,
+                int item_no,
+                char **items,
+                int order_mode)
+{
+    int result;
+    int i, j;
+    DIALOG_LISTITEM *listitems;
+    bool separate_output = dialog_vars.separate_output;
+    bool show_status = FALSE;
+    int current = 0;
+
+    listitems = dlg_calloc(DIALOG_LISTITEM, (size_t) item_no + 1);
+    assert_ptr(listitems, "dialog_buildlist");
+
+    for (i = j = 0; i < item_no; ++i) {
+       listitems[i].name = items[j++];
+       listitems[i].text = (dialog_vars.no_items
+                            ? dlg_strempty()
+                            : items[j++]);
+       listitems[i].state = !dlg_strcmp(items[j++], "on");
+       listitems[i].help = ((dialog_vars.item_help)
+                            ? items[j++]
+                            : dlg_strempty());
+    }
+    dlg_align_columns(&listitems[0].text, (int) sizeof(DIALOG_LISTITEM), item_no);
+
+    result = dlg_buildlist(title,
+                          cprompt,
+                          height,
+                          width,
+                          list_height,
+                          item_no,
+                          listitems,
+                          NULL,
+                          order_mode,
+                          &current);
+
+    switch (result) {
+    case DLG_EXIT_OK:          /* FALLTHRU */
+    case DLG_EXIT_EXTRA:
+       show_status = TRUE;
+       break;
+    case DLG_EXIT_HELP:
+       dlg_add_result("HELP ");
+       show_status = dialog_vars.help_status;
+       if (USE_ITEM_HELP(listitems[current].help)) {
+           if (show_status) {
+               if (separate_output) {
+                   dlg_add_string(listitems[current].help);
+                   dlg_add_separator();
+               } else {
+                   dlg_add_quoted(listitems[current].help);
+               }
+           } else {
+               dlg_add_string(listitems[current].help);
+           }
+           result = DLG_EXIT_ITEM_HELP;
+       } else {
+           if (show_status) {
+               if (separate_output) {
+                   dlg_add_string(listitems[current].name);
+                   dlg_add_separator();
+               } else {
+                   dlg_add_quoted(listitems[current].name);
+               }
+           } else {
+               dlg_add_string(listitems[current].name);
+           }
+       }
+       break;
+    }
+
+    if (show_status) {
+       for (i = 0; i < item_no; i++) {
+           if (listitems[i].state) {
+               if (separate_output) {
+                   dlg_add_string(listitems[i].name);
+                   dlg_add_separator();
+               } else {
+                   if (dlg_need_separator())
+                       dlg_add_separator();
+                   dlg_add_quoted(listitems[i].name);
+               }
+           }
+       }
+    }
+
+    dlg_free_columns(&listitems[0].text, (int) sizeof(DIALOG_LISTITEM), item_no);
+    free(listitems);
+    return result;
+}
diff --git a/contrib/dialog/buttons.c b/contrib/dialog/buttons.c
new file mode 100644 (file)
index 0000000..d37cfe5
--- /dev/null
@@ -0,0 +1,789 @@
+/*
+ *  $Id: buttons.c,v 1.94 2012/12/30 20:51:01 tom Exp $
+ *
+ *  buttons.c -- draw buttons, e.g., OK/Cancel
+ *
+ *  Copyright 2000-2011,2012   Thomas E. Dickey
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License, version 2.1
+ *  as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to
+ *     Free Software Foundation, Inc.
+ *     51 Franklin St., Fifth Floor
+ *     Boston, MA 02110, USA.
+ */
+
+#include <dialog.h>
+#include <dlg_keys.h>
+
+#ifdef NEED_WCHAR_H
+#include <wchar.h>
+#endif
+
+#define MIN_BUTTON (-dialog_state.visit_cols)
+
+static void
+center_label(char *buffer, int longest, const char *label)
+{
+    int len = dlg_count_columns(label);
+    int left = 0, right = 0;
+
+    *buffer = 0;
+    if (len < longest) {
+       left = (longest - len) / 2;
+       right = (longest - len - left);
+       if (left > 0)
+           sprintf(buffer, "%*s", left, " ");
+    }
+    strcat(buffer, label);
+    if (right > 0)
+       sprintf(buffer + strlen(buffer), "%*s", right, " ");
+}
+
+/*
+ * Parse a multibyte character out of the string, set it past the parsed
+ * character.
+ */
+static int
+string_to_char(const char **stringp)
+{
+    int result;
+#ifdef USE_WIDE_CURSES
+    const char *string = *stringp;
+    size_t have = strlen(string);
+    size_t check;
+    size_t len;
+    wchar_t cmp2[2];
+    mbstate_t state;
+
+    memset(&state, 0, sizeof(state));
+    len = mbrlen(string, have, &state);
+    if ((int) len > 0 && len <= have) {
+       memset(&state, 0, sizeof(state));
+       memset(cmp2, 0, sizeof(cmp2));
+       check = mbrtowc(cmp2, string, len, &state);
+       if ((int) check <= 0)
+           cmp2[0] = 0;
+       *stringp += len;
+    } else {
+       cmp2[0] = UCH(*string);
+       *stringp += 1;
+    }
+    result = cmp2[0];
+#else
+    const char *string = *stringp;
+    result = UCH(*string);
+    *stringp += 1;
+#endif
+    return result;
+}
+
+static size_t
+count_labels(const char **labels)
+{
+    size_t result = 0;
+    if (labels != 0) {
+       while (*labels++ != 0) {
+           ++result;
+       }
+    }
+    return result;
+}
+
+/*
+ * Check if the latest key should be added to the hotkey list.
+ */
+static int
+was_hotkey(int this_key, int *used_keys, size_t next)
+{
+    int result = FALSE;
+
+    if (next != 0) {
+       size_t n;
+       for (n = 0; n < next; ++n) {
+           if (used_keys[n] == this_key) {
+               result = TRUE;
+               break;
+           }
+       }
+    }
+    return result;
+}
+
+/*
+ * Determine the hot-keys for a set of button-labels.  Normally these are
+ * the first uppercase character in each label.  However, if more than one
+ * button has the same first-uppercase, then we will (attempt to) look for
+ * an alternate.
+ *
+ * This allocates data which must be freed by the caller.
+ */
+static int *
+get_hotkeys(const char **labels)
+{
+    int *result = 0;
+    size_t count = count_labels(labels);
+    size_t n;
+
+    if ((result = dlg_calloc(int, count + 1)) != 0) {
+       for (n = 0; n < count; ++n) {
+           const char *label = labels[n];
+           const int *indx = dlg_index_wchars(label);
+           int limit = dlg_count_wchars(label);
+           int i;
+
+           for (i = 0; i < limit; ++i) {
+               int first = indx[i];
+               int check = UCH(label[first]);
+#ifdef USE_WIDE_CURSES
+               int last = indx[i + 1];
+               if ((last - first) != 1) {
+                   const char *temp = (label + first);
+                   check = string_to_char(&temp);
+               }
+#endif
+               if (dlg_isupper(check) && !was_hotkey(check, result, n)) {
+                   result[n] = check;
+                   break;
+               }
+           }
+       }
+    }
+    return result;
+}
+
+/*
+ * Print a button
+ */
+static void
+print_button(WINDOW *win, char *label, int hotkey, int y, int x, int selected)
+{
+    int i;
+    int state = 0;
+    const int *indx = dlg_index_wchars(label);
+    int limit = dlg_count_wchars(label);
+    chtype key_attr = (selected
+                      ? button_key_active_attr
+                      : button_key_inactive_attr);
+    chtype label_attr = (selected
+                        ? button_label_active_attr
+                        : button_label_inactive_attr);
+
+    (void) wmove(win, y, x);
+    (void) wattrset(win, selected
+                   ? button_active_attr
+                   : button_inactive_attr);
+    (void) waddstr(win, "<");
+    (void) wattrset(win, label_attr);
+    for (i = 0; i < limit; ++i) {
+       int check;
+       int first = indx[i];
+       int last = indx[i + 1];
+
+       switch (state) {
+       case 0:
+           check = UCH(label[first]);
+#ifdef USE_WIDE_CURSES
+           if ((last - first) != 1) {
+               const char *temp = (label + first);
+               check = string_to_char(&temp);
+           }
+#endif
+           if (check == hotkey) {
+               (void) wattrset(win, key_attr);
+               state = 1;
+           }
+           break;
+       case 1:
+           wattrset(win, label_attr);
+           state = 2;
+           break;
+       }
+       waddnstr(win, label + first, last - first);
+    }
+    (void) wattrset(win, selected
+                   ? button_active_attr
+                   : button_inactive_attr);
+    (void) waddstr(win, ">");
+    (void) wmove(win, y, x + ((int) strspn(label, " ")) + 1);
+}
+
+/*
+ * Count the buttons in the list.
+ */
+int
+dlg_button_count(const char **labels)
+{
+    int result = 0;
+    while (*labels++ != 0)
+       ++result;
+    return result;
+}
+
+/*
+ * Compute the size of the button array in columns.  Return the total number of
+ * columns in *length, and the longest button's columns in *longest
+ */
+void
+dlg_button_sizes(const char **labels,
+                int vertical,
+                int *longest,
+                int *length)
+{
+    int n;
+
+    *length = 0;
+    *longest = 0;
+    for (n = 0; labels[n] != 0; n++) {
+       if (vertical) {
+           *length += 1;
+           *longest = 1;
+       } else {
+           int len = dlg_count_columns(labels[n]);
+           if (len > *longest)
+               *longest = len;
+           *length += len;
+       }
+    }
+    /*
+     * If we can, make all of the buttons the same size.  This is only optional
+     * for buttons laid out horizontally.
+     */
+    if (*longest < 6 - (*longest & 1))
+       *longest = 6 - (*longest & 1);
+    if (!vertical)
+       *length = *longest * n;
+}
+
+/*
+ * Compute the size of the button array.
+ */
+int
+dlg_button_x_step(const char **labels, int limit, int *gap, int *margin, int *step)
+{
+    int count = dlg_button_count(labels);
+    int longest;
+    int length;
+    int unused;
+    int used;
+    int result;
+
+    *margin = 0;
+    if (count != 0) {
+       dlg_button_sizes(labels, FALSE, &longest, &length);
+       used = (length + (count * 2));
+       unused = limit - used;
+
+       if ((*gap = unused / (count + 3)) <= 0) {
+           if ((*gap = unused / (count + 1)) <= 0)
+               *gap = 1;
+           *margin = *gap;
+       } else {
+           *margin = *gap * 2;
+       }
+       *step = *gap + (used + count - 1) / count;
+       result = (*gap > 0) && (unused >= 0);
+    } else {
+       result = 0;
+    }
+    return result;
+}
+
+/*
+ * Make sure there is enough space for the buttons
+ */
+void
+dlg_button_layout(const char **labels, int *limit)
+{
+    int width = 1;
+    int gap, margin, step;
+
+    if (labels != 0 && dlg_button_count(labels)) {
+       while (!dlg_button_x_step(labels, width, &gap, &margin, &step))
+           ++width;
+       width += (4 * MARGIN);
+       if (width > COLS)
+           width = COLS;
+       if (width > *limit)
+           *limit = width;
+    }
+}
+
+/*
+ * Print a list of buttons at the given position.
+ */
+void
+dlg_draw_buttons(WINDOW *win,
+                int y, int x,
+                const char **labels,
+                int selected,
+                int vertical,
+                int limit)
+{
+    chtype save = dlg_get_attrs(win);
+    int n;
+    int step = 0;
+    int length;
+    int longest;
+    int final_x;
+    int final_y;
+    int gap;
+    int margin;
+    size_t need;
+    char *buffer;
+
+    dlg_mouse_setbase(getbegx(win), getbegy(win));
+
+    getyx(win, final_y, final_x);
+
+    dlg_button_sizes(labels, vertical, &longest, &length);
+
+    if (vertical) {
+       y += 1;
+       step = 1;
+    } else {
+       dlg_button_x_step(labels, limit, &gap, &margin, &step);
+       x += margin;
+    }
+
+    /*
+     * Allocate a buffer big enough for any label.
+     */
+    need = (size_t) longest;
+    if (need != 0) {
+       int *hotkeys = get_hotkeys(labels);
+       assert_ptr(hotkeys, "dlg_draw_buttons");
+
+       for (n = 0; labels[n] != 0; ++n) {
+           need += strlen(labels[n]) + 1;
+       }
+       buffer = dlg_malloc(char, need);
+       assert_ptr(buffer, "dlg_draw_buttons");
+
+       /*
+        * Draw the labels.
+        */
+       for (n = 0; labels[n] != 0; n++) {
+           center_label(buffer, longest, labels[n]);
+           mouse_mkbutton(y, x, dlg_count_columns(buffer), n);
+           print_button(win, buffer, hotkeys[n], y, x,
+                        (selected == n) || (n == 0 && selected < 0));
+           if (selected == n)
+               getyx(win, final_y, final_x);
+
+           if (vertical) {
+               if ((y += step) > limit)
+                   break;
+           } else {
+               if ((x += step) > limit)
+                   break;
+           }
+       }
+       (void) wmove(win, final_y, final_x);
+       wrefresh(win);
+       (void) wattrset(win, save);
+       free(buffer);
+       free(hotkeys);
+    }
+}
+
+/*
+ * Match a given character against the beginning of the string, ignoring case
+ * of the given character.  The matching string must begin with an uppercase
+ * character.
+ */
+int
+dlg_match_char(int ch, const char *string)
+{
+    if (string != 0) {
+       int cmp2 = string_to_char(&string);
+#ifdef USE_WIDE_CURSES
+       wint_t cmp1 = dlg_toupper(ch);
+       if (cmp2 != 0 && (wchar_t) cmp1 == (wchar_t) dlg_toupper(cmp2)) {
+           return TRUE;
+       }
+#else
+       if (ch > 0 && ch < 256) {
+           if (dlg_toupper(ch) == dlg_toupper(cmp2))
+               return TRUE;
+       }
+#endif
+    }
+    return FALSE;
+}
+
+/*
+ * Find the first uppercase character in the label, which we may use for an
+ * abbreviation.
+ */
+int
+dlg_button_to_char(const char *label)
+{
+    int cmp = -1;
+
+    while (*label != 0) {
+       cmp = string_to_char(&label);
+       if (dlg_isupper(cmp)) {
+           break;
+       }
+    }
+    return cmp;
+}
+
+/*
+ * Given a list of button labels, and a character which may be the abbreviation
+ * for one, find it, if it exists.  An abbreviation will be the first character
+ * which happens to be capitalized in the label.
+ */
+int
+dlg_char_to_button(int ch, const char **labels)
+{
+    int result = DLG_EXIT_UNKNOWN;
+
+    if (labels != 0) {
+       int *hotkeys = get_hotkeys(labels);
+       int j;
+
+       ch = (int) dlg_toupper(dlg_last_getc());
+
+       if (hotkeys != 0) {
+           for (j = 0; labels[j] != 0; ++j) {
+               if (ch == hotkeys[j]) {
+                   dlg_flush_getc();
+                   result = j;
+                   break;
+               }
+           }
+           free(hotkeys);
+       }
+    }
+
+    return result;
+}
+
+static const char *
+my_yes_label(void)
+{
+    return (dialog_vars.yes_label != NULL)
+       ? dialog_vars.yes_label
+       : _("Yes");
+}
+
+static const char *
+my_no_label(void)
+{
+    return (dialog_vars.no_label != NULL)
+       ? dialog_vars.no_label
+       : _("No");
+}
+
+static const char *
+my_ok_label(void)
+{
+    return (dialog_vars.ok_label != NULL)
+       ? dialog_vars.ok_label
+       : _("OK");
+}
+
+static const char *
+my_cancel_label(void)
+{
+    return (dialog_vars.cancel_label != NULL)
+       ? dialog_vars.cancel_label
+       : _("Cancel");
+}
+
+static const char *
+my_exit_label(void)
+{
+    return (dialog_vars.exit_label != NULL)
+       ? dialog_vars.exit_label
+       : _("EXIT");
+}
+
+static const char *
+my_extra_label(void)
+{
+    return (dialog_vars.extra_label != NULL)
+       ? dialog_vars.extra_label
+       : _("Extra");
+}
+
+static const char *
+my_help_label(void)
+{
+    return (dialog_vars.help_label != NULL)
+       ? dialog_vars.help_label
+       : _("Help");
+}
+
+/*
+ * Return a list of button labels.
+ */
+const char **
+dlg_exit_label(void)
+{
+    const char **result;
+    DIALOG_VARS save;
+
+    if (dialog_vars.extra_button) {
+       dlg_save_vars(&save);
+       dialog_vars.nocancel = TRUE;
+       result = dlg_ok_labels();
+       dlg_restore_vars(&save);
+    } else {
+       static const char *labels[3];
+       int n = 0;
+
+       if (!dialog_vars.nook)
+           labels[n++] = my_exit_label();
+       if (dialog_vars.help_button)
+           labels[n++] = my_help_label();
+       if (n == 0)
+           labels[n++] = my_exit_label();
+       labels[n] = 0;
+
+       result = labels;
+    }
+    return result;
+}
+
+/*
+ * Map the given button index for dlg_exit_label() into our exit-code.
+ */
+int
+dlg_exit_buttoncode(int button)
+{
+    int result;
+    DIALOG_VARS save;
+
+    dlg_save_vars(&save);
+    dialog_vars.nocancel = TRUE;
+
+    result = dlg_ok_buttoncode(button);
+
+    dlg_restore_vars(&save);
+
+    return result;
+}
+
+const char **
+dlg_ok_label(void)
+{
+    static const char *labels[4];
+    int n = 0;
+
+    labels[n++] = my_ok_label();
+    if (dialog_vars.extra_button)
+       labels[n++] = my_extra_label();
+    if (dialog_vars.help_button)
+       labels[n++] = my_help_label();
+    labels[n] = 0;
+    return labels;
+}
+
+/*
+ * Return a list of button labels for the OK/Cancel group.
+ */
+const char **
+dlg_ok_labels(void)
+{
+    static const char *labels[5];
+    int n = 0;
+
+    if (!dialog_vars.nook)
+       labels[n++] = my_ok_label();
+    if (dialog_vars.extra_button)
+       labels[n++] = my_extra_label();
+    if (!dialog_vars.nocancel)
+       labels[n++] = my_cancel_label();
+    if (dialog_vars.help_button)
+       labels[n++] = my_help_label();
+    labels[n] = 0;
+    return labels;
+}
+
+/*
+ * Map the given button index for dlg_ok_labels() into our exit-code
+ */
+int
+dlg_ok_buttoncode(int button)
+{
+    int result = DLG_EXIT_ERROR;
+    int n = !dialog_vars.nook;
+
+    if (!dialog_vars.nook && (button <= 0)) {
+       result = DLG_EXIT_OK;
+    } else if (dialog_vars.extra_button && (button == n++)) {
+       result = DLG_EXIT_EXTRA;
+    } else if (!dialog_vars.nocancel && (button == n++)) {
+       result = DLG_EXIT_CANCEL;
+    } else if (dialog_vars.help_button && (button == n)) {
+       result = DLG_EXIT_HELP;
+    }
+    dlg_trace_msg("# dlg_ok_buttoncode(%d) = %d\n", button, result);
+    return result;
+}
+
+/*
+ * Given that we're using dlg_ok_labels() to list buttons, find the next index
+ * in the list of buttons.  The 'extra' parameter if negative provides a way to
+ * enumerate extra active areas on the widget.
+ */
+int
+dlg_next_ok_buttonindex(int current, int extra)
+{
+    int result = current + 1;
+
+    if (current >= 0
+       && dlg_ok_buttoncode(result) < 0)
+       result = extra;
+    return result;
+}
+
+/*
+ * Similarly, find the previous button index.
+ */
+int
+dlg_prev_ok_buttonindex(int current, int extra)
+{
+    int result = current - 1;
+
+    if (result < extra) {
+       for (result = 0; dlg_ok_buttoncode(result + 1) >= 0; ++result) {
+           ;
+       }
+    }
+    return result;
+}
+
+/*
+ * Find the button-index for the "OK" or "Cancel" button, according to
+ * whether --defaultno is given.  If --nocancel was given, we always return
+ * the index for the first button (usually "OK" unless --nook was used).
+ */
+int
+dlg_defaultno_button(void)
+{
+    int result = 0;
+
+    if (dialog_vars.defaultno && !dialog_vars.nocancel) {
+       while (dlg_ok_buttoncode(result) != DLG_EXIT_CANCEL)
+           ++result;
+    }
+    dlg_trace_msg("# dlg_defaultno_button() = %d\n", result);
+    return result;
+}
+
+/*
+ * Find the button-index for a button named with --default-button. If the
+ * option was not specified, or if the selected button does not exist, return
+ * the index of the first button (usually "OK" unless --nook was used).
+ */
+int
+dlg_default_button(void)
+{
+    int i, n;
+    int result = 0;
+
+    if (dialog_vars.default_button >= 0) {
+       for (i = 0; (n = dlg_ok_buttoncode(i)) >= 0; i++) {
+           if (n == dialog_vars.default_button) {
+               result = i;
+               break;
+           }
+       }
+    }
+    dlg_trace_msg("# dlg_default_button() = %d\n", result);
+    return result;
+}
+
+/*
+ * Return a list of buttons for Yes/No labels.
+ */
+const char **
+dlg_yes_labels(void)
+{
+    const char **result;
+
+    if (dialog_vars.extra_button) {
+       result = dlg_ok_labels();
+    } else {
+       static const char *labels[4];
+       int n = 0;
+
+       labels[n++] = my_yes_label();
+       labels[n++] = my_no_label();
+       if (dialog_vars.help_button)
+           labels[n++] = my_help_label();
+       labels[n] = 0;
+
+       result = labels;
+    }
+
+    return result;
+}
+
+/*
+ * Map the given button index for dlg_yes_labels() into our exit-code.
+ */
+int
+dlg_yes_buttoncode(int button)
+{
+    int result = DLG_EXIT_ERROR;
+
+    if (dialog_vars.extra_button) {
+       result = dlg_ok_buttoncode(button);
+    } else if (button == 0) {
+       result = DLG_EXIT_OK;
+    } else if (button == 1) {
+       result = DLG_EXIT_CANCEL;
+    } else if (button == 2 && dialog_vars.help_button) {
+       result = DLG_EXIT_HELP;
+    }
+
+    return result;
+}
+
+/*
+ * Return the next index in labels[];
+ */
+int
+dlg_next_button(const char **labels, int button)
+{
+    if (button < -1)
+       button = -1;
+
+    if (labels[button + 1] != 0) {
+       ++button;
+    } else {
+       button = MIN_BUTTON;
+    }
+    return button;
+}
+
+/*
+ * Return the previous index in labels[];
+ */
+int
+dlg_prev_button(const char **labels, int button)
+{
+    if (button > MIN_BUTTON) {
+       --button;
+    } else {
+       if (button < -1)
+           button = -1;
+
+       while (labels[button + 1] != 0)
+           ++button;
+    }
+    return button;
+}
diff --git a/contrib/dialog/calendar.c b/contrib/dialog/calendar.c
new file mode 100644 (file)
index 0000000..dab4617
--- /dev/null
@@ -0,0 +1,686 @@
+/*
+ * $Id: calendar.c,v 1.66 2012/07/01 18:13:07 Zoltan.Kelemen Exp $
+ *
+ *  calendar.c -- implements the calendar box
+ *
+ *  Copyright 2001-2011,2012   Thomas E. Dickey
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License, version 2.1
+ *  as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to
+ *     Free Software Foundation, Inc.
+ *     51 Franklin St., Fifth Floor
+ *     Boston, MA 02110, USA.
+ */
+
+#include <dialog.h>
+#include <dlg_keys.h>
+
+#include <time.h>
+
+#define ONE_DAY  (60 * 60 * 24)
+
+#define MON_WIDE 4             /* width of a month-name */
+#define DAY_HIGH 6             /* maximum lines in day-grid */
+#define DAY_WIDE (8 * MON_WIDE)        /* width of the day-grid */
+#define HDR_HIGH 1             /* height of cells with month/year */
+#define BTN_HIGH 1             /* height of button-row excluding margin */
+
+/* two more lines: titles for day-of-week and month/year boxes */
+#define MIN_HIGH (DAY_HIGH + 2 + HDR_HIGH + BTN_HIGH + (7 * MARGIN))
+#define MIN_WIDE (DAY_WIDE + (4 * MARGIN))
+
+typedef enum {
+    sMONTH = -3
+    ,sYEAR = -2
+    ,sDAY = -1
+} STATES;
+
+struct _box;
+
+typedef int (*BOX_DRAW) (struct _box *, struct tm *);
+
+typedef struct _box {
+    WINDOW *parent;
+    WINDOW *window;
+    int x;
+    int y;
+    int width;
+    int height;
+    BOX_DRAW box_draw;
+} BOX;
+
+static const char *
+nameOfDayOfWeek(int n)
+{
+    static const char *table[7]
+#ifndef ENABLE_NLS
+    =
+    {
+       "Sunday",
+       "Monday",
+       "Tuesday",
+       "Wednesday",
+       "Thursday",
+       "Friday",
+       "Saturday"
+    }
+#endif
+     ;
+    const char *result = 0;
+
+    if (n >= 0 && n < 7) {
+#ifdef ENABLE_NLS
+       if (table[n] == 0) {
+           nl_item items[7] =
+           {
+               ABDAY_1, ABDAY_2, ABDAY_3, ABDAY_4, ABDAY_5, ABDAY_6, ABDAY_7
+           };
+           table[n] = nl_langinfo(items[n]);
+       }
+#endif
+       result = table[n];
+    }
+    if (result == 0) {
+       result = "?";
+    }
+    return result;
+}
+
+static const char *
+nameOfMonth(int n)
+{
+    static const char *table[12]
+#ifndef ENABLE_NLS
+    =
+    {
+       "January",
+       "February",
+       "March",
+       "April",
+       "May",
+       "June",
+       "July",
+       "August",
+       "September",
+       "October",
+       "November",
+       "December"
+    }
+#endif
+     ;
+    const char *result = 0;
+
+    if (n >= 0 && n < 12) {
+#ifdef ENABLE_NLS
+       if (table[n] == 0) {
+           nl_item items[12] =
+           {
+               MON_1, MON_2, MON_3, MON_4, MON_5, MON_6,
+               MON_7, MON_8, MON_9, MON_10, MON_11, MON_12
+           };
+           table[n] = nl_langinfo(items[n]);
+       }
+#endif
+       result = table[n];
+    }
+    if (result == 0) {
+       result = "?";
+    }
+    return result;
+}
+
+static int
+days_in_month(struct tm *current, int offset /* -1, 0, 1 */ )
+{
+    static const int nominal[] =
+    {
+       31, 28, 31, 30, 31, 30,
+       31, 31, 30, 31, 30, 31
+    };
+    int year = current->tm_year;
+    int month = current->tm_mon + offset;
+    int result;
+
+    while (month < 0) {
+       month += 12;
+       year -= 1;
+    }
+    while (month >= 12) {
+       month -= 12;
+       year += 1;
+    }
+    result = nominal[month];
+    if (month == 1)
+       result += ((year % 4) == 0);
+    return result;
+}
+
+static int
+days_in_year(struct tm *current, int offset /* -1, 0, 1 */ )
+{
+    int year = current->tm_year + 1900 + offset;
+
+    return ((year % 4) == 0) ? 366 : 365;
+}
+
+static int
+day_cell_number(struct tm *current)
+{
+    int cell;
+    cell = current->tm_mday - ((6 + current->tm_mday - current->tm_wday) % 7);
+    if ((current->tm_mday - 1) % 7 != current->tm_wday)
+       cell += 6;
+    else
+       cell--;
+    return cell;
+}
+
+static int
+next_or_previous(int key, int two_d)
+{
+    int result = 0;
+
+    switch (key) {
+    case DLGK_GRID_UP:
+       result = two_d ? -7 : -1;
+       break;
+    case DLGK_GRID_LEFT:
+       result = -1;
+       break;
+    case DLGK_GRID_DOWN:
+       result = two_d ? 7 : 1;
+       break;
+    case DLGK_GRID_RIGHT:
+       result = 1;
+       break;
+    default:
+       beep();
+       break;
+    }
+    return result;
+}
+
+/*
+ * Draw the day-of-month selection box
+ */
+static int
+draw_day(BOX * data, struct tm *current)
+{
+    int cell_wide = MON_WIDE;
+    int y, x, this_x = 0;
+    int save_y = 0, save_x = 0;
+    int day = current->tm_mday;
+    int mday;
+    int week;
+    int last = days_in_month(current, 0);
+    int prev = days_in_month(current, -1);
+
+    werase(data->window);
+    dlg_draw_box2(data->parent,
+                 data->y - MARGIN, data->x - MARGIN,
+                 data->height + (2 * MARGIN), data->width + (2 * MARGIN),
+                 menubox_attr,
+                 menubox_border_attr,
+                 menubox_border2_attr);
+
+    (void) wattrset(data->window, menubox_attr);       /* daynames headline */
+    for (x = 0; x < 7; x++) {
+       mvwprintw(data->window,
+                 0, (x + 1) * cell_wide, "%*.*s ",
+                 cell_wide - 1,
+                 cell_wide - 1,
+                 nameOfDayOfWeek(x));
+    }
+
+    mday = ((6 + current->tm_mday - current->tm_wday) % 7) - 7;
+    if (mday <= -7)
+       mday += 7;
+    /* mday is now in the range -6 to 0. */
+    week = (current->tm_yday + 6 + mday - current->tm_mday) / 7;
+
+    for (y = 1; mday < last; y++) {
+       (void) wattrset(data->window, menubox_attr);    /* weeknumbers headline */
+       mvwprintw(data->window,
+                 y, 0,
+                 "%*d ",
+                 cell_wide - 1,
+                 ++week);
+       for (x = 0; x < 7; x++) {
+           this_x = 1 + (x + 1) * cell_wide;
+           ++mday;
+           if (wmove(data->window, y, this_x) == ERR)
+               continue;
+           (void) wattrset(data->window, item_attr);   /* not selected days */
+           if (mday == day) {
+               (void) wattrset(data->window, item_selected_attr);      /* selected day */
+               save_y = y;
+               save_x = this_x;
+           }
+           if (mday > 0) {
+               if (mday <= last) {
+                   wprintw(data->window, "%*d", cell_wide - 2, mday);
+               } else if (mday == day) {
+                   wprintw(data->window, "%*d", cell_wide - 2, mday - last);
+               }
+           } else if (mday == day) {
+               wprintw(data->window, "%*d", cell_wide - 2, mday + prev);
+           }
+       }
+       wmove(data->window, save_y, save_x);
+    }
+    /* just draw arrows - scrollbar is unsuitable here */
+    dlg_draw_arrows(data->parent, TRUE, TRUE,
+                   data->x + ARROWS_COL,
+                   data->y - 1,
+                   data->y + data->height);
+
+    return 0;
+}
+
+/*
+ * Draw the month-of-year selection box
+ */
+static int
+draw_month(BOX * data, struct tm *current)
+{
+    int month;
+
+    month = current->tm_mon + 1;
+
+    (void) wattrset(data->parent, dialog_attr);                /* Headline "Month" */
+    (void) mvwprintw(data->parent, data->y - 2, data->x - 1, _("Month"));
+    dlg_draw_box2(data->parent,
+                 data->y - 1, data->x - 1,
+                 data->height + 2, data->width + 2,
+                 menubox_attr,
+                 menubox_border_attr,
+                 menubox_border2_attr);
+    (void) wattrset(data->window, item_attr);  /* color the month selection */
+    mvwprintw(data->window, 0, 0, "%s", nameOfMonth(month - 1));
+    wmove(data->window, 0, 0);
+    return 0;
+}
+
+/*
+ * Draw the year selection box
+ */
+static int
+draw_year(BOX * data, struct tm *current)
+{
+    int year = current->tm_year + 1900;
+
+    (void) wattrset(data->parent, dialog_attr);                /* Headline "Year" */
+    (void) mvwprintw(data->parent, data->y - 2, data->x - 1, _("Year"));
+    dlg_draw_box2(data->parent,
+                 data->y - 1, data->x - 1,
+                 data->height + 2, data->width + 2,
+                 menubox_attr,
+                 menubox_border_attr,
+                 menubox_border2_attr);
+    (void) wattrset(data->window, item_attr);  /* color the year selection */
+    mvwprintw(data->window, 0, 0, "%4d", year);
+    wmove(data->window, 0, 0);
+    return 0;
+}
+
+static int
+init_object(BOX * data,
+           WINDOW *parent,
+           int x, int y,
+           int width, int height,
+           BOX_DRAW box_draw,
+           int code)
+{
+    data->parent = parent;
+    data->x = x;
+    data->y = y;
+    data->width = width;
+    data->height = height;
+    data->box_draw = box_draw;
+
+    data->window = derwin(data->parent,
+                         data->height, data->width,
+                         data->y, data->x);
+    if (data->window == 0)
+       return -1;
+    (void) keypad(data->window, TRUE);
+
+    dlg_mouse_setbase(getbegx(parent), getbegy(parent));
+    if (code == 'D') {
+       dlg_mouse_mkbigregion(y + 1, x + MON_WIDE, height - 1, width - MON_WIDE,
+                             KEY_MAX, 1, MON_WIDE, 3);
+    } else {
+       dlg_mouse_mkregion(y, x, height, width, code);
+    }
+
+    return 0;
+}
+
+static int
+CleanupResult(int code, WINDOW *dialog, char *prompt, DIALOG_VARS * save_vars)
+{
+    if (dialog != 0)
+       dlg_del_window(dialog);
+    dlg_mouse_free_regions();
+    if (prompt != 0)
+       free(prompt);
+    dlg_restore_vars(save_vars);
+
+    return code;
+}
+
+#define DrawObject(data) (data)->box_draw(data, &current)
+
+/*
+ * Display a dialog box for entering a date
+ */
+int
+dialog_calendar(const char *title,
+               const char *subtitle,
+               int height,
+               int width,
+               int day,
+               int month,
+               int year)
+{
+    /* *INDENT-OFF* */
+    static DLG_KEYS_BINDING binding[] = {
+       HELPKEY_BINDINGS,
+       ENTERKEY_BINDINGS,
+       DLG_KEYS_DATA( DLGK_ENTER,      ' ' ),
+       DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ),
+       DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ),
+       DLG_KEYS_DATA( DLGK_GRID_DOWN,  'j' ),
+       DLG_KEYS_DATA( DLGK_GRID_DOWN,  DLGK_MOUSE(KEY_NPAGE) ),
+       DLG_KEYS_DATA( DLGK_GRID_DOWN,  KEY_DOWN ),
+       DLG_KEYS_DATA( DLGK_GRID_DOWN,  KEY_NPAGE ),
+       DLG_KEYS_DATA( DLGK_GRID_LEFT,  '-' ),
+       DLG_KEYS_DATA( DLGK_GRID_LEFT,  'h' ),
+       DLG_KEYS_DATA( DLGK_GRID_LEFT,  CHR_BACKSPACE ),
+       DLG_KEYS_DATA( DLGK_GRID_LEFT,  CHR_PREVIOUS ),
+       DLG_KEYS_DATA( DLGK_GRID_LEFT,  KEY_LEFT ),
+       DLG_KEYS_DATA( DLGK_GRID_RIGHT, '+' ),
+       DLG_KEYS_DATA( DLGK_GRID_RIGHT, 'l' ),
+       DLG_KEYS_DATA( DLGK_GRID_RIGHT, CHR_NEXT ),
+       DLG_KEYS_DATA( DLGK_GRID_RIGHT, KEY_NEXT ),
+       DLG_KEYS_DATA( DLGK_GRID_RIGHT, KEY_RIGHT ),
+       DLG_KEYS_DATA( DLGK_GRID_UP,    'k' ),
+       DLG_KEYS_DATA( DLGK_GRID_UP,    KEY_PPAGE ),
+       DLG_KEYS_DATA( DLGK_GRID_UP,    KEY_PREVIOUS ),
+       DLG_KEYS_DATA( DLGK_GRID_UP,    KEY_UP ),
+       DLG_KEYS_DATA( DLGK_GRID_UP,    DLGK_MOUSE(KEY_PPAGE) ),
+       END_KEYS_BINDING
+    };
+    /* *INDENT-ON* */
+
+#ifdef KEY_RESIZE
+    int old_height = height;
+    int old_width = width;
+#endif
+    BOX dy_box, mn_box, yr_box;
+    int fkey;
+    int key = 0;
+    int key2;
+    int step;
+    int button;
+    int result = DLG_EXIT_UNKNOWN;
+    WINDOW *dialog;
+    time_t now_time = time((time_t *) 0);
+    struct tm current;
+    int state = dlg_default_button();
+    const char **buttons = dlg_ok_labels();
+    char *prompt = dlg_strclone(subtitle);
+    int mincols = MIN_WIDE;
+    char buffer[MAX_LEN];
+    DIALOG_VARS save_vars;
+
+    dlg_save_vars(&save_vars);
+    dialog_vars.separate_output = TRUE;
+
+    dlg_does_output();
+
+    now_time = time((time_t *) 0);
+    current = *localtime(&now_time);
+    if (day < 0)
+       day = current.tm_mday;
+    if (month < 0)
+       month = current.tm_mon + 1;
+    if (year < 0)
+       year = current.tm_year + 1900;
+
+    /* compute a struct tm that matches the day/month/year parameters */
+    if (((year -= 1900) > 0) && (year < 200)) {
+       /* ugly, but I'd like to run this on older machines w/o mktime -TD */
+       for (;;) {
+           if (year > current.tm_year) {
+               now_time += ONE_DAY * days_in_year(&current, 0);
+           } else if (year < current.tm_year) {
+               now_time -= ONE_DAY * days_in_year(&current, -1);
+           } else if (month > current.tm_mon + 1) {
+               now_time += ONE_DAY * days_in_month(&current, 0);
+           } else if (month < current.tm_mon + 1) {
+               now_time -= ONE_DAY * days_in_month(&current, -1);
+           } else if (day > current.tm_mday) {
+               now_time += ONE_DAY;
+           } else if (day < current.tm_mday) {
+               now_time -= ONE_DAY;
+           } else {
+               break;
+           }
+           current = *localtime(&now_time);
+       }
+    }
+    dlg_button_layout(buttons, &mincols);
+
+#ifdef KEY_RESIZE
+  retry:
+#endif
+
+    dlg_auto_size(title, prompt, &height, &width, 0, mincols);
+    height += MIN_HIGH - 1;
+    dlg_print_size(height, width);
+    dlg_ctl_size(height, width);
+
+    dialog = dlg_new_window(height, width,
+                           dlg_box_y_ordinate(height),
+                           dlg_box_x_ordinate(width));
+    dlg_register_window(dialog, "calendar", binding);
+    dlg_register_buttons(dialog, "calendar", buttons);
+
+    /* mainbox */
+    dlg_draw_box2(dialog, 0, 0, height, width, dialog_attr, border_attr, border2_attr);
+    dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr);
+    dlg_draw_title(dialog, title);
+
+    (void) wattrset(dialog, dialog_attr);      /* text mainbox */
+    dlg_print_autowrap(dialog, prompt, height, width);
+
+    /* compute positions of day, month and year boxes */
+    memset(&dy_box, 0, sizeof(dy_box));
+    memset(&mn_box, 0, sizeof(mn_box));
+    memset(&yr_box, 0, sizeof(yr_box));
+
+    if (init_object(&dy_box,
+                   dialog,
+                   (width - DAY_WIDE) / 2,
+                   1 + (height - (DAY_HIGH + BTN_HIGH + (5 * MARGIN))),
+                   DAY_WIDE,
+                   DAY_HIGH + 1,
+                   draw_day,
+                   'D') < 0
+       || DrawObject(&dy_box) < 0) {
+       return CleanupResult(DLG_EXIT_ERROR, dialog, prompt, &save_vars);
+    }
+
+    if (init_object(&mn_box,
+                   dialog,
+                   dy_box.x,
+                   dy_box.y - (HDR_HIGH + 2 * MARGIN),
+                   (DAY_WIDE / 2) - MARGIN,
+                   HDR_HIGH,
+                   draw_month,
+                   'M') < 0
+       || DrawObject(&mn_box) < 0) {
+       return CleanupResult(DLG_EXIT_ERROR, dialog, prompt, &save_vars);
+    }
+
+    if (init_object(&yr_box,
+                   dialog,
+                   dy_box.x + mn_box.width + 2,
+                   mn_box.y,
+                   mn_box.width,
+                   mn_box.height,
+                   draw_year,
+                   'Y') < 0
+       || DrawObject(&yr_box) < 0) {
+       return CleanupResult(DLG_EXIT_ERROR, dialog, prompt, &save_vars);
+    }
+
+    dlg_trace_win(dialog);
+    while (result == DLG_EXIT_UNKNOWN) {
+       BOX *obj = (state == sDAY ? &dy_box
+                   : (state == sMONTH ? &mn_box :
+                      (state == sYEAR ? &yr_box : 0)));
+
+       button = (state < 0) ? 0 : state;
+       dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width);
+       if (obj != 0)
+           dlg_set_focus(dialog, obj->window);
+
+       key = dlg_mouse_wgetch(dialog, &fkey);
+       if (dlg_result_key(key, fkey, &result))
+           break;
+
+       if (fkey && (key >= DLGK_MOUSE(KEY_MIN) && key <= DLGK_MOUSE(KEY_MAX))) {
+           key = dlg_lookup_key(dialog, key - M_EVENT, &fkey);
+       }
+
+       if ((key2 = dlg_char_to_button(key, buttons)) >= 0) {
+           result = key2;
+       } else if (fkey) {
+           /* handle function-keys */
+           switch (key) {
+           case DLGK_MOUSE('D'):
+               state = sDAY;
+               break;
+           case DLGK_MOUSE('M'):
+               state = sMONTH;
+               break;
+           case DLGK_MOUSE('Y'):
+               state = sYEAR;
+               break;
+           case DLGK_ENTER:
+               result = dlg_enter_buttoncode(button);
+               break;
+           case DLGK_FIELD_PREV:
+               state = dlg_prev_ok_buttonindex(state, sMONTH);
+               break;
+           case DLGK_FIELD_NEXT:
+               state = dlg_next_ok_buttonindex(state, sMONTH);
+               break;
+#ifdef KEY_RESIZE
+           case KEY_RESIZE:
+               /* reset data */
+               height = old_height;
+               width = old_width;
+               /* repaint */
+               dlg_clear();
+               dlg_del_window(dialog);
+               refresh();
+               dlg_mouse_free_regions();
+               goto retry;
+#endif
+           default:
+               step = 0;
+               key2 = -1;
+               if (is_DLGK_MOUSE(key)) {
+                   if ((key2 = dlg_ok_buttoncode(key - M_EVENT)) >= 0) {
+                       result = key2;
+                       break;
+                   } else if (key >= DLGK_MOUSE(KEY_MAX)) {
+                       state = sDAY;
+                       obj = &dy_box;
+                       key2 = 1;
+                       step = (key
+                               - DLGK_MOUSE(KEY_MAX)
+                               - day_cell_number(&current));
+                   }
+               }
+               if (obj != 0) {
+                   if (key2 < 0)
+                       step = next_or_previous(key, (obj == &dy_box));
+                   if (step != 0) {
+                       struct tm old = current;
+
+                       /* see comment regarding mktime -TD */
+                       if (obj == &dy_box) {
+                           now_time += ONE_DAY * step;
+                       } else if (obj == &mn_box) {
+                           if (step > 0)
+                               now_time += ONE_DAY *
+                                   days_in_month(&current, 0);
+                           else
+                               now_time -= ONE_DAY *
+                                   days_in_month(&current, -1);
+                       } else if (obj == &yr_box) {
+                           if (step > 0)
+                               now_time += (ONE_DAY
+                                            * days_in_year(&current, 0));
+                           else
+                               now_time -= (ONE_DAY
+                                            * days_in_year(&current, -1));
+                       }
+
+                       current = *localtime(&now_time);
+
+                       if (obj != &dy_box
+                           && (current.tm_mday != old.tm_mday
+                               || current.tm_mon != old.tm_mon
+                               || current.tm_year != old.tm_year))
+                           DrawObject(&dy_box);
+                       if (obj != &mn_box && current.tm_mon != old.tm_mon)
+                           DrawObject(&mn_box);
+                       if (obj != &yr_box && current.tm_year != old.tm_year)
+                           DrawObject(&yr_box);
+                       (void) DrawObject(obj);
+                   }
+               } else if (state >= 0) {
+                   if (next_or_previous(key, FALSE) < 0)
+                       state = dlg_prev_ok_buttonindex(state, sMONTH);
+                   else if (next_or_previous(key, FALSE) > 0)
+                       state = dlg_next_ok_buttonindex(state, sMONTH);
+               }
+               break;
+           }
+       }
+    }
+
+#define DefaultFormat(dst, src) \
+       sprintf(dst, "%02d/%02d/%0d", \
+               src.tm_mday, src.tm_mon + 1, src.tm_year + 1900)
+#ifdef HAVE_STRFTIME
+    if (dialog_vars.date_format != 0) {
+       size_t used = strftime(buffer,
+                              sizeof(buffer) - 1,
+                              dialog_vars.date_format,
+                              &current);
+       if (used == 0 || *buffer == '\0')
+           DefaultFormat(buffer, current);
+    } else
+#endif
+       DefaultFormat(buffer, current);
+
+    dlg_add_result(buffer);
+    dlg_add_separator();
+
+    return CleanupResult(result, dialog, prompt, &save_vars);
+}
diff --git a/contrib/dialog/checklist.c b/contrib/dialog/checklist.c
new file mode 100644 (file)
index 0000000..b15b47b
--- /dev/null
@@ -0,0 +1,691 @@
+/*
+ *  $Id: checklist.c,v 1.148 2012/12/24 02:08:58 tom Exp $
+ *
+ *  checklist.c -- implements the checklist box
+ *
+ *  Copyright 2000-2011,2012   Thomas E. Dickey
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License, version 2.1
+ *  as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to
+ *     Free Software Foundation, Inc.
+ *     51 Franklin St., Fifth Floor
+ *     Boston, MA 02110, USA.
+ *
+ *  An earlier version of this program lists as authors:
+ *     Savio Lam (lam836@cs.cuhk.hk)
+ *     Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension
+ *     Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two
+ */
+
+#include <dialog.h>
+#include <dlg_keys.h>
+
+#define MIN_HIGH  (1 + (5 * MARGIN))
+
+typedef struct {
+    /* the outer-window */
+    WINDOW *dialog;
+    int box_y;
+    int box_x;
+    int check_x;
+    int item_x;
+    int checkflag;
+    int use_height;
+    int use_width;
+    /* the inner-window */
+    WINDOW *list;
+    DIALOG_LISTITEM *items;
+    int item_no;
+    const char *states;
+} ALL_DATA;
+
+/*
+ * Print list item.  The 'selected' parameter is true if 'choice' is the
+ * current item.  That one is colored differently from the other items.
+ */
+static void
+print_item(ALL_DATA * data,
+          WINDOW *win,
+          DIALOG_LISTITEM * item,
+          const char *states,
+          int choice,
+          int selected)
+{
+    chtype save = dlg_get_attrs(win);
+    int i;
+    bool both = (!dialog_vars.no_tags && !dialog_vars.no_items);
+    bool first = TRUE;
+    int climit = (getmaxx(win) - data->check_x + 1);
+    const char *show = (dialog_vars.no_items
+                       ? item->name
+                       : item->text);
+
+    /* Clear 'residue' of last item */
+    (void) wattrset(win, menubox_attr);
+    (void) wmove(win, choice, 0);
+    for (i = 0; i < data->use_width; i++)
+       (void) waddch(win, ' ');
+
+    (void) wmove(win, choice, data->check_x);
+    (void) wattrset(win, selected ? check_selected_attr : check_attr);
+    (void) wprintw(win,
+                  (data->checkflag == FLAG_CHECK) ? "[%c]" : "(%c)",
+                  states[item->state]);
+    (void) wattrset(win, menubox_attr);
+    (void) waddch(win, ' ');
+
+    if (both) {
+       dlg_print_listitem(win, item->name, climit, first, selected);
+       first = FALSE;
+    }
+
+    (void) wmove(win, choice, data->item_x);
+    dlg_print_listitem(win, show, climit, first, selected);
+
+    if (selected) {
+       dlg_item_help(item->help);
+    }
+    (void) wattrset(win, save);
+}
+
+static void
+print_list(ALL_DATA * data, int choice, int scrollamt, int max_choice)
+{
+    int i;
+    int cur_y, cur_x;
+
+    getyx(data->dialog, cur_y, cur_x);
+    for (i = 0; i < max_choice; i++) {
+       print_item(data,
+                  data->list,
+                  &data->items[i + scrollamt],
+                  data->states,
+                  i, i == choice);
+    }
+    (void) wnoutrefresh(data->list);
+
+    dlg_draw_scrollbar(data->dialog,
+                      (long) (scrollamt),
+                      (long) (scrollamt),
+                      (long) (scrollamt + max_choice),
+                      (long) (data->item_no),
+                      data->box_x + data->check_x,
+                      data->box_x + data->use_width,
+                      data->box_y,
+                      data->box_y + data->use_height + 1,
+                      menubox_border2_attr,
+                      menubox_border_attr);
+
+    (void) wmove(data->dialog, cur_y, cur_x);
+}
+
+static bool
+check_hotkey(DIALOG_LISTITEM * items, int choice)
+{
+    bool result = FALSE;
+
+    if (dlg_match_char(dlg_last_getc(),
+                      (dialog_vars.no_tags
+                       ? items[choice].text
+                       : items[choice].name))) {
+       result = TRUE;
+    }
+    return result;
+}
+
+/*
+ * This is an alternate interface to 'checklist' which allows the application
+ * to read the list item states back directly without putting them in the
+ * output buffer.  It also provides for more than two states over which the
+ * check/radio box can display.
+ */
+int
+dlg_checklist(const char *title,
+             const char *cprompt,
+             int height,
+             int width,
+             int list_height,
+             int item_no,
+             DIALOG_LISTITEM * items,
+             const char *states,
+             int flag,
+             int *current_item)
+{
+    /* *INDENT-OFF* */
+    static DLG_KEYS_BINDING binding[] = {
+       HELPKEY_BINDINGS,
+       ENTERKEY_BINDINGS,
+       DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ),
+       DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ),
+       DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ),
+       DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_LEFT ),
+       DLG_KEYS_DATA( DLGK_ITEM_FIRST, KEY_HOME ),
+       DLG_KEYS_DATA( DLGK_ITEM_LAST,  KEY_END ),
+       DLG_KEYS_DATA( DLGK_ITEM_LAST,  KEY_LL ),
+       DLG_KEYS_DATA( DLGK_ITEM_NEXT,  '+' ),
+       DLG_KEYS_DATA( DLGK_ITEM_NEXT,  KEY_DOWN ),
+       DLG_KEYS_DATA( DLGK_ITEM_NEXT,  CHR_NEXT ),
+       DLG_KEYS_DATA( DLGK_ITEM_PREV,  '-' ),
+       DLG_KEYS_DATA( DLGK_ITEM_PREV,  KEY_UP ),
+       DLG_KEYS_DATA( DLGK_ITEM_PREV,  CHR_PREVIOUS ),
+       DLG_KEYS_DATA( DLGK_PAGE_NEXT,  KEY_NPAGE ),
+       DLG_KEYS_DATA( DLGK_PAGE_NEXT,  DLGK_MOUSE(KEY_NPAGE) ),
+       DLG_KEYS_DATA( DLGK_PAGE_PREV,  KEY_PPAGE ),
+       DLG_KEYS_DATA( DLGK_PAGE_PREV,  DLGK_MOUSE(KEY_PPAGE) ),
+       END_KEYS_BINDING
+    };
+    /* *INDENT-ON* */
+
+#ifdef KEY_RESIZE
+    int old_height = height;
+    int old_width = width;
+#endif
+    ALL_DATA all;
+    int i, j, key2, found, x, y, cur_x, cur_y;
+    int key = 0, fkey;
+    int button = dialog_state.visit_items ? -1 : dlg_default_button();
+    int choice = dlg_default_listitem(items);
+    int scrollamt = 0;
+    int max_choice;
+    int was_mouse;
+    int use_width, list_width, name_width, text_width;
+    int result = DLG_EXIT_UNKNOWN;
+    int num_states;
+    WINDOW *dialog;
+    char *prompt = dlg_strclone(cprompt);
+    const char **buttons = dlg_ok_labels();
+    const char *widget_name;
+
+    memset(&all, 0, sizeof(all));
+    all.items = items;
+    all.item_no = item_no;
+
+    dlg_does_output();
+    dlg_tab_correct_str(prompt);
+
+    /*
+     * If this is a radiobutton list, ensure that no more than one item is
+     * selected initially.  Allow none to be selected, since some users may
+     * wish to provide this flavor.
+     */
+    if (flag == FLAG_RADIO) {
+       bool first = TRUE;
+
+       for (i = 0; i < item_no; i++) {
+           if (items[i].state) {
+               if (first) {
+                   first = FALSE;
+               } else {
+                   items[i].state = 0;
+               }
+           }
+       }
+       widget_name = "radiolist";
+    } else {
+       widget_name = "checklist";
+    }
+#ifdef KEY_RESIZE
+  retry:
+#endif
+
+    all.use_height = list_height;
+    use_width = dlg_calc_list_width(item_no, items) + 10;
+    use_width = MAX(26, use_width);
+    if (all.use_height == 0) {
+       /* calculate height without items (4) */
+       dlg_auto_size(title, prompt, &height, &width, MIN_HIGH, use_width);
+       dlg_calc_listh(&height, &all.use_height, item_no);
+    } else {
+       dlg_auto_size(title, prompt,
+                     &height, &width,
+                     MIN_HIGH + all.use_height, use_width);
+    }
+    dlg_button_layout(buttons, &width);
+    dlg_print_size(height, width);
+    dlg_ctl_size(height, width);
+
+    /* we need at least two states */
+    if (states == 0 || strlen(states) < 2)
+       states = " *";
+    num_states = (int) strlen(states);
+    all.states = states;
+
+    all.checkflag = flag;
+
+    x = dlg_box_x_ordinate(width);
+    y = dlg_box_y_ordinate(height);
+
+    dialog = dlg_new_window(height, width, y, x);
+    all.dialog = dialog;
+    dlg_register_window(dialog, widget_name, binding);
+    dlg_register_buttons(dialog, widget_name, buttons);
+
+    dlg_mouse_setbase(x, y);
+
+    dlg_draw_box2(dialog, 0, 0, height, width, dialog_attr, border_attr, border2_attr);
+    dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr);
+    dlg_draw_title(dialog, title);
+
+    (void) wattrset(dialog, dialog_attr);
+    dlg_print_autowrap(dialog, prompt, height, width);
+
+    all.use_width = width - 6;
+    getyx(dialog, cur_y, cur_x);
+    all.box_y = cur_y + 1;
+    all.box_x = (width - all.use_width) / 2 - 1;
+
+    /*
+     * After displaying the prompt, we know how much space we really have.
+     * Limit the list to avoid overwriting the ok-button.
+     */
+    if (all.use_height + MIN_HIGH > height - cur_y)
+       all.use_height = height - MIN_HIGH - cur_y;
+    if (all.use_height <= 0)
+       all.use_height = 1;
+
+    max_choice = MIN(all.use_height, item_no);
+
+    /* create new window for the list */
+    all.list = dlg_sub_window(dialog, all.use_height, all.use_width,
+                             y + all.box_y + 1, x + all.box_x + 1);
+
+    /* draw a box around the list items */
+    dlg_draw_box(dialog, all.box_y, all.box_x,
+                all.use_height + 2 * MARGIN,
+                all.use_width + 2 * MARGIN,
+                menubox_border_attr, menubox_border2_attr);
+
+    text_width = 0;
+    name_width = 0;
+    /* Find length of longest item to center checklist */
+    for (i = 0; i < item_no; i++) {
+       text_width = MAX(text_width, dlg_count_columns(items[i].text));
+       name_width = MAX(name_width, dlg_count_columns(items[i].name));
+    }
+
+    /* If the name+text is wider than the list is allowed, then truncate
+     * one or both of them.  If the name is no wider than 1/4 of the list,
+     * leave it intact.
+     */
+    use_width = (all.use_width - 6);
+    if (dialog_vars.no_tags) {
+       list_width = MIN(all.use_width, text_width);
+    } else if (dialog_vars.no_items) {
+       list_width = MIN(all.use_width, name_width);
+    } else {
+       if (text_width >= 0
+           && name_width >= 0
+           && use_width > 0
+           && text_width + name_width > use_width) {
+           int need = (int) (0.25 * use_width);
+           if (name_width > need) {
+               int want = (int) (use_width * ((double) name_width) /
+                                 (text_width + name_width));
+               name_width = (want > need) ? want : need;
+           }
+           text_width = use_width - name_width;
+       }
+       list_width = (text_width + name_width);
+    }
+
+    all.check_x = (use_width - list_width) / 2;
+    all.item_x = ((dialog_vars.no_tags
+                  ? 0
+                  : (dialog_vars.no_items
+                     ? 0
+                     : (2 + name_width)))
+                 + all.check_x + 4);
+
+    /* ensure we are scrolled to show the current choice */
+    if (choice >= (max_choice + scrollamt)) {
+       scrollamt = choice - max_choice + 1;
+       choice = max_choice - 1;
+    }
+    print_list(&all, choice, scrollamt, max_choice);
+
+    /* register the new window, along with its borders */
+    dlg_mouse_mkbigregion(all.box_y + 1, all.box_x,
+                         all.use_height, all.use_width + 2,
+                         KEY_MAX, 1, 1, 1 /* by lines */ );
+
+    dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width);
+
+    dlg_trace_win(dialog);
+    while (result == DLG_EXIT_UNKNOWN) {
+       if (button < 0)         /* --visit-items */
+           wmove(dialog, all.box_y + choice + 1, all.box_x + all.check_x + 2);
+
+       key = dlg_mouse_wgetch(dialog, &fkey);
+       if (dlg_result_key(key, fkey, &result))
+           break;
+
+       was_mouse = (fkey && is_DLGK_MOUSE(key));
+       if (was_mouse)
+           key -= M_EVENT;
+
+       if (was_mouse && (key >= KEY_MAX)) {
+           getyx(dialog, cur_y, cur_x);
+           i = (key - KEY_MAX);
+           if (i < max_choice) {
+               choice = (key - KEY_MAX);
+               print_list(&all, choice, scrollamt, max_choice);
+
+               key = ' ';      /* force the selected item to toggle */
+           } else {
+               beep();
+               continue;
+           }
+           fkey = FALSE;
+       } else if (was_mouse && key >= KEY_MIN) {
+           key = dlg_lookup_key(dialog, key, &fkey);
+       }
+
+       /*
+        * A space toggles the item status.  We handle either a checklist
+        * (any number of items can be selected) or radio list (zero or one
+        * items can be selected).
+        */
+       if (key == ' ') {
+           int current = scrollamt + choice;
+           int next = items[current].state + 1;
+
+           if (next >= num_states)
+               next = 0;
+
+           if (flag == FLAG_CHECK) {   /* checklist? */
+               getyx(dialog, cur_y, cur_x);
+               items[current].state = next;
+               print_item(&all, all.list,
+                          &items[scrollamt + choice],
+                          states,
+                          choice, TRUE);
+               (void) wnoutrefresh(all.list);
+               (void) wmove(dialog, cur_y, cur_x);
+           } else {            /* radiolist */
+               for (i = 0; i < item_no; i++) {
+                   if (i != current) {
+                       items[i].state = 0;
+                   }
+               }
+               if (items[current].state) {
+                   getyx(dialog, cur_y, cur_x);
+                   items[current].state = next ? next : 1;
+                   print_item(&all, all.list,
+                              &items[current],
+                              states,
+                              choice, TRUE);
+                   (void) wnoutrefresh(all.list);
+                   (void) wmove(dialog, cur_y, cur_x);
+               } else {
+                   items[current].state = 1;
+                   print_list(&all, choice, scrollamt, max_choice);
+               }
+           }
+           continue;           /* wait for another key press */
+       }
+
+       /*
+        * Check if key pressed matches first character of any item tag in
+        * list.  If there is more than one match, we will cycle through
+        * each one as the same key is pressed repeatedly.
+        */
+       found = FALSE;
+       if (!fkey) {
+           if (button < 0 || !dialog_state.visit_items) {
+               for (j = scrollamt + choice + 1; j < item_no; j++) {
+                   if (check_hotkey(items, j)) {
+                       found = TRUE;
+                       i = j - scrollamt;
+                       break;
+                   }
+               }
+               if (!found) {
+                   for (j = 0; j <= scrollamt + choice; j++) {
+                       if (check_hotkey(items, j)) {
+                           found = TRUE;
+                           i = j - scrollamt;
+                           break;
+                       }
+                   }
+               }
+               if (found)
+                   dlg_flush_getc();
+           } else if ((j = dlg_char_to_button(key, buttons)) >= 0) {
+               button = j;
+               ungetch('\n');
+               continue;
+           }
+       }
+
+       /*
+        * A single digit (1-9) positions the selection to that line in the
+        * current screen.
+        */
+       if (!found
+           && (key <= '9')
+           && (key > '0')
+           && (key - '1' < max_choice)) {
+           found = TRUE;
+           i = key - '1';
+       }
+
+       if (!found) {
+           if (fkey) {
+               found = TRUE;
+               switch (key) {
+               case DLGK_ITEM_FIRST:
+                   i = -scrollamt;
+                   break;
+               case DLGK_ITEM_LAST:
+                   i = item_no - 1 - scrollamt;
+                   break;
+               case DLGK_PAGE_PREV:
+                   if (choice)
+                       i = 0;
+                   else if (scrollamt != 0)
+                       i = -MIN(scrollamt, max_choice);
+                   else
+                       continue;
+                   break;
+               case DLGK_PAGE_NEXT:
+                   i = MIN(choice + max_choice, item_no - scrollamt - 1);
+                   break;
+               case DLGK_ITEM_PREV:
+                   i = choice - 1;
+                   if (choice == 0 && scrollamt == 0)
+                       continue;
+                   break;
+               case DLGK_ITEM_NEXT:
+                   i = choice + 1;
+                   if (scrollamt + choice >= item_no - 1)
+                       continue;
+                   break;
+               default:
+                   found = FALSE;
+                   break;
+               }
+           }
+       }
+
+       if (found) {
+           if (i != choice) {
+               getyx(dialog, cur_y, cur_x);
+               if (i < 0 || i >= max_choice) {
+                   if (i < 0) {
+                       scrollamt += i;
+                       choice = 0;
+                   } else {
+                       choice = max_choice - 1;
+                       scrollamt += (i - max_choice + 1);
+                   }
+                   print_list(&all, choice, scrollamt, max_choice);
+               } else {
+                   choice = i;
+                   print_list(&all, choice, scrollamt, max_choice);
+               }
+           }
+           continue;           /* wait for another key press */
+       }
+
+       if (fkey) {
+           switch (key) {
+           case DLGK_ENTER:
+               result = dlg_enter_buttoncode(button);
+               break;
+           case DLGK_FIELD_PREV:
+               button = dlg_prev_button(buttons, button);
+               dlg_draw_buttons(dialog, height - 2, 0, buttons, button,
+                                FALSE, width);
+               break;
+           case DLGK_FIELD_NEXT:
+               button = dlg_next_button(buttons, button);
+               dlg_draw_buttons(dialog, height - 2, 0, buttons, button,
+                                FALSE, width);
+               break;
+#ifdef KEY_RESIZE
+           case KEY_RESIZE:
+               /* reset data */
+               height = old_height;
+               width = old_width;
+               /* repaint */
+               dlg_clear();
+               dlg_del_window(dialog);
+               refresh();
+               dlg_mouse_free_regions();
+               goto retry;
+#endif
+           default:
+               if (was_mouse) {
+                   if ((key2 = dlg_ok_buttoncode(key)) >= 0) {
+                       result = key2;
+                       break;
+                   }
+                   beep();
+               }
+           }
+       } else {
+           beep();
+       }
+    }
+
+    dlg_del_window(dialog);
+    dlg_mouse_free_regions();
+    free(prompt);
+    *current_item = (scrollamt + choice);
+    return result;
+}
+
+/*
+ * Display a dialog box with a list of options that can be turned on or off
+ * The `flag' parameter is used to select between radiolist and checklist.
+ */
+int
+dialog_checklist(const char *title,
+                const char *cprompt,
+                int height,
+                int width,
+                int list_height,
+                int item_no,
+                char **items,
+                int flag)
+{
+    int result;
+    int i, j;
+    DIALOG_LISTITEM *listitems;
+    bool separate_output = ((flag == FLAG_CHECK)
+                           && (dialog_vars.separate_output));
+    bool show_status = FALSE;
+    int current = 0;
+
+    listitems = dlg_calloc(DIALOG_LISTITEM, (size_t) item_no + 1);
+    assert_ptr(listitems, "dialog_checklist");
+
+    for (i = j = 0; i < item_no; ++i) {
+       listitems[i].name = items[j++];
+       listitems[i].text = (dialog_vars.no_items
+                            ? dlg_strempty()
+                            : items[j++]);
+       listitems[i].state = !dlg_strcmp(items[j++], "on");
+       listitems[i].help = ((dialog_vars.item_help)
+                            ? items[j++]
+                            : dlg_strempty());
+    }
+    dlg_align_columns(&listitems[0].text, (int) sizeof(DIALOG_LISTITEM), item_no);
+
+    result = dlg_checklist(title,
+                          cprompt,
+                          height,
+                          width,
+                          list_height,
+                          item_no,
+                          listitems,
+                          NULL,
+                          flag,
+                          &current);
+
+    switch (result) {
+    case DLG_EXIT_OK:          /* FALLTHRU */
+    case DLG_EXIT_EXTRA:
+       show_status = TRUE;
+       break;
+    case DLG_EXIT_HELP:
+       dlg_add_result("HELP ");
+       show_status = dialog_vars.help_status;
+       if (USE_ITEM_HELP(listitems[current].help)) {
+           if (show_status) {
+               if (separate_output) {
+                   dlg_add_string(listitems[current].help);
+                   dlg_add_separator();
+               } else {
+                   dlg_add_quoted(listitems[current].help);
+               }
+           } else {
+               dlg_add_string(listitems[current].help);
+           }
+           result = DLG_EXIT_ITEM_HELP;
+       } else {
+           if (show_status) {
+               if (separate_output) {
+                   dlg_add_string(listitems[current].name);
+                   dlg_add_separator();
+               } else {
+                   dlg_add_quoted(listitems[current].name);
+               }
+           } else {
+               dlg_add_string(listitems[current].name);
+           }
+       }
+       break;
+    }
+
+    if (show_status) {
+       for (i = 0; i < item_no; i++) {
+           if (listitems[i].state) {
+               if (separate_output) {
+                   dlg_add_string(listitems[i].name);
+                   dlg_add_separator();
+               } else {
+                   if (dlg_need_separator())
+                       dlg_add_separator();
+                   if (flag == FLAG_CHECK)
+                       dlg_add_quoted(listitems[i].name);
+                   else
+                       dlg_add_string(listitems[i].name);
+               }
+           }
+       }
+    }
+
+    dlg_free_columns(&listitems[0].text, (int) sizeof(DIALOG_LISTITEM), item_no);
+    free(listitems);
+    return result;
+}
diff --git a/contrib/dialog/columns.c b/contrib/dialog/columns.c
new file mode 100644 (file)
index 0000000..d03761f
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ *  $Id: columns.c,v 1.10 2011/10/20 20:53:55 tom Exp $
+ *
+ *  columns.c -- implements column-alignment
+ *
+ *  Copyright 2008-2010,2011   Thomas E. Dickey
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License, version 2.1
+ *  as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to
+ *     Free Software Foundation, Inc.
+ *     51 Franklin St., Fifth Floor
+ *     Boston, MA 02110, USA.
+ */
+
+#include <dialog.h>
+
+#define each(row, data) \
+               row = 0, data = target; \
+               row < num_rows; \
+               ++row, data = next_row(data, per_row)
+
+static char *
+column_separator(void)
+{
+    char *result = 0;
+
+    if ((result = dialog_vars.column_separator) != 0) {
+       if (*result == '\0')
+           result = 0;
+    }
+    return result;
+}
+
+static char **
+next_row(char **target, int per_row)
+{
+    char *result = (char *) target;
+    result += per_row;
+    return (char **) (void *) result;
+}
+
+static char *
+next_col(char *source, unsigned offset)
+{
+    char *mark = column_separator();
+    char *result = source + offset;
+    if (offset)
+       result += strlen(mark);
+    return strstr(result, mark);
+}
+
+/*
+ * Parse the source string, storing the offsets and widths of each column in
+ * the corresponding arrays.  Return the number of columns.
+ */
+static unsigned
+split_row(char *source, unsigned *offsets, unsigned *widths)
+{
+    int mark = (int) strlen(column_separator());
+    char *next = 0;
+    unsigned result = 0;
+    unsigned offset = 0;
+
+    do {
+       if (result) {
+           offset = (unsigned) (mark + next - source);
+           widths[result - 1] = offset - offsets[result - 1] - (unsigned) mark;
+       }
+       offsets[result] = offset;
+       ++result;
+    } while ((next = next_col(source, offset)) != 0);
+
+    offset = (unsigned) strlen(source);
+    widths[result - 1] = offset - offsets[result - 1];
+
+    return result;
+}
+
+/*
+ * The caller passes a pointer to a struct or array containing pointers
+ * to strings that we may want to copy and reformat according to the column
+ * separator.
+ */
+void
+dlg_align_columns(char **target, int per_row, int num_rows)
+{
+    int row;
+
+    if (column_separator()) {
+       char **value;
+       unsigned numcols = 1;
+       size_t maxcols = 0;
+       unsigned *widths;
+       unsigned *offsets;
+       unsigned *maxwidth;
+       unsigned realwidth;
+       unsigned n;
+
+       /* first allocate arrays for workspace */
+       for (each(row, value)) {
+           size_t len = strlen(*value);
+           if (maxcols < len)
+               maxcols = len;
+       }
+       ++maxcols;
+       widths = dlg_calloc(unsigned, maxcols);
+       offsets = dlg_calloc(unsigned, maxcols);
+       maxwidth = dlg_calloc(unsigned, maxcols);
+
+       assert_ptr(widths, "dlg_align_columns");
+       assert_ptr(offsets, "dlg_align_columns");
+       assert_ptr(maxwidth, "dlg_align_columns");
+
+       /* now, determine the number of columns and the column-widths */
+       for (each(row, value)) {
+           unsigned cols = split_row(*value, offsets, widths);
+           if (numcols < cols)
+               numcols = cols;
+           for (n = 0; n < cols; ++n) {
+               if (maxwidth[n] < widths[n])
+                   maxwidth[n] = widths[n];
+           }
+       }
+       realwidth = numcols - 1;
+       for (n = 0; n < numcols; ++n) {
+           realwidth += maxwidth[n];
+       }
+
+       /* finally, construct reformatted strings */
+       for (each(row, value)) {
+           unsigned cols = split_row(*value, offsets, widths);
+           unsigned offset = 0;
+           char *text = dlg_malloc(char, realwidth + 1);
+
+           assert_ptr(text, "dlg_align_columns");
+
+           memset(text, ' ', (size_t) realwidth);
+           for (n = 0; n < cols; ++n) {
+               memcpy(text + offset, *value + offsets[n], (size_t) widths[n]);
+               offset += maxwidth[n] + 1;
+           }
+           text[realwidth] = 0;
+           *value = text;
+       }
+
+       free(widths);
+       free(offsets);
+       free(maxwidth);
+    }
+}
+
+/*
+ * Free temporary storage used while making column-aligned data.
+ */
+void
+dlg_free_columns(char **target, int per_row, int num_rows)
+{
+    int row;
+    char **value;
+
+    if (column_separator()) {
+       for (each(row, value)) {
+           free(*value);
+       }
+    }
+}
diff --git a/contrib/dialog/dialog.1 b/contrib/dialog/dialog.1
new file mode 100644 (file)
index 0000000..2d6218b
--- /dev/null
@@ -0,0 +1,1634 @@
+'\" t
+.\" $Id: dialog.1,v 1.164 2012/12/30 23:32:18 tom Exp $
+.\" Copyright 2005-2011,2012  Thomas E. Dickey
+.\"
+.\" This program is free software; you can redistribute it and/or modify
+.\" it under the terms of the GNU Lesser General Public License, version 2.1
+.\" as published by the Free Software Foundation.
+.\"
+.\" This program is distributed in the hope that it will be useful, but
+.\" WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+.\" Lesser General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU Lesser General Public
+.\" License along with this program; if not, write to
+.\"    Free Software Foundation, Inc.
+.\"    51 Franklin St., Fifth Floor
+.\"    Boston, MA 02110, USA.
+.\"
+.\" definitions for renaming
+.ds p dialog
+.ds l dialog
+.ds L Dialog
+.ds D DIALOG
+.\"
+.de ES
+.ne 8
+.IP
+..
+.de Ex
+.RS +7
+.PP
+.nf
+..
+.de Ee
+.fi
+.RE
+..
+.\" Bulleted paragraph
+.de bP
+.IP \(bu 4
+..
+.
+.TH \*D 1 "" "$Date: 2012/12/30 23:32:18 $"
+.SH NAME
+dialog \- display dialog boxes from shell scripts
+.SH SYNOPSIS
+\fB\*p --clear\fP
+.br
+.BI "\*p --create-rc " file
+.br
+\fB\*p --print-maxsize\fP
+.br
+\fB\*p\fP
+\fIcommon-options\fP
+\fIbox-options\fP
+.SH DESCRIPTION
+\fB\*L\fP
+is a program that will let you to present a variety of questions or
+display messages using dialog boxes from a shell script.
+These types of dialog boxes are implemented
+(though not all are necessarily compiled into \fB\*p\fR):
+.RS
+.LP
+.nh
+.na
+.BR buildlist ", "
+.BR calendar ", "
+.BR checklist ", "
+.BR dselect ", "
+.BR editbox ", "
+.BR form ", "
+.BR fselect ", "
+.BR gauge ", "
+.BR infobox ", "
+.BR inputbox ", "
+.BR inputmenu ", "
+.BR menu ", "
+.BR mixedform ", "
+.BR mixedgauge ", "
+.BR msgbox " (message), "
+.BR passwordbox ", "
+.BR passwordform ", "
+.BR pause ", "
+.BR prgbox ", "
+.BR programbox ", "
+.BR progressbox ", "
+.BR radiolist ", "
+.BR rangebox ", "
+.BR tailbox ", "
+.BR tailboxbg ", "
+.BR textbox ", "
+.BR timebox ", "
+.BR treeview ", and "
+.BR yesno " (yes/no)."
+.ad
+.hy
+.RE
+.PP
+You can put more than one dialog box into a script:
+.bP
+Use the "\fB--and-widget\fP" token to force \fB\*p\fP to proceed to the next
+dialog unless you have pressed ESC to cancel, or
+.bP
+Simply add the tokens for the next dialog box, making a chain.
+\*L stops chaining when the return code from a dialog is nonzero,
+e.g., Cancel or No (see DIAGNOSTICS).
+.PP
+Some widgets, e.g., checklist, will write text to \fB\*p\fP's output.
+Normally that is the standard error, but there are options for
+changing this: "\fB--output-fd\fP", "\fB--stderr\fP" and "\fB--stdout\fP".
+No text is written if the Cancel button (or ESC) is pressed;
+\fB\*p\fP exits immediately in that case.
+.
+.\" ************************************************************************
+.SH OPTIONS
+All options begin with "\fB--\fP"
+(two ASCII hyphens,
+for the benefit of those using systems with deranged locale support).
+.PP
+A "\fB--\fP" by itself is used as an escape,
+i.e., the next token on the command-line is not treated as an option.
+.RS
+.B \*p --title -- --Not an option
+.RE
+.PP
+The "\fB--args\fP" option tells \fB\*p\fP to list the command-line
+parameters to the standard error.
+This is useful when debugging complex scripts using
+the "\fB--\fP" and "\fB--file\fP",
+since the command-line may be rewritten as these are expanded.
+.PP
+The "\fB--file\fP" option tells \fB\*p\fP to read parameters from
+the file named as its value.
+.RS
+.B \*p --file \fIparameterfile
+.RE
+Blanks not within double-quotes are discarded
+(use backslashes to quote single characters).
+The result is inserted into the command-line,
+replacing "\fB--file\fP" and its option value.
+Interpretation of the command-line resumes from that point.
+If \fIparameterfile\fP begins with "&", \fB\*p\fP
+interprets the following text as a file descriptor number
+rather than a filename.
+.
+.SS \fBCommon Options\fP
+.
+.IP "\fB--ascii-lines
+Rather than draw graphics lines around boxes,
+draw ASCII "+" and "-" in the same place.
+See also "\fB--no-lines\fR".
+.
+.IP "\fB--aspect \fIratio"
+This gives you some control over the box dimensions when using auto
+sizing (specifying 0 for height and width).
+It represents width / height.
+The default is 9, which means 9 characters wide to every 1 line high.
+.
+.IP "\fB--backtitle \fIbacktitle"
+Specifies a
+\fIbacktitle\fP
+string to be displayed on the backdrop, at the top of the screen.
+.
+.IP "\fB--begin \fIy x"
+Specify the position of the upper left corner of a dialog box on the screen.
+.
+.IP "\fB--cancel-label \fIstring"
+Override the label used for "Cancel" buttons.
+.
+.IP "\fB--clear"
+Clears the widget screen, keeping only the screen_color background.
+Use this when you combine widgets with "\fB--and-widget\fR" to erase the
+contents of a previous widget on the screen, so it won't be seen
+under the contents of a following widget.
+Understand this as the complement of "\fB--keep-window\fR".
+To compare the effects, use these:
+.
+.ES
+All three widgets visible, staircase effect, ordered 1,2,3:
+.Ex
+\*p \\
+                               --begin 2 2 --yesno "" 0 0 \\
+    --and-widget               --begin 4 4 --yesno "" 0 0 \\
+    --and-widget               --begin 6 6 --yesno "" 0 0
+.Ee
+.
+.ES
+Only the last widget is left visible:
+.Ex
+\*p \\
+                 --clear       --begin 2 2 --yesno "" 0 0 \\
+    --and-widget --clear       --begin 4 4 --yesno "" 0 0 \\
+    --and-widget               --begin 6 6 --yesno "" 0 0
+.Ee
+.
+.ES
+All three widgets visible, staircase effect, ordered 3,2,1:
+.Ex
+\*p \\
+                 --keep-window --begin 2 2 --yesno "" 0 0 \\
+    --and-widget --keep-window --begin 4 4 --yesno "" 0 0 \\
+    --and-widget               --begin 6 6 --yesno "" 0 0
+.Ee
+.
+.ES
+First and third widget visible, staircase effect, ordered 3,1:
+.Ex
+\*p \\
+                 --keep-window --begin 2 2 --yesno "" 0 0 \\
+    --and-widget --clear       --begin 4 4 --yesno "" 0 0 \\
+    --and-widget               --begin 6 6 --yesno "" 0 0
+.Ee
+.IP
+Note, if you want to restore original console colors and send your
+cursor home after the dialog program has exited, use the \fBclear\fR\ (1)
+command.
+.
+.IP "\fB--colors"
+Interpret embedded "\\Z" sequences in the dialog text
+by the following character,
+which tells \fB\*p\fP to set colors or video attributes:
+0 through 7 are the ANSI used in curses:
+black,
+red,
+green,
+yellow,
+blue,
+magenta,
+cyan and
+white respectively.
+Bold is set by 'b', reset by 'B'.
+Reverse is set by 'r', reset by 'R'.
+Underline is set by 'u', reset by 'U'.
+The settings are cumulative, e.g., "\\Zb\\Z1" makes the following text
+bold (perhaps bright) red.
+Restore normal settings with "\\Zn".
+.
+.IP "\fB--column-separator \fIstring"
+Tell \fB\*p\fP to split data for radio/checkboxes and menus on the
+occurrences of the given string, and to align the split data into columns.
+.
+.IP "\fB--cr-wrap"
+Interpret embedded newlines in the dialog text as a newline on the screen.
+Otherwise, \fB\*p\fR will only wrap lines where needed to fit inside the text box.
+.IP
+Even though you can control line breaks with this,
+\fB\*L\fR will still wrap any lines that are too long for the width of the box.
+Without cr-wrap, the layout of your text may be formatted to look nice
+in the source code of your script without affecting the way it will
+look in the dialog.
+.IP
+See also the "\fB--no-collapse\fP" and "\fB--trim\fP" options.
+.
+.IP "\fB--create-rc \fIfile"
+When
+\fB\*p\fP
+supports run-time configuration,
+this can be used to dump a sample configuration file to the file specified
+by
+.IR file "."
+.
+.IP "\fB--date-format \fIformat"
+If the host provides \fBstrftime\fP,
+this option allows you to specify the format of the date printed for
+the \fB--calendar\fP widget.
+The time of day (hour, minute, second) are the current local time.
+.
+.IP "\fB--defaultno"
+Make the default value of the
+\fByes/no\fP
+box a
+.BR No .
+Likewise, make the default button of widgets that provide "OK" and "Cancel"
+a \fBCancel\fP.
+If "\fB--nocancel\fP" or "\fB--visit-items\fP" are given
+those options overrides this,
+making the default button always "Yes" (internally the same as "OK").
+.
+.IP "\fB--default-button \fIstring"
+Set the default (preselected) button in a widget.
+By preselecting a button,
+a script makes it possible for the user to simply press \fIEnter\fP
+to proceed through a dialog with minimum interaction.
+.IP
+The option's value is the name of the button:
+.IR ok ,
+.IR yes ,
+.IR cancel ,
+.IR no ,
+.IR help "\ or"
+.IR extra .
+.IP
+Normally the first button in each widget is the default.
+The first button shown is determined by the widget
+together with the "\fB--nook\fP" and "\fB--nocancel\fP options.
+If this option is not given, there is no default button assigned.
+.
+.IP "\fB--default-item \fIstring"
+Set the default item in a checklist, form or menu box.
+Normally the first item in the box is the default.
+.
+.IP "\fB--exit-label \fIstring"
+Override the label used for "EXIT" buttons.
+.
+.IP "\fB--extra-button"
+Show an extra button, between "OK" and "Cancel" buttons.
+.
+.IP "\fB--extra-label \fIstring"
+Override the label used for "Extra" buttons.
+Note: for inputmenu widgets, this defaults to "Rename".
+.
+.IP "\fB--help"
+Prints the help message to the standard output and exits.
+The help message is also printed if no options are given,
+or if an unrecognized option is given.
+.
+.IP "\fB--help-button"
+Show a help-button after "OK" and "Cancel" buttons,
+i.e., in checklist, radiolist and menu boxes.
+If "\fB--item-help\fR" is also given, on exit
+the return status will be the same as for the "OK" button,
+and the item-help text will be written to \fB\*p\fP's output after the token "HELP".
+Otherwise, the return status will indicate that the Help button was pressed,
+and no message printed.
+.
+.IP "\fB--help-label \fIstring"
+Override the label used for "Help" buttons.
+.
+.IP "\fB--help-status"
+If the help-button is selected,
+writes the checklist, radiolist or form information
+after the item-help "HELP" information.
+This can be used to reconstruct the state of a checklist after processing
+the help request.
+.
+.IP "\fB--hfile \fIfilename"
+Display the given file using a textbox when the user presses F1.
+.
+.IP "\fB--hline \fIstring"
+Display the given string centered at the bottom of the widget.
+.
+.IP "\fB--ignore"
+Ignore options that \fB\*p\fP does not recognize.
+Some well-known ones such as "\fB--icon\fP" are ignored anyway,
+but this is a better choice for compatibility with other implementations.
+.
+.IP "\fB--input-fd \fIfd"
+Read keyboard input from the given file descriptor.
+Most \fB\*p\fR scripts read from the standard input,
+but the gauge widget reads a pipe (which is always standard input).
+Some configurations do not work properly when
+\fB\*p\fP tries to reopen the terminal.
+Use this option (with appropriate juggling of file-descriptors)
+if your script must work in that type of environment.
+.
+.IP "\fB--insecure"
+Makes the password widget friendlier but less secure,
+by echoing asterisks for each character.
+.
+.IP "\fB--item-help"
+Interpret the tags data for checklist, radiolist and menu boxes
+adding a column which is displayed in the bottom line of the
+screen, for the currently selected item.
+.
+.IP "\fB--keep-tite"
+When built with \fBncurses\fP,
+\fB\*p\fP normally checks to see if it is running in an \fBxterm\fP,
+and in that case tries to suppress the initialization strings that
+would make it switch to the alternate screen.
+Switching between the normal and alternate screens
+is visually distracting in a script which runs \fB\*p\fP
+several times.
+Use this option to allow \fB\*p\fP to use those initialization strings.
+.
+.IP "\fB--keep-window"
+Normally when \fB\*p\fR performs several \fBtailboxbg\fR widgets
+connected by "\fB--and-widget\fR",
+it clears the old widget from the screen by painting over it.
+Use this option to suppress that repainting.
+.IP
+At exit, \fB\*p\fR repaints all of the widgets which have been
+marked with "\fB--keep-window\fR", even if they are not \fBtailboxbg\fR widgets.
+That causes them to be repainted in reverse order.
+See the discussion of the "\fB--clear\fR" option for examples.
+.
+.IP "\fB--max-input \fIsize"
+Limit input strings to the given size.
+If not specified, the limit is 2048.
+.
+.IP "\fB--no-cancel"
+.IP "\fB--nocancel"
+Suppress the "Cancel" button in checklist, inputbox and menu box modes.
+A script can still test if the user pressed the ESC key to cancel to quit.
+.
+.IP "\fB--no-collapse"
+Normally \fB\*p\fR converts tabs to spaces and reduces multiple
+spaces to a single space for text which is displayed in a message boxes, etc.
+Use this option to disable that feature.
+Note that \fB\*p\fR will still wrap text,
+subject to the "\fB--cr-wrap\fR" and "\fB--trim\fR" options.
+.
+.IP "\fB--no-items"
+Some widgets (checklist, inputmenu, radiolist, menu) display a list
+with two columns (a "tag" and "item", i.e., "description").
+This option tells \fB\*p\fP to read shorter rows,
+omitting the "item" part of the list.
+This is occasionally useful, e.g., if the tags provide enough information.
+.IP
+See also \fB--no-tags\fP.
+If both options are given, this one is ignored.
+.
+.IP "\fB--no-kill"
+Tells
+\fB\*p\fP
+to put the
+\fBtailboxbg\fP
+box in the background,
+printing its process id to \fB\*p\fP's output.
+SIGHUP is disabled for the background process.
+.
+.IP "\fB--no-label \fIstring"
+Override the label used for "No" buttons.
+.
+.IP "\fB--no-lines
+Rather than draw lines around boxes, draw spaces in the same place.
+See also "\fB--ascii-lines\fR".
+.
+.IP "\fB--no-mouse
+Do not enable the mouse.
+.
+.IP "\fB--no-nl-expand
+Do not convert "\\n" substrings of the message/prompt text into
+literal newlines.
+.
+.IP "\fB--no-ok"
+.IP "\fB--nook"
+Suppress the "OK" button in checklist, inputbox and menu box modes.
+A script can still test if the user pressed the "Enter" key to accept the data.
+.
+.IP "\fB--no-shadow"
+Suppress shadows that would be drawn to the right and bottom of each dialog box.
+.
+.IP "\fB--no-tags"
+Some widgets (checklist, inputmenu, radiolist, menu) display a list
+with two columns (a "tag" and "description").
+The tag is useful for scripting, but may not help the user.
+The \fB--no-tags\fP option (from Xdialog) may be used to suppress the
+column of tags from the display.
+Unlike the \fB--no-items\fP option,
+this does not affect the data which is read from the script.
+.IP
+Xdialog does not display the tag column for the analogous buildlist
+and treeview widgets; \fB\*p\fP does the same.
+.IP
+Normally \fB\*p\fP allows you to quickly move to entries on the displayed list,
+by matching a single character to the first character of the tag.
+When the \fB--no-tags\fP option is given, \fB\*p\fP matches against
+the first character of the description.
+In either case, the matchable character is highlighted.
+.
+.IP "\fB--ok-label \fIstring"
+Override the label used for "OK" buttons.
+.
+.IP "\fB--output-fd \fIfd"
+Direct output to the given file descriptor.
+Most \fB\*p\fR scripts write to the standard error,
+but error messages may also be written there, depending on your script.
+.
+.IP "\fB--separator \fIstring"
+.IP "\fB--output-separator\fIstring"
+Specify a string that will separate the output on \fB\*p\fP's output from
+checklists, rather than a newline (for --separate-output) or a space.
+This applies to other widgets such as forms and editboxes which normally
+use a newline.
+.
+.IP "\fB--print-maxsize"
+Print the maximum size of dialog boxes, i.e., the screen size,
+to \fB\*p\fP's output.
+This may be used alone, without other options.
+.
+.IP "\fB--print-size"
+Prints the size of each dialog box to \fB\*p\fP's output.
+.
+.IP "\fB--print-version"
+Prints \fB\*p\fR's version to \fB\*p\fP's output.
+This may be used alone, without other options.
+It does not cause \fBdialog\fP to exit by itself.
+.
+.IP "\fB--quoted"
+Normally \fB\*p\fP quotes the strings returned by checklist's
+as well as the item-help text.
+Use this option to quote all string results.
+.
+.IP "\fB--scrollbar"
+For widgets holding a scrollable set of data,
+draw a scrollbar on its right-margin.
+This does not respond to the mouse.
+.
+.IP "\fB--separate-output"
+For checklist widgets, output result one line at a time, with no quoting.
+This facilitates parsing by another program.
+.
+.IP "\fB--separate-widget \fIstring"
+Specify a string that will separate the output on \fB\*p\fP's output from
+each widget.
+This is used to simplify parsing the result of a dialog with several widgets.
+If this option is not given,
+the default separator string is a tab character.
+.
+.IP "\fB--shadow"
+Draw a shadow to the right and bottom of each dialog box.
+.
+.IP "\fB--single-quoted"
+Use single-quoting as needed (and no quotes if unneeded) for the
+output of checklist's as well as the item-help text.
+If this option is not set, \fB\*p\fP uses double quotes around each item.
+In either case,
+\fB\*p\fP adds backslashes to make the output useful in shell scripts.
+.
+.IP "\fB--size-err"
+Check the resulting size of a dialog box before trying to use it,
+printing the resulting size if it is larger than the screen.
+(This option is obsolete, since all new-window calls are checked).
+.
+.IP "\fB--sleep \fIsecs"
+Sleep (delay) for the given number of seconds after processing a dialog box.
+.
+.IP "\fB--stderr"
+Direct output to the standard error.
+This is the default, since curses normally writes screen updates to
+the standard output.
+.
+.IP "\fB--stdout"
+Direct output to the standard output.
+This option is provided for compatibility with Xdialog,
+however using it in portable scripts is not recommended,
+since curses normally writes its screen updates to the standard output.
+If you use this option, \fB\*p\fR attempts to reopen the terminal
+so it can write to the display.
+Depending on the platform and your environment, that may fail.
+.
+.IP "\fB--tab-correct"
+Convert each tab character to one or more spaces
+(for the \fBtextbox\fP widget; otherwise to a single space).
+Otherwise, tabs are rendered according to the curses library's interpretation.
+.
+.IP "\fB--tab-len \fIn"
+Specify the number of spaces that a tab character occupies if the
+"\fB--tab-correct\fP" option is given.
+The default is 8.
+This option is only effective for the \fBtextbox\fP widget.
+.
+.IP "\fB--time-format \fIformat"
+If the host provides \fBstrftime\fP,
+this option allows you to specify the format of the time printed for
+the \fB--timebox\fP widget.
+The day, month, year values in this case are for the current local time.
+.
+.IP "\fB--timeout \fIsecs"
+Timeout (exit with error code)
+if no user response within the given number of seconds.
+A timeout of zero seconds is ignored.
+.IP
+This option is ignored by the "\fB--pause\fP" widget.
+It is also overridden if the background "\fB--tailboxbg\fP" option is used
+to setup multiple concurrent widgets.
+.
+.IP "\fB--title \fItitle"
+Specifies a
+\fItitle\fP
+string to be displayed at the top of the dialog box.
+.
+.IP "\fB--trace \fIfilename"
+logs the command-line parameters,
+keystrokes and other information to the given file.
+If \fBdialog\fP reads a configure file, it is logged as well.
+Piped input to the \fIgauge\fP widget is logged.
+Use control/T to log a picture of the current dialog window.
+.PP
+The \fB\*p\fR program handles some command-line parameters specially,
+and removes them from the parameter list as they are processed.
+For example, if the first option is \fB--trace\fP,
+then that is processed (and removed) before \fB\*p\fR initializes the display.
+.
+.IP "\fB--trim"
+eliminate leading blanks,
+trim literal newlines and repeated blanks from message text.
+.
+.IP
+See also the "\fB--cr-wrap\fR" and "\fB--no-collapse\fR" options.
+.
+.IP "\fB--version"
+Prints \fB\*p\fR's version to the standard output, and exits.
+See also "\fB--print-version\fP".
+.
+.IP "\fB--visit-items"
+Modify the tab-traversal of checklist, radiolist, menubox and inputmenu
+to include the list of items as one of the states.
+This is useful as a visual aid,
+i.e., the cursor position helps some users.
+.IP
+When this option is given, the cursor is initially placed on the list.
+Abbreviations (the first letter of the tag) apply to the list items.
+If you tab to the button row, abbreviations apply to the buttons.
+.
+.IP "\fB--yes-label \fIstring"
+Override the label used for "Yes" buttons.
+.
+.\" ************************************************************************
+.SS Box Options
+All dialog boxes have at least three parameters:
+.TP 5
+\fItext\fP
+the caption or contents of the box.
+.TP 5
+\fIheight\fP
+the height of the dialog box.
+.TP 5
+\fIwidth\fP
+the width of the dialog box.
+.PP
+Other parameters depend on the box type.
+.
+.
+.IP "\fB--buildlist \fItext height width \fR[ \fItag item status \fR] \fI..."
+A \fBbuildlist\fP dialog displays two lists, side-by-side.
+The list on the left shows unselected items.
+The list on the right shows selected items.
+As items are selected or unselected, they move between the lists.
+.IP
+Use a carriage return or the "OK" button to accept the current value
+in the selected-window and exit.
+The results are written using the order displayed in the selected-window.
+.IP
+The initial on/off state of each entry is specified by
+.IR status "."
+.IP
+The dialog behaves like a \fBmenu\fP, using the \fB--visit-items\fP
+to control whether the cursor is allowed to visit the lists directly.
+.RS
+.bP
+If \fB--visit-items\fP is not given,
+tab-traversal uses two states (OK/Cancel).
+.bP
+If \fB--visit-items\fP is given,
+tab-traversal uses four states (Left/Right/OK/Cancel).
+.RE
+.IP
+Whether or not \fB--visit--items\fP is given,
+it is possible to move the highlight between the two lists using
+the default "^" (left-column) and "$" (right-column) keys.
+.IP
+On exit, a list of the \fItag\fP
+strings of those entries that are turned on
+will be printed on \fB\*p\fP's output.
+.IP
+If the "\fB--separate-output\fP" option is not given,
+the strings will be quoted as needed to make it simple for scripts to separate them.
+By default, this uses double-quotes.
+See the "\fB--single-quoted\fP" option, which modifies the quoting behavior.
+.
+.
+.IP "\fB--calendar \fItext height width day month year"
+A \fBcalendar\fP box displays
+month, day and year in separately adjustable windows.
+If the values for day, month or year are missing or negative,
+the current date's corresponding values are used.
+You can increment or decrement any of those using the
+left-, up-, right- and down-arrows.
+Use vi-style h, j, k and l for moving around the array of days in a month.
+Use tab or backtab to move between windows.
+If the year is given as zero, the current date is used as an initial value.
+.IP
+On exit, the date is printed in the form day/month/year.
+The format can be overridden using the \fB--date-format\fP option.
+.
+.
+.IP "\fB--checklist \fItext height width list-height \fR[ \fItag item status \fR] \fI..."
+A
+\fBchecklist\fP
+box is similar to a
+\fBmenu\fP
+box; there are
+multiple entries presented in the form of a menu.
+Another difference is
+that you can indicate which entry is currently selected, by setting its
+.IR status " to " on "."
+Instead of choosing
+one entry among the entries, each entry can be turned on or off by the user.
+The initial on/off state of each entry is specified by
+.IR status "."
+.IP
+On exit, a list of the \fItag\fP
+strings of those entries that are turned on
+will be printed on \fB\*p\fP's output.
+.IP
+If the "\fB--separate-output\fP" option is not given,
+the strings will be quoted as needed to make it simple for scripts to separate them.
+By default, this uses double-quotes.
+See the "\fB--single-quoted\fP" option, which modifies the quoting behavior.
+.
+.
+.IP "\fB--dselect \fIfilepath height width\fR"
+The directory-selection dialog displays a text-entry window in which you can type
+a directory, and above that a windows with directory names.
+.IP
+Here
+\fBfilepath\fP
+can be a filepath in which case the directory window
+will display the contents of the path and the text-entry window will contain
+the preselected directory.
+.IP
+Use tab or arrow keys to move between the windows.
+Within the directory window, use the up/down arrow keys
+to scroll the current selection.
+Use the space-bar to copy the current selection into the text-entry
+window.
+.IP
+Typing any printable characters switches focus to the text-entry window,
+entering that character as well as scrolling the directory
+window to the closest match.
+.IP
+Use a carriage return or the "OK" button to accept the current value
+in the text-entry window and exit.
+.IP
+On exit, the contents of the text-entry window are written to \fB\*p\fP's output.
+.
+.IP "\fB--editbox \fIfilepath height width\fR"
+The edit-box dialog displays a copy of the file.
+You may edit it using
+the \fIbackspace\fP, \fIdelete\fP and cursor keys
+to correct typing errors.
+It also recognizes pageup/pagedown.
+Unlike the \fB--inputbox\fP,
+you must tab to the "OK" or "Cancel" buttons to close the dialog.
+Pressing the "Enter" key within the box will split the corresponding line.
+.IP
+On exit, the contents of the edit window are written to \fB\*p\fP's output.
+.
+.nf
+.IP "\fB--form \fItext height width formheight \fR[ \fIlabel y x item y x flen ilen \fR] \fI..."
+.fi
+The \fBform\fP dialog displays a form consisting of labels and fields,
+which are positioned on a scrollable window by coordinates given in the script.
+The field length \fIflen\fR and input-length \fIilen\fR tell how long
+the field can be.
+The former defines the length shown for a selected field,
+while the latter defines the permissible length of the data entered in the
+field.
+.RS
+.bP
+If \fIflen\fR is zero, the corresponding field cannot be altered.
+and the contents of the field determine the displayed-length.
+.bP
+If \fIflen\fR is negative, the corresponding field cannot be altered,
+and the negated value of \fIflen\fR is used as the displayed-length.
+.bP
+If \fIilen\fR is zero, it is set to \fIflen\fR.
+.RE
+.IP
+Use up/down arrows (or control/N, control/P) to move between fields.
+Use tab to move between windows.
+.IP
+On exit, the contents of the form-fields are written to \fB\*p\fP's output,
+each field separated by a newline.
+The text used to fill non-editable fields
+(\fIflen\fR is zero or negative)
+is not written out.
+.
+.
+.IP "\fB--fselect \fIfilepath height width\fR"
+The \fBfselect\fP (file-selection) dialog displays a text-entry window in which you can type
+a filename (or directory), and above that two windows with directory
+names and filenames.
+.IP
+Here
+\fBfilepath\fP
+can be a filepath in which case the file and directory windows
+will display the contents of the path and the text-entry window will contain
+the preselected filename.
+.IP
+Use tab or arrow keys to move between the windows.
+Within the directory or filename windows, use the up/down arrow keys
+to scroll the current selection.
+Use the space-bar to copy the current selection into the text-entry
+window.
+.IP
+Typing any printable characters switches focus to the text-entry window,
+entering that character as well as scrolling the directory and filename
+windows to the closest match.
+.IP
+Typing the space character forces \fB\*p\fP to complete the current
+name (up to the point where there may be a match against more than one
+entry).
+.IP
+Use a carriage return or the "OK" button to accept the current value
+in the text-entry window and exit.
+.IP
+On exit, the contents of the text-entry window are written to \fB\*p\fP's output.
+.
+.
+.IP "\fB--gauge \fItext height width [percent]\fR"
+A
+\fBgauge\fP
+box displays a meter along the bottom of the box.
+The meter indicates the percentage.
+New percentages are read from
+standard input, one integer per line.
+The meter is updated
+to reflect each new percentage.
+If the standard input reads the string "XXX",
+then the first line following is taken as an integer percentage,
+then subsequent lines up to another "XXX" are used for a new prompt.
+The gauge exits when EOF is reached on the standard input.
+.IP
+The \fIpercent\fR value denotes the initial percentage shown in the meter.
+If not specified, it is zero.
+.IP
+On exit, no text is written to \fB\*p\fP's output.
+The widget accepts no input, so the exit status is always OK.
+.
+.
+.IP "\fB--infobox \fItext height width"
+An \fBinfo\fP box is basically a \fBmessage\fP box.
+However, in this case, \fB\*p\fP
+will exit immediately after displaying the message to the user.
+The screen is not cleared when \fB\*p\fP
+exits, so that the message will remain on the screen until the calling
+shell script clears it later.
+This is useful when you want to inform
+the user that some operations are carrying on that may require some
+time to finish.
+.IP
+On exit, no text is written to \fB\*p\fP's output.
+Only an "OK" button is provided for input,
+but an ESC exit status may be returned.
+.
+.
+.IP "\fB--inputbox \fItext height width [init]"
+An
+\fBinput\fP
+box is useful when you want to ask questions that
+require the user to input a string as the answer.
+If init is supplied
+it is used to initialize the input string.
+When entering the string,
+the \fIbackspace\fP, \fIdelete\fP and cursor keys
+can be used to correct typing errors.
+If the input string is longer than
+can fit in the dialog box, the input field will be scrolled.
+.IP
+On exit, the input string will be printed on \fB\*p\fP's output.
+.
+.
+.IP "\fB--inputmenu \fItext height width menu-height \fR[ \fItag item \fR] \fI..."
+An \fBinputmenu\fP box is very similar to an ordinary \fBmenu\fP box.
+There are only a few differences between them:
+.RS
+.TP 4
+1.
+The entries are not automatically centered but left adjusted.
+.TP
+2.
+An extra button (called \fIRename\fP) is implied to rename
+the current item when it is pressed.
+.TP
+3.
+It is possible to rename the current entry by pressing the
+\fIRename\fP
+button.
+Then \fB\*p\fP will write the following on \fB\*p\fP's output.
+.IP
+RENAMED <tag> <item>
+.RE
+.
+.
+.IP "\fB--menu \fItext height width menu-height \fR[ \fItag item \fR] \fI..."
+As its name suggests, a
+\fBmenu\fP
+box is a dialog box that can be used to present a list of choices in
+the form of a menu for the user to choose.
+Choices are displayed in the order given.
+Each menu entry consists of a \fItag\fP string and an \fIitem\fP string.
+The \fItag\fP
+gives the entry a name to distinguish it from the other entries in the
+menu.
+The \fIitem\fP is a short description of the option that the entry represents.
+The user can move between the menu entries by pressing the
+cursor keys, the first letter of the \fItag\fP
+as a hot-key, or the number keys
+.IR 1-9 ". There are"
+\fImenu-height\fP
+entries displayed in the menu at one time, but the menu will be
+scrolled if there are more entries than that.
+.IP
+On exit the \fItag\fP
+of the chosen menu entry will be printed on \fB\*p\fP's output.
+If the "\fB--help-button\fR" option is given, the corresponding help
+text will be printed if the user selects the help button.
+.
+.nf
+.IP "\fB--mixedform \fItext height width formheight \fR[ \fIlabel y x item y x flen ilen itype \fR] \fI..."
+.fi
+The \fBmixedform\fP dialog displays a form consisting of labels and fields,
+much like the \fB--form\fP dialog.
+It differs by adding a field-type parameter to each field's description.
+Each bit in the type denotes an attribute of the field:
+.RS
+.TP 5
+1
+hidden, e.g., a password field.
+.TP 5
+2
+readonly, e.g., a label.
+.RE
+.
+.IP "\fB--mixedgauge \fItext height width percent \fR[ \fItag1 item1 \fR] \fI..."
+A
+\fBmixedgauge\fP
+box displays a meter along the bottom of the box.
+The meter indicates the percentage.
+.IP
+It also displays a list of the \fItag\fP- and \fIitem\fP-values at the
+top of the box.
+See \*l(3) for the tag values.
+.IP
+The \fItext\fP is shown as a caption between the list and meter.
+The \fIpercent\fR value denotes the initial percentage shown in the meter.
+.IP
+No provision is made for reading data from the standard input as \fB--gauge\fP
+does.
+.IP
+On exit, no text is written to \fB\*p\fP's output.
+The widget accepts no input, so the exit status is always OK.
+.
+.IP "\fB--msgbox \fItext height width"
+A \fBmessage\fP box is very similar to a \fByes/no\fP box.
+The only difference between a \fBmessage\fP box and a \fByes/no\fP
+box is that a \fBmessage\fP box has only a single \fBOK\fP button.
+You can use this dialog box to display any message you like.
+After reading the message, the user can press the \fIENTER\fP key so that
+\fB\*p\fP will exit and the calling shell script can continue its operation.
+.IP
+If the message is too large for the space,
+\fB\*p\fP may allow you to scroll it,
+provided that the underlying curses implementation is capable enough.
+In this case, a percentage is shown in the base of the widget.
+.IP
+On exit, no text is written to \fB\*p\fP's output.
+Only an "OK" button is provided for input,
+but an ESC exit status may be returned.
+.
+.IP "\fB--pause \fItext height width seconds\fR"
+A
+\fBpause\fP
+box displays a meter along the bottom of the box.
+The meter indicates how many seconds remain until the end of the pause.
+The pause exits when timeout is reached
+or the user presses the OK button
+(status OK)
+or the user presses the CANCEL button
+or Esc key.
+.IP "\fB--passwordbox \fItext height width [init]"
+A \fBpassword\fP box is similar to an input box,
+except that the text the user enters is not displayed.
+This is useful when prompting for passwords or other
+sensitive information.
+Be aware that if anything is passed in "init", it
+will be visible in the system's process table to casual snoopers.
+Also, it
+is very confusing to the user to provide them with a default password they
+cannot see.
+For these reasons, using "init" is highly discouraged.
+See "\fB--insecure\fP" if you do not care about your password.
+.IP
+On exit, the input string will be printed on \fB\*p\fP's output.
+.
+.
+.nf
+.IP "\fB--passwordform \fItext height width formheight \fR[ \fIlabel y x item y x flen ilen \fR] \fI..."
+.fi
+This is identical to \fB--form\fP except that all text fields are
+treated as \fBpassword\fP widgets rather than \fBinputbox\fP widgets.
+.
+.
+.IP "\fB--prgbox \fItext command height width"
+.IP "\fB--prgbox \fIcommand height width"
+A \fBprgbox\fP is very similar to a \fBprogrambox\fP.
+.IP
+This dialog box is used to display the output of a command that is
+specified as an argument to \fBprgbox\fP.
+.IP
+After the command completes, the user can press the \fIENTER\fP key so that
+\fBdialog\fP will exit and the calling shell script can continue its operation.
+.IP
+If three parameters are given, it displays the text under the title,
+delineated from the scrolling file's contents.
+If only two parameters are given, this text is omitted.
+.
+.
+.IP "\fB--programbox \fItext height width"
+.IP "\fB--programbox \fIheight width"
+A \fBprogrambox\fP is very similar to a \fBprogressbox\fP.
+The only difference between a \fBprogram\fP box and a \fBprogress\fP
+box is that a \fBprogram\fP box displays an \fBOK\fP button
+(but only after the command completes).
+.IP
+This dialog box is used to display the piped output of a command.
+After the command completes, the user can press the \fIENTER\fP key so that
+\fBdialog\fP will exit and the calling shell script can continue its operation.
+.IP
+If three parameters are given, it displays the text under the title,
+delineated from the scrolling file's contents.
+If only two parameters are given, this text is omitted.
+.
+.
+.IP "\fB--progressbox \fItext height width"
+.IP "\fB--progressbox \fIheight width"
+A \fBprogressbox\fP is similar to an \fBtailbox\fP,
+except that
+.RS
+.TP 3
+a) rather than displaying the contents of a file,
+it displays the piped output of a command and
+.TP 3
+b) it will exit when it reaches the end of the file
+(there is no "OK" button).
+.RE
+.IP
+If three parameters are given, it displays the text under the title,
+delineated from the scrolling file's contents.
+If only two parameters are given, this text is omitted.
+.
+.
+.IP "\fB--radiolist \fItext height width list-height \fR [ \fItag item status \fR] \fI..."
+A
+\fBradiolist\fP
+box is similar to a
+\fBmenu\fP
+box.
+The only difference is
+that you can indicate which entry is currently selected, by setting its
+.IR status " to " on "."
+.IP
+On exit, the tag of the selected item is written to \fB\*p\fP's output.
+.
+.
+.IP "\fB--tailbox \fIfile height width"
+Display text from a file in a dialog box, as in a "tail -f" command.
+Scroll left/right using vi-style 'h' and 'l', or arrow-keys.
+A '0' resets the scrolling.
+.IP
+On exit, no text is written to \fB\*p\fP's output.
+Only an "OK" button is provided for input,
+but an ESC exit status may be returned.
+.
+.
+.nf
+.IP "\fB--rangebox \fItext height width list-height min-value max-value default-value"
+.fi
+Allow the user to select from a range of values, e.g., using a slider.
+The dialog shows the current value as a bar (like the gauge dialog).
+Tabs or arrow keys move the cursor between the buttons and the value.
+When the cursor is on the value,
+you can edit it by:
+.RS
+.TP 5
+left/right cursor movement to select a digit to modify
+.TP 5
++/-
+characters to increment/decrement the digit by one
+.TP 5
+0 through 9
+to set the digit to the given value
+.RE
+.IP
+Some keys are also recognized in all cursor positions:
+.RS
+.TP 5
+home/end
+set the value to its maximum or minimum
+.TP 5
+pageup/pagedown
+increment the value so that the slider moves by one column
+.RE
+.
+.
+.IP "\fB--tailboxbg \fIfile height width"
+Display text from a file in a dialog box as a background task,
+as in a "tail -f &" command.
+Scroll left/right using vi-style 'h' and 'l', or arrow-keys.
+A '0' resets the scrolling.
+.IP
+\*L treats the background task specially if there are other
+widgets (\fB--and-widget\fP) on the screen concurrently.
+Until those widgets are closed (e.g., an "OK"),
+\fB\*p\fP will perform all of the tailboxbg widgets in the same process,
+polling for updates.
+You may use a tab to traverse between the widgets on the screen,
+and close them individually, e.g., by pressing \fIENTER\fP.
+Once the non-tailboxbg widgets are closed, \fB\*p\fP forks a copy of itself
+into the background, and prints its process id if the "\fB--no-kill\fP" option
+is given.
+.IP
+On exit, no text is written to \fB\*p\fP's output.
+Only an "EXIT" button is provided for input,
+but an ESC exit status may be returned.
+.IP
+NOTE:
+Older versions of \fB\*p\fP forked immediately and attempted to
+update the screen individually.
+Besides being bad for performance,
+it was unworkable.
+Some older scripts may not work properly with the polled scheme.
+.
+.
+.IP "\fB--textbox \fIfile height width"
+A
+\fBtext\fP
+box lets you display the contents of a text file in a dialog box.
+It is like a simple text file viewer.
+The user can move through the file by using the
+cursor, page-up, page-down
+and \fIHOME/END\fR keys available on most keyboards.
+If the lines are too long to be displayed in the box,
+the \fILEFT/RIGHT\fP
+keys can be used to scroll the text region horizontally.
+You may also use vi-style keys h, j, k, l in place of the cursor keys,
+and B or N in place of the page-up and page-down keys.
+Scroll up/down using vi-style 'k' and 'j', or arrow-keys.
+Scroll left/right using vi-style 'h' and 'l', or arrow-keys.
+A '0' resets the left/right scrolling.
+For more convenience,
+vi-style forward and backward searching functions are also provided.
+.IP
+On exit, no text is written to \fB\*p\fP's output.
+Only an "EXIT" button is provided for input,
+but an ESC exit status may be returned.
+.
+.
+.IP "\fB--timebox \fItext height [width hour minute second]"
+A dialog is displayed which allows you to select hour, minute and second.
+If the values for hour, minute or second are missing or negative,
+the current date's corresponding values are used.
+You can increment or decrement any of those using the
+left-, up-, right- and down-arrows.
+Use tab or backtab to move between windows.
+.IP
+On exit, the result is printed in the form hour:minute:second.
+The format can be overridden using the \fB--time-format\fP option.
+.
+.
+.IP "\fB--treeview \fItext height width list-height \fR[ \fItag item status depth \fR] \fI..."
+Display data organized as a tree.
+Each group of data contains a tag,
+the text to display for the item,
+its status ("on" or "off")
+and the depth of the item in the tree.
+.IP
+Only one item can be selected (like the \fBradiolist\fP).
+The tag is not displayed.
+.IP
+On exit, the tag of the selected item is written to \fB\*p\fP's output.
+.
+.
+.IP "\fB--yesno \fItext height width"
+A \fByes/no\fP dialog box of
+size \fIheight\fP rows by \fIwidth\fP columns will be displayed.
+The string specified by
+\fItext\fP
+is displayed inside the dialog box.
+If this string is too long to fit
+in one line, it will be automatically divided into multiple lines at
+appropriate places.
+The
+\fItext\fP
+string can also contain the sub-string
+.I
+"\en"
+or newline characters
+\fI`\en'\fP
+to control line breaking explicitly.
+This dialog box is useful for
+asking questions that require the user to answer either yes or no.
+The dialog box has a
+\fBYes\fP
+button and a
+\fBNo\fP
+button, in which the user can switch between by pressing the
+.IR TAB " key."
+.IP
+On exit, no text is written to \fB\*p\fP's output.
+In addition to the "Yes" and "No" exit codes (see DIAGNOSTICS)
+an ESC exit status may be returned.
+.IP
+The codes used for "Yes" and "No" match those used for "OK" and "Cancel",
+internally no distinction is made.
+.
+.\" ************************************************************************
+.SS "Obsolete Options"
+.\" from cdialog 0.9a (Pako)
+.IP "\fB--beep"
+This was used to tell the original cdialog that it should make a beep
+when the separate processes of the tailboxbg widget would repaint the screen.
+.
+.\" from cdialog 0.9a (Pako)
+.IP "\fB--beep-after"
+Beep after a user has completed a widget by pressing one of the buttons.
+.
+.\" ************************************************************************
+.SH "RUN-TIME CONFIGURATION"
+.TP 4
+1.
+Create a sample configuration file by typing:
+.LP
+.in +1i
+"\*p --create-rc <file>"
+.TP 4
+2.
+At start,
+\fB\*p\fP
+determines the settings to use as follows:
+.RS
+.TP 4
+a)
+if environment variable
+\fBDIALOGRC\fP
+is set, its value determines the name of the configuration file.
+.TP 4
+b)
+if the file in (a) is not found, use the file
+\fI$HOME/.dialogrc\fP
+as the configuration file.
+.TP 4
+c)
+if the file in (b) is not found, try using the GLOBALRC file determined at
+compile-time, i.e., \fI/etc/dialogrc\fP.
+.TP 4
+d)
+if the file in (c) is not found, use compiled in defaults.
+.RE
+.TP 4
+3.
+Edit the sample configuration file and copy it to some place that
+\fB\*p\fP
+can find, as stated in step 2 above.
+.
+.\" ************************************************************************
+.SH "KEY BINDINGS"
+You can override or add to key bindings in \fB\*p\fP
+by adding to the configuration file.
+\fB\*L\fP's \fBbindkey\fP command maps single keys to its internal coding.
+.Ex
+bindkey \fIwidget\fP \fIcurses_key\fP \fIdialog_key\fP
+.Ee
+.PP
+The \fIwidget\fP name can be "*" (all widgets), or
+specific widgets such as \fBtextbox\fP.
+Specific widget bindings override the "*" bindings.
+User-defined bindings override the built-in bindings.
+.PP
+The \fIcurses_key\fP can be any of the names derived from
+\fBcurses.h\fP, e.g., "HELP" from "KEY_HELP".
+\fB\*L\fP also recognizes ANSI control characters such as "^A", "^?",
+as well as C1-controls such as "~A" and "~?".
+Finally, it allows any single character to be escaped with a backslash.
+.PP
+\fB\*L\fP's internal keycode names correspond to the
+\fBDLG_KEYS_ENUM\fP type in
+\fBdlg_keys.h\fP, e.g., "HELP" from "DLGK_HELP".
+.SS Widget Names
+.PP
+Some widgets (such as the formbox) have an area where fields can be edited.
+Those are managed in a subwindow of the widget, and
+may have separate keybindings from the main widget
+because the subwindows are registered using a different name.
+.TS
+center tab(/) ;
+l l l
+l l l .
+\fIWidget\fR/\fIWindow name\fR/\fISubwindow Name\fR
+calendar/calendar
+checklist/checklist
+editbox/editbox/editbox2
+form/formbox/formfield
+fselect/fselect/fselect2
+inputbox/inputbox/inputbox2
+menu/menubox/menu
+msgbox/msgbox
+pause/pause
+progressbox/progressbox
+radiolist/radiolist
+tailbox/tailbox
+textbox/textbox/searchbox
+timebox/timebox
+yesno/yesno
+.TE
+.PP
+Some widgets are actually other widgets,
+using internal settings to modify the behavior.
+Those use the same widget name as the actual widget:
+.TS
+center tab(/) ;
+l l
+l l .
+\fIWidget\fR/\fIActual Widget\fR
+dselect/fselect
+infobox/msgbox
+inputmenu/menu
+mixedform/form
+passwordbox/inputbox
+passwordform/form
+prgbox/progressbox
+programbox/progressbox
+tailboxbg/tailbox
+.TE
+.SS Built-in Bindings
+This manual page does not list the key bindings for each widget,
+because that detailed information can be obtained by running \fB\*p\fP.
+If you have set the \fB--trace\fP option,
+\fB\*p\fP writes the key-binding information for each widget
+as it is registered.
+.SS Example
+Normally \fB\*p\fP uses different keys for navigating between the buttons
+and editing part of a dialog versus navigating within the editing part.
+That is, tab (and back-tab) traverse buttons
+(or between buttons and the editing part),
+while arrow keys traverse fields within the editing part.
+Tabs are also recognized as a special case for traversing between
+widgets, e.g., when using multiple tailboxbg widgets.
+.PP
+Some users may wish to use the same key for traversing within the
+editing part as for traversing between buttons.
+The form widget is written to support this sort of redefinition of
+the keys, by adding a special group in <code>dlgk_keys.h</code>
+for "form" (left/right/next/prev).
+Here is an example binding demonstrating how to do this:
+.Ex
+bindkey formfield TAB  form_NEXT
+bindkey formbox   TAB  form_NEXT
+bindkey formfield BTAB form_prev
+bindkey formbox   BTAB form_prev
+.Ee
+.PP
+That type of redefinition would not be useful in other widgets,
+e.g., calendar, due to the potentially large number of fields to traverse.
+.
+.\" ************************************************************************
+.SH ENVIRONMENT
+.TP 15
+\fBDIALOGOPTS\fP
+Define this variable to apply any of the common options to each widget.
+Most of the common options are reset before processing each widget.
+If you set the options in this environment variable,
+they are applied to \fB\*p\fP's state after the reset.
+As in the "\fB--file\fP" option,
+double-quotes and backslashes are interpreted.
+.IP
+The "\fB--file\fP" option is not considered a common option
+(so you cannot embed it within this environment variable).
+.TP 15
+\fBDIALOGRC\fP
+Define this variable if you want to specify the name of the configuration file
+to use.
+.TP 15
+\fBDIALOG_CANCEL\fP
+.TP 15
+\fBDIALOG_ERROR\fP
+.TP 15
+\fBDIALOG_ESC\fP
+.TP 15
+\fBDIALOG_EXTRA\fP
+.TP 15
+\fBDIALOG_HELP\fP
+.TP 15
+\fBDIALOG_ITEM_HELP\fP
+.TP 15
+\fBDIALOG_OK\fP
+Define any of these variables to change the exit code on
+Cancel (1),
+error (-1),
+ESC (255),
+Extra (3),
+Help (2),
+Help with \fB--item-help\fP (2),
+or OK (0).
+Normally shell scripts cannot distinguish between -1 and 255.
+.TP 15
+\fBDIALOG_TTY\fP
+Set this variable to "1" to provide compatibility with older versions
+of \fB\*p\fP which assumed that if the script redirects the standard output,
+that the "\fB--stdout\fP" option was given.
+.SH FILES
+.TP 20
+\fI$HOME/.dialogrc\fP
+default configuration file
+.SH EXAMPLES
+The \fB\*p\fP sources contain several samples
+of how to use the different box options and how they look.
+Just take a look into the directory \fBsamples/\fP of the source.
+.SH DIAGNOSTICS
+Exit status is subject to being overridden by environment variables.
+The default values and corresponding environment variables
+that can override them are:
+.TP 5
+0
+if
+.BR \*p " is exited by pressing the " Yes " or " OK
+button (DIALOG_OK).
+.TP 5
+1
+if the
+.BR No " or " Cancel
+button is pressed (DIALOG_CANCEL).
+.TP 5
+2
+if the
+.BR Help
+button is pressed (DIALOG_HELP).
+.TP 5
+3
+if the
+.BR Extra
+button is pressed (DIALOG_EXTRA).
+.TP 5
+4
+if the
+.BR Help
+button is pressed (DIALOG_HELP),
+or the \fB--item-help\fP option is set
+when the \fBHelp\fP button is pressed (DIALOG_ITEM_HELP),
+.TP 5
+-1
+if errors occur inside \fB\*p\fP (DIALOG_ERROR)
+or \fB\*p\fP is exited by pressing the \fIESC\fP key (DIALOG_ESC).
+.
+.\" ************************************************************************
+.SH PORTABILITY
+\fB\*L\fP works with X/Open curses.
+However, some implementations have deficiencies:
+.RS 3
+.bP
+HPUX curses (and perhaps others) do not open the terminal properly for
+the \fInewterm\fP function.
+This interferes with \fB\*p\fP's \fB--input-fd\fP option,
+by preventing cursor-keys and similar escape sequences from being recognized.
+.bP
+NetBSD 5.1 curses has incomplete support for wide-characters.
+\fB\*p\fP will build, but not all examples display properly.
+.RE
+.\" ************************************************************************
+.SH COMPATIBILITY
+You may want to write scripts which run with other \fBdialog\fP "clones".
+.SS ORIGINAL DIALOG
+First, there is the "original" \fBdialog\fP program to consider (versions
+0.3 to 0.9).
+It had some misspelled (or inconsistent) options.
+The \fB\*p\fP program maps those deprecated options to the preferred ones.
+They include:
+.RS
+.TS
+l l
+_ _
+l l.
+\fIOption\fR   \fITreatment\fR
+\fB--beep-after\fP     ignored
+\fB--guage\fP  mapped to \fB--gauge\fP
+.TE
+.RE
+.SS XDIALOG
+Technically, "\fBXdialog\fP",
+this is an X application.
+With some care, it is possible to write useful scripts that work
+with both \fBXdialog\fP and \fBdialog\fP.
+.PP
+The \fB\*p\fP program ignores these options which are recognized
+by \fBXdialog\fP:
+.RS
+.TS
+l l
+_ _
+l l.
+\fIOption\fR   \fITreatment\fR
+\fB--allow-close\fP    ignored
+\fB--auto-placement\fP ignored
+\fB--fixed-font\fP     ignored
+\fB--icon\fP   ignored
+\fB--keep-colors\fP    ignored
+\fB--no-close\fP       ignored
+\fB--no-cr-wrap\fP     ignored
+\fB--screen-center\fP  ignored
+\fB--separator\fP      mapped to \fB--separate-output\fP
+\fB--smooth\fP ignored
+\fB--under-mouse\fP    ignored
+\fB--wmclass\fP        ignored
+.TE
+.RE
+.PP
+\fBXdialog\fP's manpage has a section discussing its compatibility with \fB\*p\fP.
+There are some differences not shown in the manpage.
+For example, the html documentation states
+.RS
+.PP
+Note:  former  Xdialog  releases  used  the  "\n" (line feed) as a
+results  separator  for  the  checklist  widget; this has been
+changed  to  "/"  in  Xdialog v1.5.0 so to make it compatible with
+(c)dialog.  In  your  old scripts using the Xdialog checklist, you
+will  then  have  to  add  the --separate-output option before the
+--checklist one.
+.RE
+.PP
+\fB\*L\fP has not used a different separator;
+the difference was likely due to confusion regarding some script.
+.SS WHIPTAIL
+Then there is \fBwhiptail\fP.
+For practical purposes, it is maintained by Debian
+(very little work is done by its upstream developers).
+Its documentation (README.whiptail) claims
+.RS
+.sp
+.nf
+whiptail(1) is a lightweight replacement for \*p(1),
+to provide dialog boxes for shell scripts.
+It is built on the
+newt windowing library rather than the ncurses library, allowing
+it to be smaller in embedded enviroments such as installers,
+rescue disks, etc.
+.sp
+whiptail is designed to be drop-in compatible with \*p, but
+has less features: some dialog boxes are not implemented, such
+as tailbox, timebox, calendarbox, etc.
+.fi
+.RE
+.PP
+Comparing actual sizes (Debian testing, 2007/1/10):
+The total of sizes for \fBwhiptail\fP, the newt, popt and slang libraries is 757kb.
+The comparable number for \fB\*p\fP (counting ncurses) is 520kb.
+Disregard the first paragraph.
+.PP
+The second paragraph is misleading, since \fBwhiptail\fP
+also does not work for common options of \fB\*p\fP,
+such as the gauge box.
+\fBwhiptail\fP is less compatible with \fB\*p\fP than the
+original mid-1990s dialog 0.4 program.
+.PP
+\fBwhiptail\fP's manpage borrows features from \fB\*p\fP, e.g.,
+but oddly cites only \fB\*p\fP versions up to 0.4 (1994) as a source.
+That is, its manpage refers to features which
+were borrowed from more recent versions of \fB\*p\fP, e.g.,
+.bP
+\fB--gauge\fP (from 0.5)
+.bP
+\fB--passwordbox\fP (from Debian changes in 1999),
+.bP
+\fB--default-item\fP (from \fB\*p\fP 2000/02/22),
+.bP
+\fB--output-fd\fP (from \fB\*p\fP 2002/08/14).
+.PP
+Somewhat humorously, one may note that the \fBpopt\fP feature
+(undocumented in its manpage)
+of using a "--" as an escape was documented in \fB\*p\fP's manpage about
+a year before it was mentioned in \fBwhiptail\fP's manpage.
+\fBwhiptail\fP's manpage incorrectly attributes that to \fBgetopt\fP
+(and is inaccurate anyway).
+.PP
+Debian uses \fBwhiptail\fP for the official \fB\*p\fP variation.
+.PP
+The \fB\*p\fP program ignores or maps these options which are recognized
+by \fBwhiptail\fP:
+.RS
+.TS
+l l
+_ _
+l l.
+\fIOption\fR   \fITreatment\fR
+\fB--cancel-button\fP  mapped to \fB--cancel-label\fP
+\fB--fb\fP     ignored
+\fB--fullbutton\fP     ignored
+\fB--no-button\fP      mapped to \fB--no-label\fP
+\fB--nocancel\fP       mapped to \fB--no-cancel\fP
+\fB--noitem\fP mapped to \fB--no-items\fP
+\fB--notags\fP mapped to \fB--no-tags\fP
+\fB--ok-button\fP      mapped to \fB--ok-label\fP
+\fB--scrolltext\fP     mapped to \fB--scrollbar\fP
+\fB--topleft\fP        mapped to \fB--begin 0 0\fP
+\fB--yes-button\fP     mapped to \fB--yes-label\fP
+.TE
+.RE
+.LP
+There are visual differences which are not addressed by command-line options:
+.bP
+\fB\*p\fP centers lists within the window.
+\fBwhiptail\fP typically puts lists against the left margin.
+.bP
+\fBwhiptail\fP uses angle brackets ("<" and ">") for marking buttons.
+\fB\*p\fP uses square brackets.
+.bP
+\fBwhiptail\fP marks the limits of subtitles with vertical bars.
+\fB\*p\fP does not mark the limits.
+.bP
+\fBwhiptail\fP attempts to mark the top/bottom cells of a scrollbar
+with up/down arrows.
+When it cannot do this,
+it fills those cells with the background color
+of the scrollbar and confusing the user.
+\fB\*p\fP uses the entire scrollbar space,
+thereby getting better resolution.
+.\" ************************************************************************
+.SH BUGS
+Perhaps.
+.SH AUTHOR
+.LP
+Thomas E. Dickey (updates for 0.9b and beyond)
+.SH CONTRIBUTORS
+Kiran Cherupally - the mixed form and mixed gauge widgets.
+.LP
+Tobias C. Rittweiler
+.LP
+Valery Reznic - the form and progressbox widgets.
+.LP
+Yura Kalinichenko adapted the gauge widget as "pause".
+.PP
+This is a rewrite (except as needed to provide compatibility)
+of the earlier version of \fB\*p 0.9a\fP,
+which lists as authors:
+.bP
+Savio Lam - version 0.3, "dialog"
+.bP
+Stuart Herbert - patch for version 0.4
+.bP
+Marc Ewing - the gauge widget.
+.bP
+Pasquale De Marco "Pako" - version 0.9a, "cdialog"
diff --git a/contrib/dialog/dialog.3 b/contrib/dialog/dialog.3
new file mode 100644 (file)
index 0000000..b37a25b
--- /dev/null
@@ -0,0 +1,3687 @@
+'\" t
+.\" $Id: dialog.3,v 1.90 2012/12/23 22:16:50 tom Exp $
+.\" Copyright 2005-2011,2012  Thomas E. Dickey
+.\"
+.\" This program is free software; you can redistribute it and/or modify
+.\" it under the terms of the GNU Lesser General Public License, version 2.1
+.\" as published by the Free Software Foundation.
+.\"
+.\" This program is distributed in the hope that it will be useful, but
+.\" WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+.\" Lesser General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU Lesser General Public
+.\" License along with this program; if not, write to
+.\"    Free Software Foundation, Inc.
+.\"    51 Franklin St., Fifth Floor
+.\"    Boston, MA 02110, USA.
+.\"
+.\" definitions for renaming
+.ds p dialog
+.ds l dialog
+.ds L Dialog
+.ds D DIALOG
+.
+.de ES
+.ne 8
+.IP
+..
+.de EX
+.RS +10
+.nf
+..
+.de EE
+.fi
+.RE
+..
+.\" Bulleted paragraph
+.de bP
+.IP \(bu 4
+..
+.TH \*D 3 "" "$Date: 2012/12/23 22:16:50 $"
+.SH NAME
+dialog \- widgets and utilities for the \*p program
+.SH SYNOPSIS
+.B cc [ flag ... ] file ...  -l\*l [ library ... ]
+.br
+\ \ \ or
+.br
+.B cc `\*p-config --cflags` file ... `\*p-config --libs` ]
+.sp
+.B #include <\*l.h>
+.PP
+\fB\*L\fP
+is a program that will let you to present a variety of questions or
+display messages using dialog boxes from a shell script.
+It is built from the \fB\*l\fP library,
+which consists of several widgets
+as well as utility functions that are used by the widgets
+or the main program.
+.
+.SH DESCRIPTION
+This manpage documents the features from \fI<\*l.h>\fP which
+are likely to be important to developers using the widgets directly.
+Some hints are also given for developing new widgets.
+.
+.\" ************************************************************************
+.SH DEFINITIONS
+Exit codes (passed back to the main program for its use)
+are defined with a "\fIDLG_EXIT_\fP prefix.
+The defined constants can be mapped using environment variables
+as described in \fB\*p\fP(1),
+e.g., \fIDLG_EXIT_OK\fP corresponds to \fI$DIALOG_OK\fP.
+.PP
+Useful character constants which correspond to user input
+are named with the "\fICHR_\fP" prefix, e.g.,
+\fICHR_BACKSPACE\fP.
+.PP
+Colors and video attributes are categorized and associated with
+settings in the configuration file
+(see the discussion of \fI$DIALOGRC\fP in \fB\*p\fP(1)).
+The \fIDIALOG_ATR(n)\fP macro is used for defining the references
+to the combined color and attribute table \fBdlg_color_table[]\fP.
+.PP
+The \fB\*p\fP application passes its command-line parameters
+to the widget functions.  Some of those parameters are single values,
+but some of the widgets accept data as an array of values.
+Those include checklist/radiobox, menubox and formbox.
+When the \fB--item-help\fP option is given, an extra column
+of data is expected.
+The USE_ITEM_HELP(), CHECKBOX_TAGS, MENUBOX_TAGS and FORMBOX_TAGS
+macros are used to hide this difference from the calling application.
+.PP
+Most of the other definitions found in \fI<\*l.h>\fP
+are used for convenience in building the library or main program.
+These include definitions based on the generated \fI<dlg_config.h>\fP header.
+
+.\" ************************************************************************
+.SH DATA STRUCTURES
+All of the global data for the \fB\*l\fP library is stored in
+a few structures: \fIDIALOG_STATE\fP, \fIDIALOG_VARS\fP and \fIDIALOG_COLORS\fP.
+The corresponding \fBdialog_state\fP, \fBdialog_vars\fP and \fBdlg_color_table\fP
+global variables should be initialized to zeros,
+and then populated with the data to use.
+A few of these must be nonzero for the corresponding widgets to function.
+As as the case with function names,
+variables beginning with "\fIdialog_\fP"
+are designed for use by the calling application
+while variables beginning with "\fIdlg_\fP"
+are intended for lower levels, e.g., by the \fB\*l\fP library.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_STATE.all_subwindows
+This is a linked list of all subwindows created by the library.
+The \fBdlg_del_window\fP function uses this
+to free storage for subwindows when deleting a window.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_STATE.all_windows
+This is a linked list of all windows created by the library.
+The \fBdlg_del_window\fP function uses this to locate windows which
+may be redrawn after deleting a window.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_STATE.aspect_ratio
+This corresponds to the command-line option "\fB--aspect-ratio\fP".
+The value gives the application
+some control over the box dimensions when using auto
+sizing (specifying 0 for height and width).
+It represents width / height.
+The default is 9, which means 9 characters wide to every 1 line high.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_STATE.getc_callbacks
+This is setup in \fIui_getc.c\fP to record windows which must be polled
+for input, e.g,. to handle the background tailbox widget.
+One window is designated as the foreground or control window.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_STATE.getc_redirect
+If the control window for \fIDIALOG_STATE.getc_callbacks\fP is
+closed, the list is transferred to this variable.
+Closing all windows causes the application to exit.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_STATE.no_mouse
+This corresponds to the command-line option "\fB--no-mouse\fP".
+If true, \fB\*p\fP will not initialize (and enable) the mouse in
+\fIinit_dialog\fP.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_STATE.output
+This is set in the \fB\*p\fP application to the stream on
+which the application and library functions may write text results.
+Normally that is the standard error,
+since the curses library prefers to write its data to the standard output.
+Some scripts, trading portability for convenience,
+prefer to write results to the standard output,
+e.g., by using the "\fB--stdout\fP" option.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_STATE.output_count
+This is incremented by \fBdlg_does_output\fP,
+which is called by each widget that writes text to the output.
+The \fB\*p\fP application uses that to decide if it should
+also write a separator, i.e.,
+\fIDIALOG_STATE.separate_str\fP,
+between calls to each widget.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_STATE.pipe_input
+This is set in \fIinit_dialog\fP to a stream which can be used by the
+\fBgauge\fP widget, which must be the application's standard input.
+The \fB\*p\fP application calls \fIinit_dialog\fP normally with
+\fIinput\fP set to the standard input, but optionally based on the
+"\fB--input-fd\fP" option.
+Since the application cannot read from
+a pipe (standard input) and at the same time read
+the curses input from the standard input,
+it must allow for reopening the latter from either
+a specific file descriptor,
+or directly from the terminal.
+The adjusted pipe stream value is stored in this variable.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_STATE.screen_initialized
+This is set in \fIinit_dialog\fP and
+reset in \fIend_dialog\fP.
+It is used to check if curses has been initialized,
+and if the \fIendwin\fP function must be called on exit.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_STATE.screen_output
+This is set in \fIinit_dialog\fP to the output stream used
+by the curses library.
+Normally that is the standard output,
+unless that happens to not be a terminal (and if \fIinit_dialog\fP can
+successfully open the terminal directly).
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_STATE.separate_str
+This corresponds to the command-line option "\fB--separate-widget\fP".
+The given string
+specifies a string that will separate the output on \fB\*p\fP's output from
+each widget.
+This is used to simplify parsing the result of a dialog with several widgets.
+If this option is not given,
+the default separator string is a tab character.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_STATE.tab_len
+This corresponds to the command-line option "\fB--tab-len\fP \fInumber\fP".
+Specify the number of spaces that a tab character occupies if the
+"\fB--tab-correct\fP"
+option is given.
+The default is 8.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_STATE.trace_output
+This corresponds to the command-line option "\fB--trace\fP \fIfile\fP".
+It is the file pointer to which trace messages are written.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_STATE.use_colors
+This is set in \fIinit_dialog\fP if the curses implementation supports color.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_STATE.use_scrollbar
+This corresponds to the command-line option "\fB--scrollbar\fP".
+If true,
+draw a scrollbar to make windows holding scrolled data more readable.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_STATE.use_shadow
+This corresponds to the command-line option "\fB--no-shadow\fP".
+This is set in \fIinit_dialog\fP if the curses implementation supports color.
+If true,
+suppress shadows that would be drawn to the right and bottom of each dialog box.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_STATE.visit_items
+This corresponds to the command-line option "\fB--visit-items\fP".
+.\" ---------------------------------------------------------------------------
+.PP
+The \fB\*p\fP application resets the \fBdialog_vars\fP data before
+accepting options to invoke each widget.
+Most of the \fIDIALOG_VARS\fP members are set directly from \fB\*p\fP's
+command-line options:
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.ascii_lines
+This corresponds to the command-line option "\fB--ascii-lines\fP.
+It causes line-drawing to be done with ASCII characters, e.g., "+" and "-".
+See \fIDIALOG_VARS.no_lines\fP.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.backtitle
+This corresponds to the command-line option "\fB--backtitle\fP \fIbacktitle\fP".
+It specifies a
+\fIbacktitle\fP
+string to be displayed on the backdrop, at the top of the screen.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.beep_after_signal
+This corresponds to the command-line option "\fB--beep-after\fP".
+If true, beep after a user has completed a widget by pressing one of the buttons.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.beep_signal
+This corresponds to the command-line option "\fB--beep\fP".
+It is obsolete.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.begin_set
+This is true if the command-line option "\fB--begin y x\fP" was used.
+It specifies the position of the upper left corner of a dialog box on the screen.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.begin_x
+This corresponds to the \fIx\fP value from
+the command-line option "\fB--begin\fP \fIy x\fP" (second value).
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.begin_y
+This corresponds to the \fIy\fP value from
+the command-line option "\fB--begin\fP \fIy x\fP" (first value).
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.cancel_label
+This corresponds to the command-line option "\fB--cancel-label\fP \fIstring\fP".
+The given \fIstring\fP overrides the label used for "Cancel" buttons.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.cant_kill
+This corresponds to the command-line option "\fB--no-kill\fP".
+If true, this tells
+\fB\*p\fP
+to put the
+\fBtailboxbg\fP
+box in the background,
+printing its process id to \fB\*p\fP's output.
+SIGHUP is disabled for the background process.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.colors
+This corresponds to the command-line option "\fB--colors\fP".
+If true, interpret embedded "\\Z" sequences in the dialog text
+by the following character,
+which tells \fB\*p\fP to set colors or video attributes:
+0 through 7 are the ANSI codes used in curses:
+black,
+red,
+green,
+yellow,
+blue,
+magenta,
+cyan and
+white respectively.
+Bold is set by 'b', reset by 'B'.
+Reverse is set by 'r', reset by 'R'.
+Underline is set by 'u', reset by 'U'.
+The settings are cumulative, e.g., "\\Zb\\Z1" makes the following text
+bright red.
+Restore normal settings with "\\Zn".
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.column_separator
+This corresponds to the command-line option "\fB--column-separator\fP".
+\fB\*L\fP splits data for radio/checkboxes and menus on the
+occurrences of the given string, and aligns the split data into columns.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.cr_wrap
+This corresponds to the command-line option "\fB--cr-wrap\fP".
+If true,
+interpret embedded newlines in the dialog text as a newline on the screen.
+Otherwise, \fB\*p\fR will only wrap lines where needed to fit inside the text box.
+Even though you can control line breaks with this,
+\fB\*p\fR will still wrap any lines that are too long for the width of the box.
+Without cr-wrap, the layout of your text may be formatted to look nice
+in the source code of your script without affecting the way it will
+look in the dialog.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.date_format
+This corresponds to the command-line option "\fB--date-format\fP \fIstring\fP".
+If the host provides \fBstrftime\fP, and the value is nonnull,
+the calendar widget uses this to format its output.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.default_button
+This is set by the command-line option "\fB--default-button\fP.
+It is used by \fBdlg_default_button\fP.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.default_item
+This corresponds to the command-line option "\fB--default-item\fP \fIstring\fP".
+The given string is used as
+the default item in a checklist, form or menu box.
+Normally the first item in the box is the default.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.defaultno
+This corresponds to the command-line option "\fB--defaultno\fP".
+If true,
+make the default value of the
+\fByes/no\fP
+box a
+.BR No .
+Likewise, make the default button of widgets that provide "OK" and "Cancel"
+a \fBCancel\fP.
+If \fB--nocancel\fP was given that option overrides this,
+making the default button always "Yes" (internally the same as "OK").
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.dlg_clear_screen
+This corresponds to the command-line option "\fB--clear\fP".
+This option is implemented in the main program, not the library.
+If true,
+the screen will be cleared on exit.
+This may be used alone, without other options.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.exit_label
+This corresponds to the command-line option "\fB--exit-label string\fP".
+The given string overrides the label used for "EXIT" buttons.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.extra_button
+This corresponds to the command-line option "\fB--extra-button\fP".
+If true, some widgets show an extra button,
+between "OK" and "Cancel" buttons.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.extra_label
+This corresponds to the command-line option "\fB--extra-label\fP \fIstring\fP".
+The given string overrides the label used for "Extra" buttons.
+Note: for inputmenu widgets, this defaults to "Rename".
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.formitem_type
+This is set by the command-line option "\fB--passwordform\fP"
+to tell the form widget that its text fields should be treated like
+password widgets.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.help_button
+This corresponds to the command-line option "\fB--help-button\fP".
+If true, some widgets show a help-button after "OK" and "Cancel" buttons,
+i.e., in checklist, radiolist and menu boxes.
+If \fB--item-help\fR is also given, on exit
+the return status will be the same as for the "OK" button,
+and the item-help text will be written to \fB\*p\fP's output after the token "HELP".
+Otherwise, the return status will indicate that the Help button was pressed,
+and no message printed.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.help_file
+This corresponds to the command-line option "\fB--hfile\fP \fIstring\fP".
+The given filename is passed to \fBdialog_helpfile\fP when the user
+presses F1.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.help_label
+This corresponds to the command-line option "\fB--help-label\fP \fIstring\fP".
+The given string overrides the label used for "Help" buttons.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.help_line
+This corresponds to the command-line option "\fB--hline\fP \fIstring\fP".
+The given string is displayed in the bottom of dialog windows,
+like a subtitle.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.help_status
+This corresponds to the command-line option "\fB--help-status\fP".
+If true, and the the help-button is selected,
+writes the checklist or radiolist information
+after the item-help "HELP" information.
+This can be used to reconstruct the state of a checklist after processing
+the help request.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.input_length
+This is nonzero if \fIDIALOG_VARS.input_result\fP is allocated,
+versus being a pointer to the user's local variables.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.input_menu
+This flag is set to denote whether the menubox widget
+implements a menu versus a inputmenu widget.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.input_result
+This may be either a user-supplied buffer,
+or a buffer dynamically allocated by the library,
+depending on \fIDIALOG_VARS.input_length\fP:
+.RS
+.bP
+If \fIDIALOG_VARS.input_length\fP is zero,
+this is a pointer to user buffer (on the stack, or static).
+The buffer size is assumed to be \fBMAX_LEN\fP,
+which is defined in \fI<\*l.h>\fP.
+.bP
+When \fIDIALOG_VARS.input_length\fP is nonzero,
+this is a dynamically-allocated buffer used by the widgets to return
+printable results to the calling application.
+.RE
+.IP
+Certain widgets copy a result to this buffer.
+If the pointer is NULL, or if the length is insufficient for
+the result, then the \fB\*l\fP library allocates a buffer which is large enough,
+and sets \fIDIALOG_VARS.input_length\fP.
+Callers should check for this case if they have supplied their own buffer.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.insecure
+This corresponds to the command-line option "\fB--insecure\fP".
+If true, make the password widget friendlier but less secure,
+by echoing asterisks for each character.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.in_helpfile
+This variable is used to prevent \fBdialog_helpfile\fP from showing
+anything, e.g., if F1 were pressed within a help-file display.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.item_help
+This corresponds to the command-line option "\fB--item-help\fP".
+If true,
+interpret the tags data for checklist, radiolist and menu boxes
+adding a column whose text is displayed in the bottom line of the
+screen, for the currently selected item.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.keep_tite
+This is set by the command-line option "\fB--keep-tite\fP"
+to tell \fB\*p\fP to not attempt to cancel the terminal initialization
+(termcap \fIti\fP/\fIte\fP) sequences which correspond to xterm's alternate-screen
+switching.
+Normally \fB\*p\fP does this to avoid flickering when run several times
+in a script.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.keep_window
+This corresponds to the command-line option "\fB--keep-window\fP".
+If true, do not remove/repaint the window on exit.
+This is useful for keeping the window contents visible when several
+widgets are run in the same process.
+Note that curses will clear the screen when starting a new process.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.max_input
+This corresponds to the command-line option "\fB--max-input\fP \fIsize\fP".
+Limit input strings to the given size.
+If not specified, the limit is 2048.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.no_items
+This corresponds to the command-line option "\fB--no-items\fP".
+Some widgets (checklist, inputmenu, radiolist, menu) display a list
+with two columns (a "tag" and "item", i.e., "description").
+This tells \fB\*p\fP to read shorter rows from data,
+omitting the "list".
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.no_label
+This corresponds to the command-line option "\fB--no-label\fP \fIstring\fP".
+The given string overrides the label used for "No" buttons.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.no_lines
+This corresponds to the command-line option "\fB--no-lines\fP.
+It suppresses line-drawing.
+See \fIDIALOG_VARS.ascii_lines\fP.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.no_nl_expand
+This corresponds to the command-line option "\fB--no-nl-expand\fP".
+If false, \fBdlg_trim_string\fP converts literal "\\n" substrings
+in a message into newlines.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.no_tags
+This corresponds to the command-line option "\fB--no-tags\fP".
+Some widgets (checklist, inputmenu, radiolist, menu) display a list
+with two columns (a "tag" and "item", also known as "description").
+The tag is useful for scripting, but may not help the user.
+The \fB--no-tags\fP option (from Xdialog) may be used to suppress the
+column of tags from the display.
+.IP
+Normally \fB\*p\fP allows you to quickly move to entries on the displayed list,
+by matching a single character to the first character of the tag.
+When the \fB--no-tags\fP option is given, \fB\*p\fP matches against
+the first character of the description.
+In either case, the matchable character is highlighted.
+.IP
+Here is a table showing how the no_tags and no_items values interact:
+.TS
+tab(/);
+l l l l l
+_ _ _ _ _
+l l l c c.
+Widget/Fields Shown/Fields Read/.no_items/.no_tags
+buildlist/item/tag,item/0/0*
+buildlist/item/tag,item/0/1
+buildlist/tag/tag/1/0*
+buildlist/tag/tag/1/1
+checklist/tag,item/tag,item/0/0
+checklist/item/tag,item/0/1
+checklist/tag/tag/1/0
+checklist/tag/tag/1/1
+inputmenu/tag,item/tag,item/0/0
+inputmenu/item/tag,item/0/1
+inputmenu/tag/tag/1/0
+inputmenu/tag/tag/1/1
+menu/tag,item/tag,item/0/0
+menu/item/tag,item/0/1
+menu/tag/tag/1/0
+menu/tag/tag/1/1
+radiolist/tag,item/tag,item/0/0
+radiolist/item/tag,item/0/1
+radiolist/tag/tag/1/0
+radiolist/tag/tag/1/1
+treeview/item/tag,item/0/0*
+treeview/item/tag,item/0/1
+treeview/tag/tag/1/0*
+treeview/tag/tag/1/1
+_
+.TE
+.RS
+.TP 2
+*
+Xdialog does not display the tag column for the analogous buildlist
+and treeview widgets.
+\fB\*L\fP does the same on the command-line.
+However the library interface defaults to displaying the tag column.
+Your application can enable or disable the tag column as needed for each widget.
+.RE
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.nocancel
+This corresponds to the command-line option "\fB--no-cancel\fP".
+If true,
+suppress the "Cancel" button in checklist, inputbox and menu box modes.
+A script can still test if the user pressed the ESC key to cancel to quit.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.nocollapse
+This corresponds to the command-line option "\fB--no-collapse\fP".
+Normally \fB\*p\fR converts tabs to spaces and reduces multiple
+spaces to a single space for text which is displayed in a message boxes, etc.
+It true, that feature is disabled.
+Note that \fB\*p\fR will still wrap text, subject to the \fB--cr-wrap\fR
+option.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.nook
+This corresponds to the command-line option "\fB--nook\fP.
+\fB\*L\fP will suppress the "ok" (or "yes") button from the widget.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.ok_label
+This corresponds to the command-line option "\fB--ok-label\fP \fIstring\fP".
+The given string overrides the label used for "OK" buttons.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.print_siz
+This corresponds to the command-line option "\fB--print-size\fP".
+If true,
+each widget prints its size to \fB\*p\fP's output when it is invoked.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.quoted
+This corresponds to the command-line option "\fB--quoted\fP.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.separate_output
+This corresponds to the command-line option "\fB--separate-output\fP".
+If true,
+checklist widgets output result one line at a time, with no quoting.
+This facilitates parsing by another program.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.single_quoted
+This corresponds to the command-line option "\fB--single-quoted\fP".
+If true,
+Use single-quoting as needed (and no quotes if unneeded) for the
+output of checklist's as well as the item-help text.
+If this option is not set, \fB\*p\fP uses double quotes around each item.
+The latter requires occasional use of backslashes to make the output useful in
+shell scripts.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.size_err
+This corresponds to the command-line option "\fB--size-err\fP".
+If true,
+check the resulting size of a dialog box before trying to use it,
+printing the resulting size if it is larger than the screen.
+(This option is obsolete, since all new-window calls are checked).
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.sleep_secs
+This corresponds to the command-line option "\fB--sleep\fP \fIsecs\fP".
+This option is implemented in the main program, not the library.
+If nonzero, this is the number of seconds after to delay after processing a dialog box.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.tab_correct
+This corresponds to the command-line option "\fB--tab-correct\fP".
+If true, convert each tab character of the text to one or more spaces.
+Otherwise, tabs are rendered according to the curses library's interpretation.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.time_format
+This corresponds to the command-line option "\fB--time-format\fP \fIstring\fP".
+If the host provides \fBstrftime\fP, and the value is nonnull,
+the timebox widget uses this to format its output.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.timeout_secs
+This corresponds to the command-line option "\fB--timeout\fP \fIsecs\fP".
+If nonzero, timeout input requests (exit with error code)
+if no user response within the given number of seconds.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.title
+This corresponds to the command-line option "\fB--title\fP \fItitle\fP".
+Specifies a
+\fItitle\fP
+string to be displayed at the top of the dialog box.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.trim_whitespace
+This corresponds to the command-line option "\fB--trim\fP".
+If true, eliminate leading blanks,
+trim literal newlines and repeated blanks from message text.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.visit_items
+This corresponds to the command-line option "\fB--visit-items\fP".
+Modify the tab-traversal of the list-oriented widgets
+(buildlist, checklist, radiobox, menubox, inputmenu, and treeview)
+to include the list of items as one of the states.
+This is useful as a visual aid,
+i.e., the cursor position helps some users.
+.\" ---------------------------------------------------------------------------
+.IP \fIDIALOG_VARS.yes_label
+This corresponds to the command-line option "\fB--yes-label\fP \fIstring\fP".
+The given string overrides the label used for "Yes" buttons.
+.
+.\" ************************************************************************
+.\" ************************************************************************
+.SH WIDGETS
+Functions that implement major functionality for the command-line \fB\*p\fP
+program, e.g., widgets, have names beginning "\fIdialog_\fP".
+
+All dialog boxes have at least three parameters:
+.TP 5
+\fItitle\fP
+the caption for the box, shown on its top border.
+.TP 5
+\fIheight\fP
+the height of the dialog box.
+.TP 5
+\fIwidth\fP
+the width of the dialog box.
+.PP
+Other parameters depend on the box type.
+.
+.\" ************************************************************************
+.IP \fBdialog_buildlist
+implements the "\fB--buildlist\fP" option.
+.RS
+.TP 5
+.B const char * \fItitle
+is the title on the top of the widget.
+.TP 5
+.B const char * \fIcprompt
+is the prompt text shown within the widget.
+.TP 5
+.B int \fIheight
+is the desired height of the box.
+If zero, the height is adjusted to use the available screen size.
+.TP 5
+.B int \fIwidth
+is the desired width of the box.
+If zero, the height is adjusted to use the available screen size.
+.TP 5
+.B int \fIlist_height
+is the minimum height to reserve for displaying the list.
+If zero, it is computed based on the given \fIheight\fP and \fIwidth\fP.
+.TP 5
+.B int \fIitem_no
+is the number of rows in \fIitems\fP.
+.TP 5
+.B char ** \fIitems
+is an array of strings which is viewed either as a list of rows
+.RS
+\fItag item status \fR
+.RE
+.IP
+or
+.RS
+\fItag item status help\fR
+.RE
+.IP
+depending on whether \fBdialog_vars.item_help\fP is set.
+.TP 5
+.B int \fIorder_mode
+is reserved for future enhancements
+.RE
+.
+.\" ************************************************************************
+.IP \fBdialog_calendar
+implements the "\fB--calendar\fP" option.
+.RS
+.TP 5
+.B const char * \fItitle
+is the title on the top of the widget.
+.TP 5
+.B const char * \fIsubtitle
+is the prompt text shown within the widget.
+.TP 5
+.B int \fIheight
+is the height excluding the fixed-height calendar grid.
+.TP 5
+.B int \fIwidth
+is the overall width of the box,
+which is adjusted up to the calendar grid's minimum width if needed.
+.TP 5
+.B int \fIday
+is the initial day of the week shown,
+counting zero as Sunday.
+If the value is negative, the current day of the week is used.
+.TP 5
+.B int \fImonth
+is the initial month of the year shown,
+counting one as January.
+If the value is negative, the current month of the year is used.
+.TP 5
+.B int \fIyear
+is the initial year shown.
+If the value is negative, the current year is used.
+.RE
+.\" ************************************************************************
+.IP \fBdialog_checklist
+implements the "\fB--checklist\fP" and "\fB--radiolist\fP" options
+depending on the \fIflag\fP parameter.
+.RS
+.TP 5
+.B const char * \fItitle
+is the title on the top of the widget.
+.TP 5
+.B const char * \fIcprompt
+is the prompt text shown within the widget.
+.TP 5
+.B int \fIheight
+is the desired height of the box.
+If zero, the height is adjusted to use the available screen size.
+.TP 5
+.B int \fIwidth
+is the desired width of the box.
+If zero, the height is adjusted to use the available screen size.
+.TP 5
+.B int \fIlist_height
+is the minimum height to reserve for displaying the list.
+If zero, it is computed based on the given \fIheight\fP and \fIwidth\fP.
+.TP 5
+.B int \fIitem_no
+is the number of rows in \fIitems\fP.
+.TP 5
+.B int \fIitems
+is an array of strings which is viewed either as a list of rows
+.RS
+\fItag item status \fR
+.RE
+.IP
+or
+.RS
+\fItag item status help\fR
+.RE
+.IP
+depending on whether \fBdialog_vars.item_help\fP is set.
+.IP flag
+is either \fIFLAG_CHECK\fP, for checklists,
+or \fIFLAG_RADIO\fP for radiolists.
+.RE
+.\" ************************************************************************
+.IP \fBdialog_dselect
+implements the "\fB--dselect\fP" option.
+.RS
+.TP 5
+.B const char * \fItitle
+is the title on the top of the widget.
+.TP 5
+.B const char * \fIpath
+is the preselected value to show in the input-box,
+which is used also to set the directory- and file-windows.
+.TP 5
+.B int \fIheight
+is the height excluding the minimum needed to show the dialog box framework.
+If zero, the height is based on the screen size.
+.TP 5
+.B int \fIwidth
+is the desired width of the box.
+If zero, the height is based on the screen size.
+.RE
+.\" ************************************************************************
+.IP \fBdialog_editbox
+implements the "\fB--editbox\fP" option.
+.RS
+.TP 5
+.B const char * \fItitle
+is the title on the top of the widget.
+.TP 5
+.B const char * \fIfile
+is the name of the file from which to read.
+.TP 5
+.B int \fIheight
+is the desired height of the box.
+If zero, the height is adjusted to use the available screen size.
+.TP 5
+.B int \fIwidth
+is the desired width of the box.
+If zero, the height is adjusted to use the available screen size.
+.RE
+.\" ************************************************************************
+.IP \fBdialog_form
+implements the "\fB--form\fP" option.
+.RS
+.TP 5
+.B const char * \fItitle
+is the title on the top of the widget.
+.TP 5
+.B const char * \fIcprompt
+is the prompt text shown within the widget.
+.TP 5
+.B int \fIheight
+is the desired height of the box.
+If zero, the height is adjusted to use the available screen size.
+.TP 5
+.B int \fIwidth
+is the desired width of the box.
+If zero, the height is adjusted to use the available screen size.
+.TP 5
+.B int \fIform_height
+is the minimum height to reserve for displaying the list.
+If zero, it is computed based on the given \fIheight\fP and \fIwidth\fP.
+.TP 5
+.B int \fIitem_no
+is the number of rows in \fIitems\fP.
+.TP 5
+.B int \fIitems
+is an array of strings which is viewed either as a list of rows
+.RS
+\fIName NameY NameX Text TextY TextX FLen ILen\fR
+.RE
+.IP
+or
+.RS
+\fIName NameY NameX Text TextY TextX FLen ILen Help\fR
+.RE
+.IP
+depending on whether \fBdialog_vars.item_help\fP is set.
+.RE
+.\" ************************************************************************
+.IP \fBdialog_fselect
+implements the "\fB--fselect\fP" option.
+.RS
+.TP 5
+.B const char * \fItitle
+is the title on the top of the widget.
+.TP 5
+.B const char * \fIpath
+is the preselected value to show in the input-box,
+which is used also to set the directory- and file-windows.
+.TP 5
+.B int \fIheight
+is the height excluding the minimum needed to show the dialog box framework.
+If zero, the height is based on the screen size.
+.TP 5
+.B int \fIwidth
+is the desired width of the box.
+If zero, the height is based on the screen size.
+.RE
+.\" ************************************************************************
+.IP \fBdialog_gauge
+implements the "\fB--gauge\fP" option.
+Alternatively, a simpler or customized gauge widget can be
+setup using
+\fBdlg_allocate_gauge\fP,
+\fBdlg_update_gauge\fP and
+\fBdlg_free_gauge\fP.
+.RS
+.TP 5
+.B const char * \fItitle
+is the title on the top of the widget.
+.TP 5
+.B const char * \fIcprompt
+is the prompt text shown within the widget.
+.TP 5
+.B int \fIheight
+is the desired height of the box.
+If zero, the height is based on the screen size.
+.TP 5
+.B int \fIwidth
+is the desired width of the box.
+If zero, the height is based on the screen size.
+.TP 5
+.B int \fIpercent
+is the percentage to show in the progress bar.
+.RE
+.\" ************************************************************************
+.IP \fBdialog_inputbox
+implements the "\fB--inputbox\fP" or
+"\fB--password\fP" option, depending on the value of \fIpassword\fP.
+.RS
+.TP 5
+.B const char * \fItitle
+is the title on the top of the widget.
+.TP 5
+.B const char * \fIcprompt
+is the prompt text shown within the widget.
+.TP 5
+.B int \fIheight
+is the desired height of the box.
+If zero, the height is based on the screen size.
+.TP 5
+.B int \fIwidth
+is the desired width of the box.
+If zero, the height is based on the screen size.
+.TP 5
+.B const char * \fIinit
+is the initial value of the input box, whose length is taken into account
+when auto-sizing the width of the dialog box.
+.TP 5
+.B int \fIpassword
+if true, causes typed input to be echoed as asterisks.
+.RE
+.\" ************************************************************************
+.IP \fBdialog_helpfile
+implements the "\fB--hfile\fP" option.
+.RS
+.TP 5
+.B const char * \fItitle
+is the title on the top of the widget.
+.TP 5